Documentation Source Text
Check-in [de32cdc42a]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1 Hash:de32cdc42a3b650c2934d7de6fbd562d06086fa6
Date: 2012-10-23 13:29:07
User: drh
Comment:Added "charset=utf-8" marks to the content type in althttpd.c.
Tags And Properties
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to misc/althttpd.c

404
405
406
407
408
409
410

411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
...
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
...
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
...
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
...
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
....
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
....
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
....
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
  exit(0);
}

/*
** This is called if we timeout.
*/
static void Timeout(int NotUsed){

  if( !debugFlag ){
    strcpy(zReplyStatus, "999");
    MakeLogEntry(0);
    exit(0);
  }
}

/*
** Tell the client that there is an error in the script.
*/
static void CgiScriptWritable(void){
  StartResponse("500 CGI Configuration Error");
  nOut += printf(
    "Content-type: text/html\r\n"
    "\r\n"
    "<head><title>CGI Configuration Error</title></head>\n"
    "<body><h1>CGI Configuration Error</h1>\n"
    "The CGI program %s is writable by users other than its owner.\n"
    "</body>\n", zRealScript);
  MakeLogEntry(0);
  exit(0);       
}

/*
** Tell the client that the server malfunctioned.
*/
static void Malfunction(int linenum, const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);
  StartResponse("500 Server Malfunction");
  nOut += printf(
    "Content-type: text/html\r\n"
    "\r\n"
    "<head><title>Server Malfunction</title></head>\n"
    "<body><h1>Server Malfunction</h1>\n"
    "<p>This web server has malfunctioned.\n\n"
    "(Error number: %d)</p>\n", linenum);
  if( zFormat ){
    nOut += printf("<p>");
    nOut += vprintf(zFormat, ap);
    nOut += printf("</p>\n\n");
  }
  nOut += printf("</body>\n");
  MakeLogEntry(0);
  exit(0);       
}

/*
** Do a server redirect to the document specified.  The document
** name not contain scheme or network location or the query string.
................................................................................
    { "gl",         2, "video/gl"                          },
    { "gtar",       4, "application/x-gtar"                },
    { "gz",         2, "application/x-gzip"                },
    { "hdf",        3, "application/x-hdf"                 },
    { "hh",         2, "text/plain"                        },
    { "hqx",        3, "application/mac-binhex40"          },
    { "h",          1, "text/plain"                        },
    { "htm",        3, "text/html"                         },
    { "html",       4, "text/html"                         },
    { "ice",        3, "x-conference/x-cooltalk"           },
    { "ief",        3, "image/ief"                         },
    { "iges",       4, "model/iges"                        },
    { "igs",        3, "model/iges"                        },
    { "ips",        3, "application/x-ipscript"            },
    { "ipx",        3, "application/x-ipix"                },
    { "jad",        3, "text/vnd.sun.j2me.app-descriptor"  },
................................................................................
    { "xyz",        3, "chemical/x-pdb"                    },
    { "zip",        3, "application/zip"                   },
  };

  for(i=nName-1; i>0 && zName[i]!='.'; i--){}
  z = &zName[i+1];
  len = nName - i;
  if( len<sizeof(zSuffix)-1 ){
    strcpy(zSuffix, z);
    for(i=0; zSuffix[i]; i++) zSuffix[i] = tolower(zSuffix[i]);
    first = 0;
    last = sizeof(aMime)/sizeof(aMime[0]);
    while( first<=last ){
      int c;
      i = (first+last)/2;
................................................................................
  nIn += strlen(zLine);
  zMethod = StrDup(GetFirstElement(zLine,&z));
  zRealScript = zScript = StrDup(GetFirstElement(z,&z));
  zProtocol = StrDup(GetFirstElement(z,&z));
  if( zProtocol==0 || strncmp(zProtocol,"HTTP/",5)!=0 || strlen(zProtocol)!=8 ){
    StartResponse("400 Bad Request");
    nOut += printf(
      "Content-type: text/html\r\n"
      "\r\n"
      "<title>Unknown Protocol On HTTP Request</title>\n"
      "<h1>Unknown Protocol</h1>\n"
      "This server does not understand the requested protocol\n"
    );
    MakeLogEntry(0);
    exit(0);
  }
  if( zScript[0]==0 ) NotFound(__LINE__);
  if( forceClose ){
................................................................................
  /* This very simple server only understands the GET, POST
  ** and HEAD methods
  */
  if( strcmp(zMethod,"GET")!=0 && strcmp(zMethod,"POST")!=0
       && strcmp(zMethod,"HEAD")!=0 ){
    StartResponse("501 Not Implemented");
    nOut += printf(
      "Content-type: text/html\r\n"
      "\r\n"
      "<head><title>Method not implemented</title></head>\n"
      "<body><h1>Method not implemented</h1>\n"
      "The %s method is not implemented on this server.\n" 
      "</body>\n",
      zMethod);
    MakeLogEntry(0);
    exit(0);
  }

  /* Get all the optional fields that follow the first line.
  */
................................................................................
    FILE *out;
    char *zBuf;
    int n;

    if( len>MAX_CONTENT_LENGTH ){
      StartResponse("500 Request too large");
      nOut += printf(
        "Content-type: text/html\r\n"
        "\r\n"
        "Too much POST data\n"
        "</body>\n"
      );
      MakeLogEntry(0);
      exit(0);
    }
    sprintf(zTmpNamBuf, "/tmp/-post-data-XXXXXX");
    zTmpNam = zTmpNamBuf;
    mkstemp(zTmpNam);
    out = fopen(zTmpNam,"w");
    if( out==0 ){
      StartResponse("500 Cannot create /tmp file");
      nOut += printf(
        "Content-type: text/html\r\n"
        "\r\n"
        "Could not open \"%s\" for writing\n"
        "</body>\n", zTmpNam
      );
      MakeLogEntry(0);
      exit(0);
    }
    zBuf = SafeMalloc( len );
    if( useTimeout ) alarm(15 + len/2000);
    n = fread(zBuf,1,len,stdin);
................................................................................
      char zBuf[1000];
      Malfunction(__LINE__, "cannot chdir to [%s] from [%s]", 
           zDir, getcwd(zBuf,999));
    }

    /* Setup the environment appropriately.
    */
    for(i=0; i<sizeof(cgienv)/sizeof(cgienv[0]); i++){
      if( *cgienv[i].pzEnvValue ){
        SetEnv(cgienv[i].zEnvName,*cgienv[i].pzEnvValue);
      }
    }
    if( useHttps ){
      putenv("HTTPS=on");
    }
................................................................................
  sHints.ai_protocol = 0;
  rc = getaddrinfo(localOnly ? "localhost": 0, zPort, &sHints, &pAddrs);
  if( rc ){
    fprintf(stderr, "could not get addr info: %s", 
            rc!=EAI_SYSTEM ? gai_strerror(rc) : strerror(errno));
    return 1;
  }
  for(n=0, p=pAddrs; n<sizeof(listener)/sizeof(listener[0]) && p!=0;
        p=p->ai_next){
    listener[n] = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
    if( listener[n]>=0 ){
      /* if we can't terminate nicely, at least allow the socket to be reused */
      setsockopt(listener[n], SOL_SOCKET, SO_REUSEADDR,&opt, sizeof(opt));
      
#if defined(IPV6_V6ONLY)







>













|

<
<
|
|












|

|
<
<
<

<

<

<







 







|
|







 







|







 







|

<
<







 







|

<
<
|
<







 







|


<











|

|
<







 







|







 







|







404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426


427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443



444

445

446

447
448
449
450
451
452
453
...
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
...
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
...
887
888
889
890
891
892
893
894
895


896
897
898
899
900
901
902
...
908
909
910
911
912
913
914
915
916


917

918
919
920
921
922
923
924
....
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
....
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
....
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
  exit(0);
}

/*
** This is called if we timeout.
*/
static void Timeout(int NotUsed){
  (void)NotUsed;
  if( !debugFlag ){
    strcpy(zReplyStatus, "999");
    MakeLogEntry(0);
    exit(0);
  }
}

/*
** Tell the client that there is an error in the script.
*/
static void CgiScriptWritable(void){
  StartResponse("500 CGI Configuration Error");
  nOut += printf(
    "Content-type: text/plain\r\n"
    "\r\n"


    "The CGI program %s is writable by users other than its owner.\n",
    zRealScript);
  MakeLogEntry(0);
  exit(0);       
}

/*
** Tell the client that the server malfunctioned.
*/
static void Malfunction(int linenum, const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);
  StartResponse("500 Server Malfunction");
  nOut += printf(
    "Content-type: text/plain\r\n"
    "\r\n"
    "Web server malfunctioned; error number %d\n\n", linenum);



  if( zFormat ){

    nOut += vprintf(zFormat, ap);

  }

  MakeLogEntry(0);
  exit(0);       
}

/*
** Do a server redirect to the document specified.  The document
** name not contain scheme or network location or the query string.
................................................................................
    { "gl",         2, "video/gl"                          },
    { "gtar",       4, "application/x-gtar"                },
    { "gz",         2, "application/x-gzip"                },
    { "hdf",        3, "application/x-hdf"                 },
    { "hh",         2, "text/plain"                        },
    { "hqx",        3, "application/mac-binhex40"          },
    { "h",          1, "text/plain"                        },
    { "htm",        3, "text/html; charset=utf-8"          },
    { "html",       4, "text/html; charset=utf-8"          },
    { "ice",        3, "x-conference/x-cooltalk"           },
    { "ief",        3, "image/ief"                         },
    { "iges",       4, "model/iges"                        },
    { "igs",        3, "model/iges"                        },
    { "ips",        3, "application/x-ipscript"            },
    { "ipx",        3, "application/x-ipix"                },
    { "jad",        3, "text/vnd.sun.j2me.app-descriptor"  },
................................................................................
    { "xyz",        3, "chemical/x-pdb"                    },
    { "zip",        3, "application/zip"                   },
  };

  for(i=nName-1; i>0 && zName[i]!='.'; i--){}
  z = &zName[i+1];
  len = nName - i;
  if( len<(int)sizeof(zSuffix)-1 ){
    strcpy(zSuffix, z);
    for(i=0; zSuffix[i]; i++) zSuffix[i] = tolower(zSuffix[i]);
    first = 0;
    last = sizeof(aMime)/sizeof(aMime[0]);
    while( first<=last ){
      int c;
      i = (first+last)/2;
................................................................................
  nIn += strlen(zLine);
  zMethod = StrDup(GetFirstElement(zLine,&z));
  zRealScript = zScript = StrDup(GetFirstElement(z,&z));
  zProtocol = StrDup(GetFirstElement(z,&z));
  if( zProtocol==0 || strncmp(zProtocol,"HTTP/",5)!=0 || strlen(zProtocol)!=8 ){
    StartResponse("400 Bad Request");
    nOut += printf(
      "Content-type: text/plain\r\n"
      "\r\n"


      "This server does not understand the requested protocol\n"
    );
    MakeLogEntry(0);
    exit(0);
  }
  if( zScript[0]==0 ) NotFound(__LINE__);
  if( forceClose ){
................................................................................
  /* This very simple server only understands the GET, POST
  ** and HEAD methods
  */
  if( strcmp(zMethod,"GET")!=0 && strcmp(zMethod,"POST")!=0
       && strcmp(zMethod,"HEAD")!=0 ){
    StartResponse("501 Not Implemented");
    nOut += printf(
      "Content-type: text/plain\r\n"
      "\r\n"


      "The %s method is not implemented on this server.\n",

      zMethod);
    MakeLogEntry(0);
    exit(0);
  }

  /* Get all the optional fields that follow the first line.
  */
................................................................................
    FILE *out;
    char *zBuf;
    int n;

    if( len>MAX_CONTENT_LENGTH ){
      StartResponse("500 Request too large");
      nOut += printf(
        "Content-type: text/plain\r\n"
        "\r\n"
        "Too much POST data\n"

      );
      MakeLogEntry(0);
      exit(0);
    }
    sprintf(zTmpNamBuf, "/tmp/-post-data-XXXXXX");
    zTmpNam = zTmpNamBuf;
    mkstemp(zTmpNam);
    out = fopen(zTmpNam,"w");
    if( out==0 ){
      StartResponse("500 Cannot create /tmp file");
      nOut += printf(
        "Content-type: text/plain\r\n"
        "\r\n"
        "Could not open \"%s\" for writing\n", zTmpNam

      );
      MakeLogEntry(0);
      exit(0);
    }
    zBuf = SafeMalloc( len );
    if( useTimeout ) alarm(15 + len/2000);
    n = fread(zBuf,1,len,stdin);
................................................................................
      char zBuf[1000];
      Malfunction(__LINE__, "cannot chdir to [%s] from [%s]", 
           zDir, getcwd(zBuf,999));
    }

    /* Setup the environment appropriately.
    */
    for(i=0; i<(int)(sizeof(cgienv)/sizeof(cgienv[0])); i++){
      if( *cgienv[i].pzEnvValue ){
        SetEnv(cgienv[i].zEnvName,*cgienv[i].pzEnvValue);
      }
    }
    if( useHttps ){
      putenv("HTTPS=on");
    }
................................................................................
  sHints.ai_protocol = 0;
  rc = getaddrinfo(localOnly ? "localhost": 0, zPort, &sHints, &pAddrs);
  if( rc ){
    fprintf(stderr, "could not get addr info: %s", 
            rc!=EAI_SYSTEM ? gai_strerror(rc) : strerror(errno));
    return 1;
  }
  for(n=0, p=pAddrs; n<(int)(sizeof(listener)/sizeof(listener[0])) && p!=0;
        p=p->ai_next){
    listener[n] = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
    if( listener[n]>=0 ){
      /* if we can't terminate nicely, at least allow the socket to be reused */
      setsockopt(listener[n], SOL_SOCKET, SO_REUSEADDR,&opt, sizeof(opt));
      
#if defined(IPV6_V6ONLY)