📄 httpd.c
字号:
}
/* ================================================================= */
/* 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);
/* 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" );
/* 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.
*/
__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,
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 != 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 + -