- Appended to comment:
anonymous claiming to be Andrey added on 2009-09-21 00:37:14:
Seems this is a problem of WinInetd. It should not redirect files to sockets, it should copy between file handle and socket - just like any web-server does when running CGI application. It should not depend of ability of console app to operate with sockets and even know something about sockets. (sorry for my poor English)
- Appended to comment:
anonymous claiming to be tsbg added on 2009-09-19 08:46:37:
Yes it does, but only when stdin and stdout are not redirected to a socket. Windows treats file and socket handles differently. Another problem is, you cant't call socket functions like getpeername without initializing the windows socket environment.Try it with the above mentioned WinInetd server, and you will see no output until you apply the patch.
--tsbg
- Change priority to "Medium"
- Change resolution to "Open"
- Change severity to "Important"
- Appended to comment:
anonymous added on 2009-09-19 00:36:49:
From reference: " Usage: fossil http REPOSITORY Handle a single HTTP request appearing on stdin. The resulting webpage is delivered on stdout. This method is used to launch an HTTP request handler from inetd, for example. The argument is the name of the repository. "Test with current Fossil under Windows Vista:
================================================================ E:\dl\fossil-w32-20090915120431>fossil.exe http myclone.fossil GET / HTTP/1.0 Host: localhost HTTP/1.0 302 Moved Temporarily Date: Sat, 19 Sep 2009 00:30:23 GMT Connection: close Location: http://localhost/doc/tip/www/index.wiki Cache-control: no-cache, no-store Content-Type: text/html; charset=utf-8 Content-Length: 74 <html> <p>Redirect to http://localhost/doc/tip/www/index.wiki</p> </html> =======================
So it seems behave right, like declared.
- Change resolution to "Works_As_Designed"
- Change severity to "Cosmetic"
- Change comment to "This would make it possible to use Fossil with Inetd like servers on Windows, for example [http://www.xmailserver.org/wininetd.html]. The following patch against Fossil version [0eb08b860c] implements this functionality: <verbatim> diff -Naur fossil-src/src/cgi.c fossil-src-mod/src/cgi.c --- fossil-src/src/cgi.c 2009-09-13 09:37:48 +0000 +++ fossil-src-mod/src/cgi.c 2009-09-17 11:25:47 +0000 @@ -29,10 +29,11 @@ */ #include "config.h" #ifdef __MINGW32__ -# include <windows.h> /* for Sleep once server works again */ -# include <winsock2.h> /* socket operations */ -# define sleep Sleep /* windows does not have sleep, but Sleep */ -# include <ws2tcpip.h> +# include <windows.h> /* Windows specific declarations */ +# include <winsock2.h> /* Windows socket operations */ +# include <ws2tcpip.h> /* for socklen_t */ +# include <fcntl.h> +# include <io.h> #else # include <sys/socket.h> # include <netinet/in.h> @@ -1076,6 +1077,95 @@ return zResult; } +#ifdef __MINGW32__ +/* +** Data structure related to all variables for the windows socket environment. +*/ +typedef struct WinSocketData { + int fWSAInit; /* True, if Windows sockets initialized */ + SOCKET hSocket; /* Handle to the socket */ +} WinSocketData; + +static WinSocketData wsd; + +/* +** Exit handler routine. Make sure any remaining output gets flushed to the +** output stream. If the standard handles are redirected to a socket then +** make shure the socket gets closed properly and clean up the windows socket +** environment. +*/ +static void cgi_handle_http_request_exit(void) +{ + fflush(g.httpOut); + + if( wsd.hSocket != INVALID_SOCKET ){ + shutdown(wsd.hSocket, SD_BOTH); + closesocket(wsd.hSocket); + } + if (wsd.fWSAInit) { + WSACleanup(); + } + return; +} + +/* +** This routine initalizes the environment on windows for the +** cgi_handle_http_request routine. It sets the standard input and ouput +** handles to binary mode, initalizes the windows socket environment and tries +** to get the socket handle from the standard handles. It also establishs a +** exit routine to clean up on program exit. +*/ +void cgi_handle_http_request_init(void) +{ + WSADATA wd; + SOCKET hSock; + int socket_type; + int socket_type_len = sizeof(socket_type); + + /* + ** Initialize the windows socket data structure. + */ + wsd.fWSAInit = 0; + wsd.hSocket = INVALID_SOCKET; + + /* + ** Register the exit function. + */ + atexit(cgi_handle_http_request_exit); + + /* + ** Set the mode of the http input and output streams to binary. + */ + _setmode(_fileno(g.httpIn), _O_BINARY); + _setmode(_fileno(g.httpOut), _O_BINARY); + + /* + ** Initialize the windows socket API. This is required if we need to + ** call any other Windows Socket function. + */ + if( WSAStartup(MAKEWORD(2,2), &wd) == 0 ) wsd.fWSAInit = 1; + + /* + ** Windows Socket handles must be handled differently than file handles. + ** There is no function to detect if a file handle is a socket or not, so + ** lets call a socket function with the handle from stdin, and if there is + ** no error, assume it is a socket! + */ + if( wsd.fWSAInit ){ + hSock = (SOCKET)_get_osfhandle(_fileno(stdin)); + if( getsockopt (hSock, SOL_SOCKET, SO_TYPE, + (char *)&socket_type, &socket_type_len) == 0 ){ + wsd.hSocket = hSock; + } + } + return; +} + +# define CGI_SOCKET wsd.hSocket +#else +# define CGI_SOCKET fileno(g.httpIn) +#endif /* __MINGW32__ */ + /* ** This routine handles a single HTTP request which is coming in on ** standard input and which replies on standard output. @@ -1092,6 +1182,9 @@ size_t size = sizeof(struct sockaddr_in); char zLine[2000]; /* A single line of input. */ +#ifdef __MINGW32__ + cgi_handle_http_request_init(); +#endif g.fullHttpReply = 1; if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ malformed_request(); @@ -1116,7 +1209,7 @@ cgi_setenv("PATH_INFO", zToken); cgi_setenv("QUERY_STRING", &zToken[i]); if( zIpAddr==0 && - getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName, + getpeername(CGI_SOCKET, (struct sockaddr*)&remoteName, (socklen_t*)&size)>=0 ){ zIpAddr = inet_ntoa(remoteName.sin_addr); </verbatim> --tsbg"
- Change foundin to "0eb08b860c"
- Change private_contact to "76518fb407f147a1d053c00b5b993281a339c0e3"
- Change severity to "Important"
- Change status to "Open"
- Change title to "Make the http command working on Windows."
- Change type to "Feature_Request"