📄 httpd.c
字号:
if (FD_ISSET(server_socket, &readfds)) { client_socket = accept( server_socket, &client_address, &calen ); cyg_httpd_process(client_socket, &client_address); }#ifdef CYGPKG_NET_INET6 if (FD_ISSET(server_socket6, &readfds)) { client_socket = accept( server_socket6, &client_address, &calen ); cyg_httpd_process(client_socket, &client_address); }#endif } while(1);}/* ================================================================= *//* Initialization thread * * Optionally delay for a time before getting the network * running. Then create and bind the server socket and put it into * listen mode. Spawn any further server threads, then enter server * mode. */static void cyg_httpd_init(cyg_addrword_t arg){ int i; int err = 0; /* Delay for a configurable length of time to give the application * a chance to get going, or even complete, without interference * from the HTTPD. */ if( CYGNUM_HTTPD_SERVER_DELAY > 0 ) { cyg_thread_delay( CYGNUM_HTTPD_SERVER_DELAY ); } server_address.sin_family = AF_INET; server_address.sin_len = sizeof(server_address); server_address.sin_addr.s_addr = INADDR_ANY; server_address.sin_port = htons(CYGNUM_HTTPD_SERVER_PORT);#ifdef CYGPKG_NET_INET6 server_address6.sin6_family = AF_INET6; server_address6.sin6_len = sizeof(server_address6); server_address6.sin6_addr = in6addr_any; server_address6.sin6_port = htons(CYGNUM_HTTPD_SERVER_PORT);#endif /* Get the network going. This is benign if the application has * already done this. */ init_all_network_interfaces(); /* Create and bind the server socket. */ server_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); CYG_ASSERT( server_socket > 0, "Socket create failed"); err = bind( server_socket, (struct sockaddr *)&server_address, sizeof(server_address) ); CYG_ASSERT( err == 0, "bind() returned error"); err = listen( server_socket, SOMAXCONN ); CYG_ASSERT( err == 0, "listen() returned error" );#ifdef CYGPKG_NET_INET6 server_socket6 = socket( AF_INET6, SOCK_STREAM, IPPROTO_TCP ); CYG_ASSERT( server_socket6 > 0, "Socket AF_INET6 create failed"); err = bind( server_socket6, (struct sockaddr *)&server_address6, sizeof(server_address6) ); CYG_ASSERT( err == 0, "bind(AF_INET6) returned error"); err = listen( server_socket6, SOMAXCONN ); CYG_ASSERT( err == 0, "listen(AF_INET6) returned error" );#endif /* If we are configured to have more than one server thread, * create them now. */ for( i = 1; i < CYGNUM_HTTPD_THREAD_COUNT; i++ ) { cyg_thread_create( CYGNUM_HTTPD_THREAD_PRIORITY, cyg_httpd_server, 0, "HTTPD", &httpd_stacks[i][0], sizeof(httpd_stacks[i]), &httpd_thread[i], &httpd_thread_object[i] ); cyg_thread_resume( httpd_thread[i] ); } /* Now go be a server ourself. */ cyg_httpd_server(arg);}/* ================================================================= *//* System initializer * * This is called from the static constructor in init.cxx. It spawns * the main server thread and makes it ready to run. It can also be * called explicitly by the application if the auto start option is * disabled. */__externC void cyg_httpd_startup(void){ cyg_thread_create( CYGNUM_HTTPD_THREAD_PRIORITY, cyg_httpd_init, 0, "HTTPD", &httpd_stacks[0][0], sizeof(httpd_stacks[0]), &httpd_thread[0], &httpd_thread_object[0] ); cyg_thread_resume( httpd_thread[0] );}/* ================================================================= *//* HTTP protocol handling * * cyg_http_start() generates an HTTP header with the given content * type and, if non-zero, length. * cyg_http_finish() just adds a couple of newlines for luck and * flushes the stream. */__externC void cyg_http_start( FILE *client, char *content_type, int content_length ){ fputs( "HTTP/1.1 200 OK\n" "Server: " CYGDAT_HTTPD_SERVER_ID "\n", client ); if( content_type != NULL ) fprintf( client,"Content-type: %s\n", content_type ); if( content_length != 0 ) fprintf( client, "Content-length: %d\n", content_length ); fputs( "Connection: close\n" "\n", client ); }__externC void cyg_http_finish( FILE *client ){ fputs( "\n\n", client ); fflush( client );} /* ================================================================= *//* HTML tag generation * * These functions generate standard HTML begin and end tags. By using * these rather than direct printf()s we help to reduce the number of * distinct strings present in the executable. */__externC void cyg_html_tag_begin( FILE *client, char *tag, char *attr ){ char *pad = ""; if( attr == NULL ) attr = pad; else if( attr[0] != 0 ) pad = " "; fprintf(client, "<%s%s%s>\n",tag,pad,attr);}__externC void cyg_html_tag_end( FILE *client, char *tag ){ fprintf( client, "<%s%s%s>\n","/",tag,"");}/* ================================================================= *//* Parse form request data * * Given a form response string, we parse it into an argv/environment * style array of "name=value" strings. We also convert any '+' * separators back into spaces. * * TODO: also translate any %xx escape sequences back into real * characters. */__externC void cyg_formdata_parse( char *data, char *list[], int size ){ char *p = data; int i = 0; list[i] = p; while( p && *p != 0 && i < size-1 ) { if( *p == '&' ) { *p++ = 0; list[++i] = p; continue; } if( *p == '+' ) *p = ' '; p++; } list[++i] = 0;}/* ----------------------------------------------------------------- *//* Search for a form response value * * Search a form response list generated by cyg_formdata_parse() for * the named element. If it is found a pointer to the value part is * returned. If it is not found a NULL pointer is returned. */__externC char *cyg_formlist_find( char *list[], char *name ){ while( *list != 0 ) { char *p = *list; char *q = name; while( *p == *q ) p++, q++; if( *q == 0 && *p == '=' ) return p+1; list++; } return 0;}/* ================================================================= *//* Predefined page handlers *//* ----------------------------------------------------------------- *//* Send an HTML page from a single string * * This just sends the string passed as the argument with an HTTP * header that describes it as HTML. This is useful for sending * straightforward static web content. */__externC cyg_bool cyg_httpd_send_html( FILE *client, char *filename, char *request, void *arg ){ html_begin( client ); fwrite( arg, 1, strlen((char *)arg), client ); html_end( client ); return true;}/* ----------------------------------------------------------------- *//* Send arbitrary data * * This takes a pointer to a cyg_httpd_data structure as the argument * and sends the data therein after a header that uses the content * type and size from the structure. This is useful for non-HTML data * such a images. */__externC cyg_bool cyg_httpd_send_data( FILE *client, char *filename, char *request, void *arg ){ cyg_httpd_data *data = (cyg_httpd_data *)arg; cyg_http_start( client, data->content_type, data->content_length ); fwrite( data->data, 1, data->content_length, client ); return true;}/* ----------------------------------------------------------------- *//* end of httpd.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -