Documentation Source Text

Check-in [c4dcea55cd]
Login

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

Overview
Comment:Improved redirect handling in althttpd.c
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:c4dcea55cdba427518875f1128ce2bb5fa290ca078c3717ceb6616581368ac9b
User & Date: drh 2018-01-30 17:06:27
Context
2018-01-30
23:44
Remove an unused variable from althttpd.c. check-in: 94b9b95bee user: drh tags: trunk
17:06
Improved redirect handling in althttpd.c check-in: c4dcea55cd user: drh tags: trunk
2018-01-29
18:38
Add documentation for the zipfile() aggregate function. check-in: 1582bada14 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to misc/althttpd.c.

466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
....
1605
1606
1607
1608
1609
1610
1611

1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
....
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726

/*
** Compare two ETag values. Return 0 if they match and non-zero if they differ.
**
** The one on the left might be a NULL pointer and it might be quoted.
*/
static int CompareEtags(const char *zA, const char *zB){
  int lenB;
  if( zA==0 ) return 1;
  if( zA[0]=='"' ){
    int lenB = (int)strlen(zB);
    if( strncmp(zA+1, zB, lenB)==0 && zA[lenB+1]=='"' ) return 0;
  }
  return strcmp(zA, zB);
}
................................................................................
    /* Read and process the first line of the header returned by the
    ** CGI script.
    */
    if( useTimeout ) alarm(15);
    while( fgets(zLine,sizeof(zLine),in) && !isspace(zLine[0]) ){
      if( strncasecmp(zLine,"Location:",9)==0 ){
        int i;

        RemoveNewline(zLine);
        z = &zLine[10];
        while( isspace(*z) ){ z++; }
        for(i=0; z[i]; i++){
          if( z[i]=='?' ){
            zQuerySuffix = StrDup("");
          }
        }
        
        if( z[0]=='/' && z[1]=='/' ){
          /* The scheme is missing.  Add it in before redirecting */
          StartResponse("302 Redirect");
          nOut += printf("Location: %s:%s%s\r\n",zHttp,z,zQuerySuffix);
          continue;
        }else if( z[0]=='/' ){
          /* The scheme and network location are missing but we have
          ** an absolute path. */
          Redirect(z, 0, __LINE__); /* LOG: Redirect from CGI */
          continue;
        }
        /* Check to see if there is a scheme prefix */
        for(i=0; z[i] && z[i]!=':' && z[i]!='/'; i++){}
        if( z[i]==':' ){
          /* We have a scheme.  Assume there is an absolute URL */
          StartResponse("302 Redirect");
          nOut += printf("Location: %s%s\r\n",z,zQuerySuffix);
          continue;
        }
        /* Must be a relative pathname.  Construct the absolute pathname
        ** and redirect to it. */
        i = strlen(zRealScript);
        while( i>0 && zRealScript[i-1]!='/' ){ i--; }
        while( i>0 && zRealScript[i-1]=='/' ){ i--; }
        while( *z=='.' ){
          if( z[1]=='/' ){
            z += 2;
          }else if( z[1]=='.' && z[2]=='/' ){
            while( i>0 && zRealScript[i-1]!='/' ){ i--; }
            while( i>0 && zRealScript[i-1]=='/' ){ i--; }
            z += 3;
          }else{
            continue;
          }
        }
        StartResponse("302 Redirect");
        nOut += printf("Location: %s://%s",zHttp,zServerName);
        if( strcmp(zServerPort,"80") ){
          nOut += printf(":%s",zServerPort);
        }
        nOut += printf("%.*s/%s%s\r\n\r\n",i,zRealScript,z,zQuerySuffix);
        MakeLogEntry(0, __LINE__); /* LOG: CGI redirect */
        return;
      }else if( strncasecmp(zLine,"Status:",7)==0 ){
        int i;
        for(i=7; isspace(zLine[i]); i++){}
        nOut += printf("%s %s", zProtocol, &zLine[i]);
        strncpy(zReplyStatus, &zLine[i], 3);
        zReplyStatus[3] = 0;
        statusSent = 1;
................................................................................
    ** actual content file name, report that as a 404 error. */
    NotFound(__LINE__); /* LOG: Excess URI content past static file name */
  }else{
    /* If it isn't executable then it
    ** must a simple file that needs to be copied to output.
    */
    const char *zContentType = GetMimeType(zFile, lenFile);
    const char *zTag;
    char zETag[100];

    if( zTmpNam ) unlink(zTmpNam);
    sprintf(zETag, "m%xs%x", (int)statbuf.st_mtime, (int)statbuf.st_size);
    if( CompareEtags(zIfNoneMatch,zETag)==0 ){
      StartResponse("304 Not Modified");
      nOut += printf("Cache-Control: max-age=%d\r\n", mxAge);







<







 







>



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<







466
467
468
469
470
471
472

473
474
475
476
477
478
479
....
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614






















1615


























1616
1617
1618
1619
1620
1621
1622
....
1664
1665
1666
1667
1668
1669
1670

1671
1672
1673
1674
1675
1676
1677

/*
** Compare two ETag values. Return 0 if they match and non-zero if they differ.
**
** The one on the left might be a NULL pointer and it might be quoted.
*/
static int CompareEtags(const char *zA, const char *zB){

  if( zA==0 ) return 1;
  if( zA[0]=='"' ){
    int lenB = (int)strlen(zB);
    if( strncmp(zA+1, zB, lenB)==0 && zA[lenB+1]=='"' ) return 0;
  }
  return strcmp(zA, zB);
}
................................................................................
    /* Read and process the first line of the header returned by the
    ** CGI script.
    */
    if( useTimeout ) alarm(15);
    while( fgets(zLine,sizeof(zLine),in) && !isspace(zLine[0]) ){
      if( strncasecmp(zLine,"Location:",9)==0 ){
        int i;
        StartResponse("302 Redirect");
        RemoveNewline(zLine);
        z = &zLine[10];
        while( isspace(*z) ){ z++; }






















        nOut += printf("Location: %s\r\n",z);


























      }else if( strncasecmp(zLine,"Status:",7)==0 ){
        int i;
        for(i=7; isspace(zLine[i]); i++){}
        nOut += printf("%s %s", zProtocol, &zLine[i]);
        strncpy(zReplyStatus, &zLine[i], 3);
        zReplyStatus[3] = 0;
        statusSent = 1;
................................................................................
    ** actual content file name, report that as a 404 error. */
    NotFound(__LINE__); /* LOG: Excess URI content past static file name */
  }else{
    /* If it isn't executable then it
    ** must a simple file that needs to be copied to output.
    */
    const char *zContentType = GetMimeType(zFile, lenFile);

    char zETag[100];

    if( zTmpNam ) unlink(zTmpNam);
    sprintf(zETag, "m%xs%x", (int)statbuf.st_mtime, (int)statbuf.st_size);
    if( CompareEtags(zIfNoneMatch,zETag)==0 ){
      StartResponse("304 Not Modified");
      nOut += printf("Cache-Control: max-age=%d\r\n", mxAge);