HTTPD.C
资源名称:ertos.rar [点击查看]
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:11k
源码类别:
操作系统开发
开发平台:
DOS
- /*
- * Copyright (c) 1999 Erick Engelke
- */
- #include <rtos.h>
- #include <net.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <time.h>
- #include <strlst.h>
- #include <httpd.h>
- static void http_write( tcp_Socket *s, char *p )
- {
- sock_write( s, p, strlen( p ));
- }
- void html_hdr( tcp_Socket *s, char *title )
- {
- sock_puts( s, "rnrn<html><head><title>");
- sock_puts( s, title );
- sock_puts( s, "</title></head><body>");
- }
- void html_tail( tcp_Socket *s )
- {
- sock_puts( s, "</body></html>");
- }
- void html_datestring( tcp_Socket *s, char *format, DWORD plusseconds )
- {
- int len;
- char buf1[64], *buf2;
- struct tm *time_now;
- time_t secsnow;
- len = strlen( format ) + 64;
- if ( ( buf2 = kcalloc( len , 1 )) == NULL )
- sock_puts( s, "no memory");
- else {
- dos_enter(); // -ew 020401
- time( &secsnow );
- secsnow += plusseconds;
- time_now = localtime( &secsnow );
- strftime( buf1, sizeof( buf1 ),
- "%a, %d %b %Y %X %Z", time_now );
- sprintf( buf2, format, buf1 );
- dos_exit(); // -ew 020401
- sock_puts( s, buf2 );
- kfree( buf2 );
- }
- }
- #define HTTP_BUFSIZE 256
- static void http_fname( char *base, char *fname, char *ext, char *buffer )
- {
- char *p;
- while ( (p = strchr( fname, '/' )) != NULL ) *p = '\';
- /* skip any preceding slashes, .., or D: entries */
- while ( fname[0] == '\' ) fname++;
- while ( (strlen( fname ) > 2 ) && (fname[1] == ':')) fname += 2;
- while ( (strlen( fname ) > 2 ) && (fname[1] == '.')) fname += 2;
- *buffer = 0; /* reset string */
- if ( base ) {
- strcpy( buffer, base );
- strcat( buffer, "\");
- }
- strcat( buffer, fname );
- if ( ext != NULL ) {
- strcat( buffer, ".");
- strcat( buffer, ext );
- }
- }
- int http_dump( tcp_Socket *s, char *base, char *fname, char *ext )
- {
- FILE *f;
- char *buffer;
- char *p;
- int i;
- int retval = 0;
- buffer = kcalloc( HTTP_BUFSIZE, 1 );
- if ( buffer == NULL ) return -1;
- http_fname( base, fname, ext, buffer );
- dos_enter();
- f = fopen( buffer, "rb");
- dos_exit();
- if ( f == NULL ) {
- html_hdr( s, "File not found");
- sock_puts(s,"File: ");
- sock_puts(s, buffer );
- sock_puts(s, "not found");
- html_tail( s );
- retval = -1;
- } else {
- dos_enter();
- while ( (i = fread( buffer, 1, HTTP_BUFSIZE, f )) != 0 ) {
- dos_exit();
- sock_write( s, buffer, i );
- dos_enter();
- }
- fclose( f );
- dos_exit();
- retval = 0;
- }
- kfree( buffer );
- return( retval );
- }
- int http_shtml( tcp_Socket *s, char *base, char *fname, char *ext,
- ssi_type *ssi_list, stringlist *cookies )
- {
- FILE *f;
- char *buffer;
- char *p, *q;
- int i;
- int retval = -1;
- ssi_type *ssi;
- char ch;
- buffer = kcalloc( HTTP_BUFSIZE, 1 );
- if ( buffer == NULL ) return -1;
- http_fname( base, fname, ext, buffer );
- dos_enter();
- f = fopen( buffer, "rb");
- dos_exit();
- if ( f == NULL )
- {
- html_hdr( s, "File not found");
- sock_puts(s,"File: ");
- sock_puts(s, buffer );
- sock_puts(s, "not found");
- html_tail( s );
- retval = -1;
- }
- else
- {
- retval = 0;
- while ( 1 ) {
- dos_enter();
- p = fgets( buffer, HTTP_BUFSIZE, f );
- dos_exit();
- if ( p == NULL ) break;
- p = buffer;
- while ( p != NULL )
- {
- q = p;
- if ( (p = strchr( p, '#')) == NULL )
- {
- if ( *q )
- sock_puts( s, q );
- }
- else
- {
- if ( p[1] != '#' )
- {
- /* not SSI, straight text up to this point */
- ch = *(++p);
- *p = 0;
- http_write( s, q );
- *p = ch; /* restore this first char */
- }
- else
- {
- *p = 0;
- http_write( s, q );
- p = q = p+2;
- p = strchr( p, '#');
- /* tail can be either ## or #, but must be something */
- if ( p == NULL ) continue;
- *p = 0;
- if ( *(++p) == '#' ) p++;
- for ( ssi = ssi_list ; ssi->ssi_name != NULL ; ssi++ )
- {
- if ( !strcmp( ssi->ssi_name, q ))
- {
- ssi->ssi_fn( s, cookies );
- break;
- }
- }
- if ( ssi->ssi_name == NULL ) {
- http_write( s, "--SSI not found: ");
- http_write( s, q );
- sock_puts( s, "--");
- }
- }
- }
- }
- }
- dos_enter();
- fclose( f );
- dos_exit();
- }
- kfree( buffer );
- return( retval );
- }
- /*
- * string_arg - find n'th argument within a command string, zero based
- * - returns NULL if fewer args than necessary
- */
- char *string_arg( char *string, int arg, char *buffer )
- {
- char *p, *eow;
- char ch;
- int i;
- rip( string ); /* remove EOL */
- p = string;
- for ( i = 0 ; i < arg ; ++i ) {
- /* find end of word */
- while ( !isspace( ch = *p )) {
- if ( ch == 0 ) return( NULL );
- p++;
- }
- while ( isspace( ch = *p )) {
- if ( ch == 0 ) return( NULL );
- p++;
- }
- }
- /* we are now at the word we want */
- eow = p;
- i = 0;
- while ( !isspace( ch = *eow++ )) {
- if ( ch == 0 ) break;
- i++;
- }
- /* copy just the word, and then truncate string */
- memcpy( buffer, p, i );
- buffer[ i ] = 0;
- return( buffer );
- }
- #define HTTPPORT 80
- /*
- * implement one http server
- */
- void httpdthread( DWORD ptr )
- {
- tcp_Socket *s;
- char cmd[6] = "";
- char *p, *q, *r, *t, *u, *ext;
- char *buffer;
- char cmdbuf[256];
- char file[ 256 ];
- int i;
- stringlist *cookies;
- void (*userproc)( tcp_Socket *s, char *cmd, char *name, char *ext,
- stringlist *sl );
- userproc = (void *)ptr;
- #define HTTP_BUF_SIZE 1024
- buffer = kcalloc( HTTP_BUF_SIZE , 1);
- if ( buffer == NULL ) rt_halt("out of memory starting httpd");
- if ( userproc == NULL )
- rt_halt( "httpd passed user proc of NULL");
- s = kcalloc( sizeof( tcp_Socket ), 1 );
- do {
- cookies = NULL;
- memset( cmd, 0, sizeof( cmd ));
- ext = NULL;
- *file = 0;
- *cmd = 0;
- /* start listenning */
- tcp_listen( s, HTTPPORT, 0, 0, NULL, 0 );
- /* wait for a connection */
- do {
- rt_sleep( 0 ); /* just waiting */
- if ( tcp_tick( s ) == NULL ) goto reopen;
- } while ( ! sock_established( s ));
- *file = 0;
- sock_mode( s, TCP_MODE_ASCII );
- /* get each line of input text */
- do {
- while ( ! sock_dataready( s )) {
- rt_sleep(0);
- if ( tcp_tick( s ) == NULL ) goto reopen;
- }
- sock_gets( s, buffer, HTTP_BUF_SIZE );
- rip( buffer ); /* remove CR/LF */
- /* empty line signals end of request */
- if ( buffer[0] == 0 ) break;
- /*cdl modify for bbpc 2004-5-25 13:45*/
- if ( kdebug > 1 )
- {
- dos_enter();
- printf("RECEIVED: %srn", buffer ); /*cprintf("RECEIVED: %srn", buffer ); */
- dos_exit();
- }
- if ( !strncmp( buffer, "GET ", 4 ) || !strncmp( buffer, "POST", 4 ) )
- {
- memcpy( cmd, buffer, sizeof(cmd)-1);
- memcpy( cmdbuf, buffer, strlen( buffer ));
- cmd[ sizeof( cmd ) -1 ] = 0;
- for ( p = cmd ; *p ; ++p )
- if ( isspace( *p ) ) *p = 0;
- p = string_arg( buffer, 1, file );
- if ( p != NULL )
- {
- /* find the extension */
- ext = strrchr( file, '/' );
- if ( ext == NULL ) ext = file;
- ext = strrchr( file, '.' );
- if ( ext ) *ext++ = 0;
- }
- }
- else if ( !strnicmp( buffer, "COOKIE:", 7 ))
- {
- #define COOKIES
- #ifdef COOKIES
- if ( cookies == NULL )
- cookies = strlst_new();
- p = buffer + 7;
- while ( isspace( *p ) ) p++;
- /* p at start of each cookie */
- do {
- r = NULL;
- /* find BLAH=... */
- if ( ( q = strchr( p, '=')) != NULL ) {
- *q++ = 0;
- /* see if any more in list */
- if ( ( r = strchr( q, ' ')) != NULL )
- *r++ = 0;
- /* remove separting ';' */
- if ( u = strchr( q, ';' )) *u = 0;
- /* need a copy */
- t = kstrdup( q );
- strlst_adddata( cookies, p, t );
- }
- } while ( ( p = r ) != NULL );
- #endif
- }
- } while ( 1 );
- sock_puts( s, "HTTP/1.1 200 OKrn"
- "Server: eRTOSrn"
- "Connection: close");
- html_datestring(s, "Date: %s", 0);
- html_datestring(s, "Last-Modified: %s", 0);
- /* prepare output */
- (*userproc)( s, cmd, file, ext, cookies );
- reopen:
- #ifdef FLUSHALL
- /* flush all input */
- sock_mode( s, TCP_MODE_BINARY );
- while ( ( i = sock_dataready( s )) > 0 ) {
- if ( i > sizeof( buffer )) i = sizeof( buffer );
- sock_read( s, buffer, i );
- }
- #endif
- sock_close( s );
- /*
- * and wait for it to close
- */
- while ( tcp_tick( s ) )
- rt_sleep( 1 );
- /* free any cookies */
- if ( cookies != NULL ) {
- p = strlst_getfirst( cookies, &q, &r );
- while ( p != NULL ) {
- if ( r != NULL ) kfree( r );
- p = strlst_getnext( cookies, &q, &r );
- }
- strlst_freeall( cookies );
- }
- /* now we are unthreaded, start whole process again */
- } while ( 1 );
- }