# HG changeset patch # User jlarmour # Date 1155231468 0 # Node ID b5670f3c40f2ce808972e3bac4e20af340d6e437 # Parent af00278f385c4cfccae9f3b3541379f8eb9bdfa8 * cdl/httpd.cdl: * doc/athttpd.sgml: Corrected some typos and rectified some omissions. * include/jim.h: Added an inline to Jim_InitExtension() * src/cgi.c: used malloc() instead of cyg_ldr_malloc(); * src/forms.c: Added a #define to be able tio use the TCL scripting without OBJLOADER * src/http.c: * src/socket.c: Lots of typos stamped out, and some better comments too. diff --git a/packages/net/athttpd/current/ChangeLog b/packages/net/athttpd/current/ChangeLog --- a/packages/net/athttpd/current/ChangeLog +++ b/packages/net/athttpd/current/ChangeLog @@ -1,3 +1,14 @@ +2006-07-19 Anthony Tonizzo and Sergei Gavrikov + + * cdl/httpd.cdl: + * doc/athttpd.sgml: Corrected some typos and rectified some omissions. + * include/jim.h: Added an inline to Jim_InitExtension() + * src/cgi.c: used malloc() instead of cyg_ldr_malloc(); + * src/forms.c: Added a #define to be able tio use the TCL scripting + without OBJLOADER + * src/http.c: + * src/socket.c: Lots of typos stamped out, and some better comments too. + 2006-07-19 Anthony Tonizzo * src/socket.c: Corrected a typo that generated an assertion. @@ -25,17 +36,21 @@ 2006-06-13 Anthony Tonizzo cyg_httpd_start(); - + in the application code. The server initialization code spawns a new thread which calls init_all_network_interfaces() to @@ -75,44 +75,100 @@ to call multiple times. + +MIME types + +The server has an internal table with all the recognized mime types. Each time +a file or an internal resource is sent out by the server, its extension is +searched in this table and if a match is found, the associated MIME type is +then sent out in the header. + +The server already provides entries for the following standard file extensions: + +'html', 'htm', 'gif', 'jpg', 'css', 'js' + +and the user is responsible for adding any further entry. The syntax for +adding an entry is the following: + + +CYG_HTTPD_MIME_TABLE_ENTRY(entry_label, extension_string, mime_tipe_sting); + +entry table : an identifier unique to this entry +extension string : a string containing the extension for this entry +type_string : the mime string. The strings for many more mime types + is included in a file in the "doc" directory. + + + +The following is an example of how to add the Adobe Portable Document Format +pdf MIME type to the table: + + +CYG_HTTPD_MIME_TABLE_ENTRY(hal_pdf_entry, "pdf", "application/pdf"); + + + +MIME Types for Chunked Frames + +For chunked frames, which are generally used inside c language callbacks, there +is no file name to match an extension to, and thus the extension to be used +must be passed in the cyg_httpd_start_chunked() call. The +server will then scan the MIME table to find a MIME type to match the extension. + +For example, to start a chunked transfer of an html file, +the following call is used: + + +cyg_httpd_start_chunked("html"); + + + +In any event, it is the responsibility of the user to make sure that a match to +all used extensions is found in the table search. Failing this, +the default MIME type specified in the CYGDAT_NET_ATHTTPD_DEFAULT_MIME_TYPE +string is returned. + + + C language callback functions The server allows the association of particular URLs to C language callback -functions. Tables are again used for the association. The syntax of the macro -to add callback entries to the table is: +functions. eCos tables are used to define the association between a URL and its +corresponding callback. The syntax of the macro to add callback entries to +the table is: -CYG_HTTPD_HANDLER_TABLE_ENTRY(entry_label, url_string, callback); - -entry table : an identifier unique to this entry. -url_string : a string with the extension url that will be appended to the - default directory. -callback : a function with a prototype: - cyg_int32 callback_function(CYG_HTTPS_STATE*); - +CYG_HTTPD_HANDLER_TABLE_ENTRY(entry_label, url_string, callback); + +entry table : an identifier unique to this entry. +url_string : a string with the extension url that will be appended to the + default directory. +callback : a function with a prototype: + cyg_int32 callback_function(CYG_HTTPS_STATE*); + CYG_HTTPS_STATE* is a pointer to a structure that contains, among others, a buffer (outbuffer) that can be used to send data -out. The definitions of the structure is in http.h. - +out. The definitions of the structure is in http.h. + -If the callback function returns the value of 0, the server will try to find -the file with the same URL in the file system and send it. Any other value +If the callback function returns the value of 0, the server will try to find +the file with the same URL in the file system and send it. Any other value returned causes the sever to stop further processing of this request. It is assumed that in this case the user has send the response back to the client -inside the body of the callback function. - -The following is an example of how to add a callback to a function myForm() -whenever the /myform.gci is called. +inside the body of the callback function. + +The following is an example of how to add a callback to a function myForm() +whenever the URL /myform.cgi is requested: -CYG_HTTPD_HANDLER_TABLE_ENTRY( hal_cb_entry, "/myform.cgi", myForm ); +CYG_HTTPD_HANDLER_TABLE_ENTRY(hal_cb_entry, "/myform.cgi", myForm); - + and somewhere in the source tree there is a function: @@ -124,7 +180,7 @@ cyg_int32 myForm(CYG_HTTPS_STATE* p) cyg_httpd_write_chunked(p->outbuffer, strlen(p->outbuffer)) cyg_httpd_end_chunked(); return -1; // Do not further search the file system. -} +} This function also shows the correct method of using the chunked frames @@ -133,7 +189,7 @@ collect data to send out. Chunked frames are useful when the size of the frame is not known upfront. In this case it possible to send a response in chunks of various sizes, and -terminate it with a null chunk. See RFC 2616 for details. To use chunked +terminate it with a null chunk (See RFC 2616 for details). To use chunked frames, the cyg_httpd_start_chunked() function is used. The prototype is the following: @@ -155,7 +211,7 @@ void cyg_httpd_end_chunked()(void); In between these two calls, the user can call the function -cyg_httpd_write_chunked() to send out data, any number of +cyg_httpd_write_chunked() to send out data any number of times. It is important that cyg_httpd_write_chunked() be the only function used to send data out for chunked frames. This guarantees that proper formatting of the response is respected. @@ -180,78 +236,23 @@ extension : the extension used in the len : length of the data to send out -and -cyg_httpd_write, the prototype of which is the same -as cyg_httpd_write_chunked() - - - -MIME types - -The server has an internal table with all the recognized mime types. Each time -a file or an internal resource is sent out by the server, its extension is -searched in this table and if a match is found, the associated MIME type is -then sent out in the header. - -The server already provides entries for the following standard file extensions: - -'html', 'htm', 'gif', 'jpg', 'css', 'js' - -and the user can add further enties entries to the table. The syntax for -adding an entry is the following: - - -CYG_HTTPD_MIME_TABLE_ENTRY(entry_label, extension_string, mime_tipe_sting); - -entry table : an identifier unique to this entry -extension string : a string containing the extension for this entry -type_string : the mime string. The strings for many more mime types - is included in a file in the "doc" directory. - - - -The following is an example of how to add the Adobe Portable Document Format -pdf MIME type to the table: - - -CYG_HTTPD_MIME_TABLE_ENTRY(hal_pdf_entry, "pdf", "application/pdf"); - - - -MIME Types for Chunked Frames - -For chunked frames, which are generally used inside c language callbacks, there -is no file name to match an extension to, and thus the extension to be used -must be passed in the cyg_httpd_start_chunked() call. The -server will then scan the MIME table to find a MIME type to match the extension. - -For example, to start a chunked transfer of an html file, -the following call is used: - - -cyg_httpd_start_chunked("html"); - - - -In any event, it is the responsibility of the user to make sure that a match to -all used extensions is found in the table search. Failing this, -the default MIME type specified in the CYGDAT_NET_ATHTTPD_DEFAULT_MIME_TYPE -string is returned. - - +and use +cyg_httpd_write() to send data out to the client. The + prototype of cyg_httpd_write() is the same as +cyg_httpd_write_chunked() CGI -The web server allows writing of pseudo-CGI programs. This is helpful in order -to modify the functionality of the server without having to recompile it and +The web server allows writing of pseudo-CGI programs. This is helpful in order +to modify the functionality of the server without having to recompile it and reflash it. One way to implement CGI is, of course, the C language callback mechanism described above: This assumes, of course, that all the callbacks are written -at compile time and cannot be modified later on. Another way to perform the +by compile time and cannot be modified later on. Another way to perform the same functionality is the use of a library in the form of an object file. -These object files reside in the file system, and are loaded, executed and +These object files reside in the file system and are loaded, executed and unloaded on demand. Yet a third way is the use of a scripting language. Since full fledged @@ -261,25 +262,28 @@ was chosen for this server. Most of the and makes writing cgi a lot easier. In order to limit the footprint of the operating system support for both -the objloader and the tcl script for dealing with cgi files can be selected -out. Tcl support in particular increases the memory requirements considerably. +the objloader and the tcl script for dealing with cgi files can be +independently selected out. Tcl support in particular increases the memory +requirements considerably. CGI via objloader -In order to use the cgi mechanism the CYGPKG_OBJLOADER must be included +In order to use the cgi mechanism the CYGPKG_OBJLOADER must be included when building the operating system. This will enable the proper option in the -configuration tool, and if selected, the necessary code will be compiled -in the OS kernel. The user will then have to compile a library and place it -in the file system under a directory defined by +configuration tool and if selected, the necessary code will be compiled +in the eCos kernel. The user will then have to compile the necessary libraries +and place them in the file system under a directory defined by CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR. -When a request is made to the server, the web server looks into the +When a request is made, the web server checks if the root directory of the +requested URL is inside the CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR directory. +If so, the server assumes that the user requested a cgi file and looks into the directory to see if a library by the same name is present, and if so load it -and tries to execute a library function with the following prototype: +and tries to execute a function inside the library with the following prototype: -void exec_cgi(CYG_HTTPS_STATE *) +void exec_cgi(CYG_HTTPS_STATE *) @@ -287,13 +291,13 @@ The pointer CYG_HTTPS_STATE* - + When using the OBJLOADER package within the HTTP server a number of functions are automatically added to the externals table of the OBJLOADER package. These functions are likely to be used inside the library and the relocator need to have a pointer to them. In order to add more functions, see the OBJLOADER -documentation. The complete list of the functions automatically added is: +documentation. The complete list of the functions automatically added is: @@ -309,14 +313,14 @@ documentation. The complete list of the cyg_httpd_find_mime_string() -Every time the web client issues a GET or POST request for a file with an -extension of '.o'in the /cgi-bin directory (or whatever path the user chooses +Every time the web client issues a GET or POST request for a file with an +extension of '.o'in the /cgi-bin directory (or whatever path the user chooses to hold the libraries) then the library by that name is loaded, run and -when the execution is over, it is dumped from memory. - +when the execution is over, it is dumped from memory. + The library must be compiled separately, using the same toolchain used to compile the server and then added to the file system. - + In order to reduce the footprint of the server, CGI through OBJLOADER can be compiled out by unchecking CYGOPT_NET_ATHTTPD_USE_CGIBIN_OBJLOADER in the configuration tool. @@ -336,7 +340,7 @@ macro are accessible via tcl. For exampl form variable called foo, and during the GET request we are defining foo as being "1": -GET /myForm.gci?foo=1 +GET /myForm.cgi?foo=1 then tcl will be able to access the variable foo as $foo. @@ -349,20 +353,20 @@ added to the interpreter. These function "extension" is a string used to search the table of the mime types. For example, to send back to the client an HTML file, we can use: start_chunked "html"; - + write_chunked write_chunked content; content is a string to send back to the client. - + end_chunked end_chunked; -No parameters. Send back an end of frame to the client. +No parameters. Send back an end of frame to the client. @@ -388,26 +392,26 @@ path : the path to the direc domain : a domain identifier for this directory. un : username for authentication pw : password for authentication -mode : CYG_HTTPD_AUTH_BASIC fpr base64 encoding or +mode : CYG_HTTPD_AUTH_BASIC for base64 encoding or CYG_HTTPD_AUTH_DIGEST for MD5 encoding for example, to require basic authentication of the content of directory -"/foo/" with a username of 'ecos' and password "bar", the following is used: +"/ecos/" with a username of "foo" and password "bar", the following is used: -CYG_HTTPD_AUTH_TABLE_ENTRY(hal_domain1_entry, \ - "/foo/", "foo_domain", \ - "ecos", "bar", \ +CYG_HTTPD_AUTH_TABLE_ENTRY(hal_domain1_entry, \ + "/ecos/", "ecos_domain", \ + "foo", "bar", \ CYG_HTTPD_AUTH_BASIC); -Any request for a file in the directory /foo/ will now trigger a +Any request for a file in the directory /ecos/ will now trigger a credential check. These credentials, once provided, are automatically sent by -the client for every request wihtin the particular domain. +the client for every request within the particular domain. -It must be notice that the path name set in the macro is relative to the +It must be noticed that the path name set in the macro is relative to the HTML document directory, CYGDAT_NET_HTTPD_SERVEROPT_HTMLDIR and it is the first part of the path provided by the client request (including the leading slash). @@ -439,7 +443,9 @@ choosing one in the following order: If any of these files is found, its contents are sent back -to the client. If no such file is found a directory listing is sent. +to the client. If no such file is found the server uses the user-provided +index file name (if any is specified with the CYGDAT_NET_ATHTTPD_ALTERNATE_HOME +setting. Failing all this a directory listing is sent. Trailing slash redirection for directory names is supported. @@ -458,7 +464,7 @@ an eCos table. In order to take advantag adds the variable names to the table, also providing a buffer where the parsed value will eventually be stored. The values will then be available in the buffers during the processing of the request, presumably in the body -of a c language callback. +of a c language callback or CGI script. For example, if the user wants two form variables, "foo" and "bar", to be parsed automatically, those variable names must be added to the table @@ -478,10 +484,11 @@ bufflen : The length of the buf or, in the specific instance mentioned above: -char var_foo[20]; -char var_bar[20]; -CYG_HTTPD_FVAR_TABLE_ENTRY(hal_form_entry_foo, "foo", var_foo, 20); -CYG_HTTPD_FVAR_TABLE_ENTRY(hal_form_entry_bar, "bar", var_bar, 20); +#define HTML_VAR_LEN 20 +char var_foo[HTML_VAR_LEN]; +char var_bar[HTML_VAR_LEN]; +CYG_HTTPD_FVAR_TABLE_ENTRY(hal_form_entry_foo, "foo", var_foo, HTML_VAR_LEN); +CYG_HTTPD_FVAR_TABLE_ENTRY(hal_form_entry_bar, "bar", var_bar, HTML_VAR_LEN); and after the GET or POST submissions, the list will contain the value @@ -497,14 +504,10 @@ for further processing, keeping in mind in a string of characters to be produced, and any conversion from strings to integer (i.e. atoi()) must be performed in the callback. -In order to avoid stale data, all the buffers in the table are cleared -before running the parser and thus any variable in the list that was not -assigned a new value will be an empty string. - In CGI functions implemented using the objloader the pointers to the variables cannot be accessed directly, since the library will likely not know their location in memory. The proper way to access them is by using the -cyg_httpd_find_form_variable() function: +cyg_httpd_find_form_variable() function from withing the library: char* cyg_httpd_find_form_variable(char* name) @@ -514,10 +517,14 @@ name : name of the form vari returns a pointer to the buffer, or 0 if the variable was not found. -When using the OBJLOADER package within the web server, a -pointer to this function is automatically added to the externals table the -OBJLOADER for relocation. See the OBLOADER paragraph of the ATHTTP user's -guide for the full list of the exported functions. +When using the OBJLOADER package within the web server, an entry +for the cyg_httpd_find_form_variable() function is automatically added to the +externals table the OBJLOADER for relocation. See the OBLOADER paragraph of +the ATHTTP user's guide for the full list of the exported functions. + +In order to avoid stale data, all the buffers in the table are cleared +before running the parser and thus any variable in the list that was not +assigned a new value dureing the request will be an empty string. @@ -530,7 +537,7 @@ using either cyg_httpd_write()< cyg_httpd_write_chunked(). In order to simplify this process the server allows registering -any number of URLs inside internal resources, by providing the URL name, the +any number of URLs as internal resources, by providing the URL name, the pointer to the resource data and its size. When a URL is requested the server will look it up among all internal resources, and if found, it will send out the resource. diff --git a/packages/net/athttpd/current/include/jim.h b/packages/net/athttpd/current/include/jim.h --- a/packages/net/athttpd/current/include/jim.h +++ b/packages/net/athttpd/current/include/jim.h @@ -798,7 +798,7 @@ JIM_STATIC void JIM_API(Jim_Panic) (cons #if defined JIM_EXTENSION || defined JIM_EMBEDDED /* This must be included "inline" inside the extension */ -static void Jim_InitExtension(Jim_Interp *interp) +static __inline__ void Jim_InitExtension(Jim_Interp *interp) { Jim_GetApi = interp->getApiFuncPtr; diff --git a/packages/net/athttpd/current/src/auth.c b/packages/net/athttpd/current/src/auth.c --- a/packages/net/athttpd/current/src/auth.c +++ b/packages/net/athttpd/current/src/auth.c @@ -65,7 +65,7 @@ #include #include -// This is the domain that is currently authorized. +// This is a string that contains the domain that is currently authorized. cyg_uint8 *cyg_httpd_current_authName; CYG_HAL_TABLE_BEGIN(cyg_httpd_auth_table, httpd_auth_table ); @@ -84,7 +84,7 @@ char cyg_httpd_md5_ha2[HASHHEXLEN+1] = { char cyg_httpd_md5_ha1[HASHHEXLEN+1]; char b64string[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; cyg_httpd_auth_table_entry* cyg_httpd_auth_entry_from_path(char *authPath) @@ -129,55 +129,55 @@ cyg_httpd_auth_entry_from_domain(char *a cyg_int32 cyg_httpd_base64_encode(char* to, char* from, cyg_uint32 len ) { - char *fromp = from; - char *top = to; - char cbyte; - char obyte; - cyg_int8 end[3]; + char *fromp = from; + char *top = to; + char cbyte; + char obyte; + cyg_int8 end[3]; - for (; len >= 3; len -= 3) + for (; len >= 3; len -= 3) { - cbyte = *fromp++; - *top++ = b64string[(int)(cbyte >> 2)]; - obyte = (cbyte << 4) & 0x30; + cbyte = *fromp++; + *top++ = b64string[(int)(cbyte >> 2)]; + obyte = (cbyte << 4) & 0x30; - cbyte = *fromp++; - obyte |= (cbyte >> 4); - *top++ = b64string[(cyg_int32)obyte]; - obyte = (cbyte << 2) & 0x3C; + cbyte = *fromp++; + obyte |= (cbyte >> 4); + *top++ = b64string[(cyg_int32)obyte]; + obyte = (cbyte << 2) & 0x3C; - cbyte = *fromp++; - obyte |= (cbyte >> 6); - *top++ = b64string[(cyg_int32)obyte]; - *top++ = b64string[(cyg_int32)(cbyte & 0x3F)]; - } + cbyte = *fromp++; + obyte |= (cbyte >> 6); + *top++ = b64string[(cyg_int32)obyte]; + *top++ = b64string[(cyg_int32)(cbyte & 0x3F)]; + } - if (len) + if (len) { - end[0] = *fromp++; - if (--len ) + end[0] = *fromp++; + if (--len ) end[1] = *fromp++; else end[1] = 0; - end[2] = 0; + end[2] = 0; - cbyte = end[0]; - *top++ = b64string[(cyg_int32)(cbyte >> 2)]; - obyte = (cbyte << 4) & 0x30; + cbyte = end[0]; + *top++ = b64string[(cyg_int32)(cbyte >> 2)]; + obyte = (cbyte << 4) & 0x30; - cbyte = end[1]; - obyte |= (cbyte >> 4); - *top++ = b64string[(cyg_int32)obyte]; - obyte = (cbyte << 2) & 0x3C; + cbyte = end[1]; + obyte |= (cbyte >> 4); + *top++ = b64string[(cyg_int32)obyte]; + obyte = (cbyte << 2) & 0x3C; - if (len ) + if (len ) *top++ = b64string[(cyg_int32)obyte]; - else + else *top++ = '='; - *top++ = '='; - } - *top = 0; - return top - to; + *top++ = '='; + } + *top = 0; + return top - to; } cyg_int32 @@ -190,11 +190,11 @@ cyg_httpd_base64_decode(char* to, char* char obyte; cyg_int32 padding = 0; - for (; len >= 4; len -= 4) + for (; len >= 4; len -= 4) { if ((cbyte = *fromp++) == '=') cbyte = 0; - else + else { if (badchar(cbyte, p ) ) return -1; @@ -204,12 +204,12 @@ cyg_httpd_base64_decode(char* to, char* if ((cbyte = *fromp++) == '=') cbyte = 0; - else + else { - if (badchar(cbyte, p)) + if (badchar(cbyte, p)) return -1; cbyte = p - b64string; - } + } obyte |= cbyte >> 4; *top++ = obyte; @@ -219,7 +219,7 @@ cyg_httpd_base64_decode(char* to, char* cbyte = 0; padding++; } - else + else { padding = 0; if (badchar(cbyte, p)) diff --git a/packages/net/athttpd/current/src/cgi.c b/packages/net/athttpd/current/src/cgi.c --- a/packages/net/athttpd/current/src/cgi.c +++ b/packages/net/athttpd/current/src/cgi.c @@ -43,7 +43,7 @@ * #####DESCRIPTIONBEGIN#### * * Author(s): Anthony Tonizzo (atonizzo@gmail.com) - * Contributors: + * Contributors: Sergei Gavrikov (w3sg@SoftHome.net) * Date: 2006-06-12 * Purpose: * Description: @@ -179,7 +179,7 @@ cyg_int32 cyg_httpd_exec_cgi_tcl(char *f return 0; } - char* tcl_buffer = (char*)cyg_ldr_malloc(sp.st_size); + char* tcl_buffer = (char*)malloc(sp.st_size); CYG_ASSERT(tcl_buffer != NULL, "Cannot malloc() for tcl CGI"); if (tcl_buffer == NULL) { @@ -304,7 +304,7 @@ cyg_httpd_exec_cgi(void) #ifdef CYGOPT_NET_ATHTTPD_USE_CGIBIN_TCL if ( strcmp(extension, CYG_HTTPD_DEFAULT_CGIBIN_TCL_EXTENSION) == 0) { - // Load a cgibin via OBJLOADER. + // Load a cgibin via the TCL interpreter. cyg_int32 rc = cyg_httpd_exec_cgi_tcl(file_name); return rc; } diff --git a/packages/net/athttpd/current/src/forms.c b/packages/net/athttpd/current/src/forms.c --- a/packages/net/athttpd/current/src/forms.c +++ b/packages/net/athttpd/current/src/forms.c @@ -43,7 +43,7 @@ * #####DESCRIPTIONBEGIN#### * * Author(s): Anthony Tonizzo (atonizzo@gmail.com) - * Contributors: + * Contributors: Sergei Gavrikov (w3sg@SoftHome.net) * Date: 2006-06-12 * Purpose: * Description: @@ -192,6 +192,9 @@ cyg_httpd_find_form_variable(char *p) void cyg_httpd_handle_method_POST(void) { + // TODO: Need to support the case in which a POST request will send + // LOTS of data that does not fit into a single inbuffer. For example, + // file transfer over HTTP. cyg_int32 len = read(httpstate.sockets[httpstate.client_index].descriptor, httpstate.inbuffer, CYG_HTTPD_MAXINBUFFER); @@ -200,7 +203,7 @@ cyg_httpd_handle_method_POST(void) return; char *cp = httpstate.inbuffer; - while((*cp == '\r') || (*cp == '\n')) + while ((*cp == '\r') || (*cp == '\n')) cp++; cp[httpstate.inbuffer_len] = ' '; cyg_httpd_store_form_data(cp); @@ -214,9 +217,13 @@ cyg_httpd_handle_method_POST(void) return; } -#ifdef CYGOPT_NET_ATHTTPD_USE_CGIBIN_OBJLOADER - // If we did not find a c language callback handler for this URL see if - // we are trying to execute a CGI via the OBJLOADER package. +#if defined(CYGOPT_NET_ATHTTPD_USE_CGIBIN_OBJLOADER) || \ + defined(CYGOPT_NET_ATHTTPD_USE_CGIBIN_TCL) + // See if we are trying to execute a CGI via one of the supported methods. + // If we the GET request is trying to access a file in the + // CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR directory then it is assumed that + // we are trying to execute a CGI script. The extension of the file will + // determine the appropriate interpreter to use. if (httpstate.url[0] == '/' && !strncmp(httpstate.url + 1, CYGDAT_NET_ATHTTPD_SERVEROPT_CGIDIR, @@ -227,8 +234,6 @@ cyg_httpd_handle_method_POST(void) cyg_httpd_exec_cgi(); return; } - // If the OBJLOADER package is not loaded, then we'll try to send the - // file, which will likely generate a 404. #endif // No handler of any kind for a post request. Must send 404. diff --git a/packages/net/athttpd/current/src/http.c b/packages/net/athttpd/current/src/http.c --- a/packages/net/athttpd/current/src/http.c +++ b/packages/net/athttpd/current/src/http.c @@ -43,7 +43,7 @@ * #####DESCRIPTIONBEGIN#### * * Author(s): Anthony Tonizzo (atonizzo@gmail.com) - * Contributors: + * Contributors: Sergei Gavrikov (w3sg@SoftHome.net) * Date: 2006-06-12 * Purpose: * Description: @@ -159,10 +159,10 @@ cyg_httpd_send_error(cyg_int32 err_type) if(fp == NULL) return; - int payload_size = fread(httpstate.outbuffer, - 1, - CYG_HTTPD_MAXOUTBUFFER, - fp); + ssize_t payload_size = fread(httpstate.outbuffer, + 1, + CYG_HTTPD_MAXOUTBUFFER, + fp); while (payload_size > 0) { ssize_t bytes_written = cyg_httpd_write_chunked(httpstate.outbuffer, @@ -263,7 +263,7 @@ cyg_httpd_parse_date(char *time) char month[4]; struct tm tm_mod; - // We are going to get rid of the day if the week. This is the first + // We are going to get rid of the day of the week. This is always the first // part of the string, separated by a blank. time = strchr( time, ' ' ); if ( time == NULL ) @@ -320,15 +320,15 @@ cyg_httpd_parse_date(char *time) // Finds the mime string into the mime_table associated with a specific // extension. Returns the MIME type to send in the header, or NULL if the -// extension is not int he table. +// extension is not in the table. char* -cyg_httpd_find_mime_string(char *fname) +cyg_httpd_find_mime_string(char *ext) { cyg_httpd_mime_table_entry *entry = cyg_httpd_mime_table; while (entry != cyg_httpd_mime_table_end) { - if (!strcmp((const char*)fname, entry->extension )) + if (!strcmp((const char*)ext, entry->extension )) return entry->mime_string; entry++; } @@ -482,8 +482,8 @@ cyg_httpd_send_file(char *name) return; } - // We are going to try to locate a home page, if any is defined in - // the directory we are trying to access. + // We are going to try to locate an index page in the directory we got + // in the URL. cyg_httpd_append_homepage(file_name); if (file_name[strlen(file_name)-1] == '/') { diff --git a/packages/net/athttpd/current/src/jim.c b/packages/net/athttpd/current/src/jim.c --- a/packages/net/athttpd/current/src/jim.c +++ b/packages/net/athttpd/current/src/jim.c @@ -11698,7 +11698,7 @@ int Jim_InteractivePrompt(Jim_Interp *in printf("Welcome to Jim version %d.%d, " "Copyright (c) 2005 Salvatore Sanfilippo\n", JIM_VERSION / 100, JIM_VERSION % 100); - printf("CVS ID: $Id: jim.c,v 1.163 2005/09/19 15:47:15 antirez Exp $\n"); + printf("CVS ID: $Id: jim.c,v 1.1 2006/07/18 16:37:24 jlarmour Exp $\n"); Jim_SetVariableStrWithStr(interp, "jim_interactive", "1"); while (1) { char buf[1024]; diff --git a/packages/net/athttpd/current/src/socket.c b/packages/net/athttpd/current/src/socket.c --- a/packages/net/athttpd/current/src/socket.c +++ b/packages/net/athttpd/current/src/socket.c @@ -43,7 +43,7 @@ * #####DESCRIPTIONBEGIN#### * * Author(s): Anthony Tonizzo (atonizzo@gmail.com) - * Contributors: + * Contributors: Sergei Gavrikov (w3sg@SoftHome.net) * Date: 2006-06-12 * Purpose: * Description: @@ -105,14 +105,12 @@ cyg_httpd_writev(cyg_iovec *iovec_bufs, // The need for chunked transfers arises from the fact that with dinamic // pages it is not always possible to know the packet size upfront, and thus -// it is not possible to fill the Content-Length: field in the header. -// Today's web browser apparently do not even use 'Content-Length:' because -// many sites that generate dinamic frames send a header with a length of 0. -// Even though this system works (the browsers probably reads everything that -// comes in before the socket is closed and then figure it out) the HTTP -// standard _mandates_ the Content-Length: with a correct valie, and whenever -// that is not possible, chunked transfers must be used. -// This function also handles the case of a chunked frame. +// it is not possible to fill the 'Content-Length:' field in the header. +// Today's web browser use 'Content-Length:' when present in the header and +// when not present they read everything that comes in up to the last 2 \r\n +// and then figure it out. The HTTP standard _mandates_ 'Content-Length:' to +// be present in the header with a correct value, and whenever that is not +// possible, chunked transfers must be used. // // A chunked transer takes the form of: // ----------------------------------------------------------------------------- @@ -136,9 +134,10 @@ cyg_httpd_start_chunked(char *extension) // should be enough, but several posting I read seem to imply otherwise, // at least with early generation browsers that supported the // "Transfer-Encoding: chunked" mechanism. Things might be getting better - // now but I snooped some sites that use the chunked stuff and all of them - // with no exception issue a "Connection: close" on chunked frames even - // if there is nothing in the HTTP 1.1 spec that requires it. + // now but I snooped some sites that use the chunked stuff (Yahoo! for one) + /// and all of them with no exception issue a "Connection: close" on + // chunked frames even if there is nothing in the HTTP 1.1 spec that + // requires it. httpstate.mode |= CYG_HTTPD_MODE_CLOSE_CONN; // We do not cache the CGI script. In case they are used to display @@ -179,10 +178,11 @@ cyg_httpd_end_chunked(void) // This function builds and send out a standard header. It is likely going to // be used by a c language callback function, and thus followed by one or // more calls to cyg_httpd_write(). Unlike cyg_httpd_start_chunked(), this -// call requires prior knowledge of the final size of the frame, and the user +// call requires prior knowledge of the final size of the frame (browsers +// _will_trust_ the "Content-Length:" field when present!), and the user // is expected to make sure that the total number of bytes (octets) sent out -// via 'cyg_httpd_write()' matches the number passed in the len parameter. -// Its use it thus more limited, and the more flexible chunked frames should +// via 'cyg_httpd_write()' matches the number passed in the len parameter. +// Its use is thus more limited, and the more flexible chunked frames should // be used whenever possible. void cyg_httpd_create_std_header(char *extension, int len) @@ -242,8 +242,9 @@ cyg_httpd_process_request(cyg_int32 inde if (httpstate.mode & CYG_HTTPD_MODE_CLOSE_CONN) // There are 2 cases we can be here: // 1) chunked frames close their connection by default - // 2) The client requested the connection be terminated. - // In any case, we close the TX pipe, and wait for the client to + // 2) The client requested the connection be terminated with a + // "Connection: close" in the header + // In any case, we close the TX pipe and wait for the client to // send us an EOF on the receive pipe. This is a more graceful way // to handle the closing of the socket, compared to just calling // close() without first asking the opinion of the client, and @@ -266,6 +267,7 @@ cyg_httpd_handle_new_connection(cyg_int3 { cyg_int32 i; + int fd_client = accept(listener, NULL, NULL); CYG_ASSERT(listener != -1, "accept() failed"); if (fd_client == -1) @@ -336,6 +338,9 @@ cyg_httpd_daemon(cyg_addrword_t data) #ifdef CYGOPT_NET_ATHTTPD_USE_CGIBIN_TCL cyg_httpd_init_tcl_interpreter(); +#if CYGOPT_NET_ATHTTPD_DEBUG_LEVEL > 0 + diag_printf("Tcl interpreter has been initialized...\n"); +#endif #endif cyg_httpd_initialize(); @@ -380,6 +385,7 @@ cyg_httpd_daemon(cyg_addrword_t data) httpstate.fdmax = listener; while (1) { + // The listener is always added to the select() sensitivity list. FD_SET(listener, &httpstate.rfds); struct timeval tv = {CYG_HTTPD_SOCKET_IDLE_TIMEOUT, 0}; rc = select(httpstate.fdmax + 1, &httpstate.rfds, NULL, NULL, &tv); @@ -391,6 +397,10 @@ cyg_httpd_daemon(cyg_addrword_t data) cyg_httpd_handle_new_connection(listener); httpstate.fdmax = listener; + + // The sensitivity list returned by select() can have multiple + // socket descriptors that need service. Loop through the whole + // descriptor list to see if one or more need to be served. for (i = 0; i < CYGPKG_NET_MAXSOCKETS; i ++) { cyg_int32 descr = httpstate.sockets[i].descriptor; @@ -417,13 +427,14 @@ cyg_httpd_daemon(cyg_addrword_t data) } else { - perror("error"); +#if CYGOPT_NET_ATHTTPD_DEBUG_LEVEL > 0 cyg_int8 *ptr = (cyg_int8*)&httpstate.rfds; printf("rfds: %x %x %x %x\n", ptr[0], ptr[1], ptr[2], ptr[3] ); for (i = 0; i < CYGPKG_NET_MAXSOCKETS; i++) if (httpstate.sockets[i].descriptor != 0) diag_printf("Socket in list: %d\n", httpstate.sockets[i].descriptor); +#endif CYG_ASSERT(rc != -1, "Error during select()"); } }