HTTPD.C
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:11k
源码类别:

操作系统开发

开发平台:

DOS

  1. /*
  2.  * Copyright (c) 1999 Erick Engelke
  3.  */
  4. #include <rtos.h>
  5. #include <net.h>
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <strlst.h>
  11. #include <httpd.h>
  12. static void http_write( tcp_Socket *s, char *p )
  13. {
  14.     sock_write( s, p, strlen( p ));
  15. }
  16. void html_hdr( tcp_Socket *s, char *title )
  17. {
  18.     sock_puts( s, "rnrn<html><head><title>");
  19.     sock_puts( s, title );
  20.     sock_puts( s, "</title></head><body>");
  21. }
  22. void html_tail( tcp_Socket *s )
  23. {
  24.     sock_puts( s, "</body></html>");
  25. }
  26. void html_datestring( tcp_Socket *s, char *format, DWORD plusseconds )
  27. {
  28.     int len;
  29.     char buf1[64], *buf2;
  30.     struct tm *time_now;
  31.     time_t secsnow;
  32.     len = strlen( format ) + 64;
  33.     if ( ( buf2 = kcalloc( len , 1 )) == NULL )
  34.         sock_puts( s, "no memory");
  35.     else {
  36.         dos_enter();            // -ew 020401
  37.         time( &secsnow );
  38.         secsnow += plusseconds;
  39.         time_now = localtime( &secsnow );
  40.         strftime( buf1, sizeof( buf1 ),
  41.             "%a, %d %b %Y %X %Z", time_now );
  42.         sprintf( buf2, format, buf1 );
  43.         dos_exit();             // -ew 020401
  44.         sock_puts( s, buf2 );
  45.         kfree( buf2 );
  46.     }
  47. }
  48. #define HTTP_BUFSIZE 256
  49. static void http_fname( char *base, char *fname, char *ext, char *buffer )
  50. {
  51.     char *p;
  52.     while ( (p = strchr( fname, '/' )) != NULL ) *p = '\';
  53.     /* skip any preceding slashes, .., or D: entries */
  54.     while ( fname[0] == '\' ) fname++;
  55.     while ( (strlen( fname ) > 2 ) && (fname[1] == ':')) fname += 2;
  56.     while ( (strlen( fname ) > 2 ) && (fname[1] == '.')) fname += 2;
  57.     *buffer = 0;    /* reset string */
  58.     if ( base ) {
  59.         strcpy( buffer, base );
  60.         strcat( buffer, "\");
  61.     }
  62.     strcat( buffer, fname );
  63.     if ( ext != NULL ) {
  64.         strcat( buffer, ".");
  65.         strcat( buffer, ext );
  66.     }
  67. }
  68. int http_dump( tcp_Socket  *s, char *base, char *fname, char *ext )
  69. {
  70.     FILE *f;
  71.     char *buffer;
  72.     char *p;
  73.     int i;
  74.     int retval = 0;
  75.     buffer = kcalloc( HTTP_BUFSIZE, 1 );
  76.     if ( buffer == NULL ) return -1;
  77.     http_fname( base, fname, ext, buffer );
  78.     dos_enter();
  79.     f = fopen( buffer, "rb");
  80.     dos_exit();
  81.     if ( f == NULL ) {
  82.         html_hdr( s, "File not found");
  83.         sock_puts(s,"File: ");
  84.         sock_puts(s, buffer );
  85.         sock_puts(s, "not found");
  86.         html_tail( s );
  87.         retval = -1;
  88.     } else {
  89.         dos_enter();
  90.         while ( (i = fread( buffer, 1, HTTP_BUFSIZE, f )) != 0 ) {
  91.             dos_exit();
  92.             sock_write( s, buffer, i );
  93.             dos_enter();
  94.         }
  95.         fclose( f );
  96.         dos_exit();
  97.         retval = 0;
  98.     }
  99.     kfree( buffer );
  100.     return( retval );
  101. }
  102. int http_shtml( tcp_Socket  *s, char *base, char *fname, char *ext,
  103.     ssi_type *ssi_list, stringlist *cookies )
  104. {
  105.     FILE *f;
  106.     char *buffer;
  107.     char *p, *q;
  108.     int i;
  109.     int retval = -1;
  110.     ssi_type *ssi;
  111.     char ch;
  112.     buffer = kcalloc( HTTP_BUFSIZE, 1 );
  113.     if ( buffer == NULL ) return -1;
  114.     http_fname( base, fname, ext, buffer );
  115.     dos_enter();
  116.     f = fopen( buffer, "rb");
  117.     dos_exit();
  118.     if ( f == NULL ) 
  119.     {
  120.         html_hdr( s, "File not found");
  121.         sock_puts(s,"File: ");
  122.         sock_puts(s, buffer );
  123.         sock_puts(s, "not found");
  124.         html_tail( s );
  125.         retval = -1;
  126.     } 
  127.     else 
  128.     {
  129.         retval = 0;
  130.         while ( 1 ) {
  131.             dos_enter();
  132.             p = fgets( buffer, HTTP_BUFSIZE, f );
  133.             dos_exit();
  134.             if ( p == NULL ) break;
  135.             p = buffer;
  136.             while ( p != NULL ) 
  137.             {
  138.                 q = p;
  139.                 if ( (p = strchr( p, '#')) == NULL ) 
  140.                 {
  141.                     if ( *q )
  142.                         sock_puts( s, q );
  143.                 } 
  144.                 else 
  145.                 {
  146.                     if ( p[1] != '#' ) 
  147.                     {
  148.                         /* not SSI, straight text up to this point */
  149.                         ch = *(++p);
  150.                         *p = 0;
  151.                         http_write( s, q );
  152.                         *p = ch;    /* restore this first char */
  153.                     }
  154.                     else 
  155.                     {
  156.                         *p = 0;
  157.                         http_write( s, q );
  158.                         p = q = p+2;
  159.                         p = strchr( p, '#');
  160.                         /* tail can be either ## or #, but must be something */
  161.                         if ( p == NULL ) continue;
  162.                         *p = 0;
  163.                         if ( *(++p) == '#' ) p++;
  164.                         for ( ssi = ssi_list ; ssi->ssi_name != NULL ; ssi++ ) 
  165.                         {
  166.                             if ( !strcmp( ssi->ssi_name, q )) 
  167.                             {
  168.                                 ssi->ssi_fn( s, cookies  );
  169.                                 break;
  170.                             }
  171.                         }
  172.                         if ( ssi->ssi_name == NULL ) {
  173.                             http_write( s, "--SSI not found: ");
  174.                             http_write( s, q );
  175.                             sock_puts( s, "--");
  176.                         }
  177.                     }
  178.                 }
  179.             }
  180.         }
  181.         dos_enter();
  182.         fclose( f );
  183.         dos_exit();
  184.     }
  185.     kfree( buffer );
  186.     return( retval );
  187. }
  188. /*
  189.  * string_arg - find n'th argument within a command string, zero based
  190.  *            - returns NULL if fewer args than necessary
  191.  */
  192. char *string_arg( char *string, int arg, char *buffer )
  193. {
  194.     char *p, *eow;
  195.     char ch;
  196.     int i;
  197.     rip( string );  /* remove EOL */
  198.     p = string;
  199.     for ( i = 0 ; i < arg ; ++i ) {
  200.         /* find end of word */
  201.         while ( !isspace( ch = *p )) {
  202.             if ( ch == 0 ) return( NULL );
  203.             p++;
  204.         }
  205.         while ( isspace( ch = *p )) {
  206.             if ( ch == 0 ) return( NULL );
  207.             p++;
  208.         }
  209.     }
  210.     /* we are now at the word we want */
  211.     eow = p;
  212.     i = 0;
  213.     while ( !isspace( ch = *eow++ )) {
  214.         if ( ch == 0 ) break;
  215.         i++;
  216.     }
  217.     /* copy just the word, and then truncate string */
  218.     memcpy( buffer, p, i );
  219.     buffer[ i ] = 0;
  220.     return( buffer );
  221. }
  222. #define HTTPPORT 80
  223. /*
  224.  * implement one http server
  225.  */
  226. void httpdthread( DWORD ptr )
  227. {
  228.     tcp_Socket *s;
  229.     char cmd[6] = "";
  230.     char *p, *q, *r, *t, *u, *ext;
  231.     char *buffer;
  232.     char cmdbuf[256];
  233.     char file[ 256 ];
  234.     int i;
  235.     stringlist *cookies;
  236.     void (*userproc)( tcp_Socket *s, char *cmd, char *name, char *ext,
  237.         stringlist *sl );
  238.     userproc = (void *)ptr;
  239. #define HTTP_BUF_SIZE 1024
  240.     buffer = kcalloc( HTTP_BUF_SIZE , 1);
  241.     if ( buffer == NULL ) rt_halt("out of memory starting httpd");
  242.     if ( userproc == NULL )
  243.         rt_halt( "httpd passed user proc of NULL");
  244.     s = kcalloc( sizeof( tcp_Socket ), 1 );
  245.     do {
  246.         cookies = NULL;
  247.         memset( cmd, 0, sizeof( cmd ));
  248.         ext = NULL;
  249.         *file = 0;
  250.         *cmd = 0;
  251.         /* start listenning */
  252.         tcp_listen( s, HTTPPORT, 0, 0, NULL, 0 );
  253.         /* wait for a connection */
  254.         do {
  255.             rt_sleep( 0 );    /* just waiting */
  256.             if ( tcp_tick( s ) == NULL ) goto reopen;
  257.         } while ( ! sock_established( s ));
  258.         *file = 0;
  259.         sock_mode( s, TCP_MODE_ASCII );
  260.         /* get each line of input text */
  261.         do {
  262.             while ( ! sock_dataready( s )) {
  263.                 rt_sleep(0);
  264.                 if ( tcp_tick( s ) == NULL ) goto reopen;
  265.             }
  266.             sock_gets( s, buffer, HTTP_BUF_SIZE );
  267.             rip( buffer );   /* remove CR/LF */
  268.             /* empty line signals end of request */
  269.             if ( buffer[0] == 0 ) break;
  270. /*cdl modify for bbpc 2004-5-25 13:45*/
  271. if ( kdebug > 1 )
  272. {
  273. dos_enter();
  274.      printf("RECEIVED: %srn", buffer ); /*cprintf("RECEIVED: %srn", buffer ); */
  275.      dos_exit();
  276. }
  277.         if ( !strncmp( buffer, "GET ", 4 ) || !strncmp( buffer, "POST", 4 ) )
  278.         {
  279.                 memcpy( cmd, buffer, sizeof(cmd)-1);
  280.                 memcpy( cmdbuf, buffer, strlen( buffer ));
  281.                 cmd[ sizeof( cmd ) -1 ] = 0;
  282.                 for ( p = cmd ; *p ; ++p )
  283.                     if ( isspace( *p ) ) *p = 0;
  284.                 p = string_arg( buffer, 1, file );
  285.                 if ( p != NULL ) 
  286.                 {
  287.                     /* find the extension */
  288.                     ext = strrchr( file, '/' );
  289.                     if ( ext == NULL ) ext = file;
  290.                     ext = strrchr( file, '.' );
  291.                     if ( ext ) *ext++ = 0;
  292.                 }
  293.             } 
  294.             else if ( !strnicmp( buffer, "COOKIE:", 7 )) 
  295.             {
  296. #define COOKIES
  297. #ifdef COOKIES
  298.                 if ( cookies == NULL )
  299.                     cookies = strlst_new();
  300.                 p = buffer + 7;
  301.                 while ( isspace( *p ) ) p++;
  302.                 /* p at start of each cookie */
  303.                 do {
  304.                     r = NULL;
  305.                     /* find BLAH=... */
  306.                     if ( ( q = strchr( p, '=')) != NULL ) {
  307.                         *q++ = 0;
  308.                         /* see if any more in list */
  309.                         if ( ( r = strchr( q, ' ')) != NULL )
  310.                             *r++ =  0;
  311.                         /* remove separting ';' */
  312.                         if ( u = strchr( q, ';' )) *u = 0;
  313.                         /* need a copy */
  314.                         t = kstrdup( q );
  315.                         strlst_adddata( cookies, p, t );
  316.                     }
  317.                 } while ( ( p = r ) != NULL  );
  318. #endif
  319.             }
  320.         } while ( 1 );
  321.         sock_puts( s, "HTTP/1.1 200 OKrn"
  322.                       "Server: eRTOSrn"
  323.                       "Connection: close");
  324.         html_datestring(s, "Date: %s", 0);
  325.         html_datestring(s, "Last-Modified: %s", 0);
  326.         /* prepare output */
  327.         (*userproc)( s, cmd, file, ext, cookies );
  328. reopen:
  329. #ifdef FLUSHALL
  330.         /* flush all input */
  331.         sock_mode( s, TCP_MODE_BINARY );
  332.         while ( ( i = sock_dataready( s )) > 0 ) {
  333.             if ( i > sizeof( buffer )) i = sizeof( buffer );
  334.             sock_read( s, buffer, i );
  335.         }
  336. #endif
  337.         sock_close( s );
  338.         /*
  339.          * and wait for it to close
  340.          */
  341.         while ( tcp_tick( s ) )
  342.             rt_sleep( 1 );
  343.         /* free any cookies */
  344.         if ( cookies != NULL ) {
  345.             p = strlst_getfirst( cookies, &q, &r );
  346.             while ( p != NULL ) {
  347.                 if ( r != NULL ) kfree( r );
  348.                 p = strlst_getnext( cookies, &q, &r );
  349.             }
  350.             strlst_freeall( cookies );
  351.         }
  352.         /* now we are unthreaded, start whole process again */
  353.     } while ( 1 );
  354. }