Documentation Source Text

Check-in [333c090d36]
Login

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

Overview
Comment:In althttpd, keep track of wall-clock time in milliseconds, not seconds. And for the user and system times, be sure to subtract out the user and system times for prior requests on the same connection.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 333c090d361f5baf31729d1ee3be671189fa1761
User & Date: drh 2013-12-16 21:30:52.143
Context
2013-12-16
21:42
When the request URI for static content contains extra path elements, report the error as 404 instead of 301. (check-in: 155df5701c user: drh tags: trunk)
21:30
In althttpd, keep track of wall-clock time in milliseconds, not seconds. And for the user and system times, be sure to subtract out the user and system times for prior requests on the same connection. (check-in: 333c090d36 user: drh tags: trunk)
20:13
Add an extra column to the logfile output from althttpd. The 16th column gives the number of characters in the request URI that contribute to the script name. This is useful with substr() in doing queries against specific CGI scripts. (check-in: faec8e5df4 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to misc/althttpd.c.
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149


150
151
152
153
154
155
156
static char *zRemoteUser = 0;    /* REMOTE_USER set by authorization module */
static int nIn = 0;              /* Number of bytes of input */
static int nOut = 0;             /* Number of bytes of output */
static char zReplyStatus[4];     /* Reply status code */
static int statusSent = 0;       /* True after status line is sent */
static char *zLogFile = 0;       /* Log to this file */
static int debugFlag = 0;        /* True if being debugged */
static time_t beginTime;         /* Time when this process starts */
static int closeConnection = 0;  /* True to send Connection: close in reply */
static int nRequest = 0;         /* Number of requests processed */
static int omitLog = 0;          /* Do not make logfile entries if true */
static int useHttps = 0;         /* True to use HTTPS: instead of HTTP: */
static char *zHttp = "http";     /* http or https */
static int useTimeout = 1;       /* True to use times */
static int standalone = 0;       /* Run as a standalone server (no inetd) */
static int ipv6Only = 0;         /* Use IPv6 only */
static int ipv4Only = 0;         /* Use IPv4 only */



/*
** Double any double-quote characters in a string.
*/
static char *Escape(char *z){
  int i, j;
  int n;







|









>
>







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
static char *zRemoteUser = 0;    /* REMOTE_USER set by authorization module */
static int nIn = 0;              /* Number of bytes of input */
static int nOut = 0;             /* Number of bytes of output */
static char zReplyStatus[4];     /* Reply status code */
static int statusSent = 0;       /* True after status line is sent */
static char *zLogFile = 0;       /* Log to this file */
static int debugFlag = 0;        /* True if being debugged */
static struct timeval beginTime; /* Time when this process starts */
static int closeConnection = 0;  /* True to send Connection: close in reply */
static int nRequest = 0;         /* Number of requests processed */
static int omitLog = 0;          /* Do not make logfile entries if true */
static int useHttps = 0;         /* True to use HTTPS: instead of HTTP: */
static char *zHttp = "http";     /* http or https */
static int useTimeout = 1;       /* True to use times */
static int standalone = 0;       /* Run as a standalone server (no inetd) */
static int ipv6Only = 0;         /* Use IPv6 only */
static int ipv4Only = 0;         /* Use IPv4 only */
static struct rusage priorSelf;  /* Previously report SELF time */
static struct rusage priorChild; /* Previously report CHILD time */

/*
** Double any double-quote characters in a string.
*/
static char *Escape(char *z){
  int i, j;
  int n;
165
166
167
168
169
170
171







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  for(i=j=0; (c=z[i])!=0; i++){
    zOut[j++] = c;
    if( c=='"' ) zOut[j++] = c;
  }
  zOut[j] = 0;
  return zOut;
}








/*
** Make an entry in the log file.  If the HTTP connection should be
** closed, then terminate this process.  Otherwise return.
*/
static void MakeLogEntry(int a){
  FILE *log;
  if( zTmpNam ){
    unlink(zTmpNam);
  }
  if( zLogFile && !omitLog ){
    time_t now;
    struct tm *pTm;
    struct rusage self, children;
    int waitStatus;
    char zDate[200];
    char *zRM = zRemoteUser ? zRemoteUser : "";

    if( zScript==0 ) zScript = "";
    if( zRealScript==0 ) zRealScript = "";
    if( zRemoteAddr==0 ) zRemoteAddr = "";
    if( zHttpHost==0 ) zHttpHost = "";
    if( zReferer==0 ) zReferer = "";
    if( zAgent==0 ) zAgent = "";
    time(&now);
    pTm = localtime(&now);
    strftime(zDate, sizeof(zDate), "%Y-%m-%d %H:%M:%S", pTm);
    waitpid(-1, &waitStatus, WNOHANG);
    getrusage(RUSAGE_SELF, &self);
    getrusage(RUSAGE_CHILDREN, &children);
    if( (log = fopen(zLogFile,"a"))!=0 ){
#ifdef COMBINED_LOG_FORMAT
      strftime(zDate, sizeof(zDate), "%d/%b/%Y:%H:%M:%S %z", pTm);







>
>
>
>
>
>
>











|












|
|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  for(i=j=0; (c=z[i])!=0; i++){
    zOut[j++] = c;
    if( c=='"' ) zOut[j++] = c;
  }
  zOut[j] = 0;
  return zOut;
}

/*
** Convert a struct timeval into an integer number of milliseconds
*/
static int tvms(struct timeval *p){
  return (int)(p->tv_sec*1000000 + p->tv_usec);
}

/*
** Make an entry in the log file.  If the HTTP connection should be
** closed, then terminate this process.  Otherwise return.
*/
static void MakeLogEntry(int a){
  FILE *log;
  if( zTmpNam ){
    unlink(zTmpNam);
  }
  if( zLogFile && !omitLog ){
    struct timeval now;
    struct tm *pTm;
    struct rusage self, children;
    int waitStatus;
    char zDate[200];
    char *zRM = zRemoteUser ? zRemoteUser : "";

    if( zScript==0 ) zScript = "";
    if( zRealScript==0 ) zRealScript = "";
    if( zRemoteAddr==0 ) zRemoteAddr = "";
    if( zHttpHost==0 ) zHttpHost = "";
    if( zReferer==0 ) zReferer = "";
    if( zAgent==0 ) zAgent = "";
    gettimeofday(&now, 0);
    pTm = localtime(&now.tv_sec);
    strftime(zDate, sizeof(zDate), "%Y-%m-%d %H:%M:%S", pTm);
    waitpid(-1, &waitStatus, WNOHANG);
    getrusage(RUSAGE_SELF, &self);
    getrusage(RUSAGE_CHILDREN, &children);
    if( (log = fopen(zLogFile,"a"))!=0 ){
#ifdef COMBINED_LOG_FORMAT
      strftime(zDate, sizeof(zDate), "%d/%b/%Y:%H:%M:%S %z", pTm);
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240



241
242
243
244
245
246
247
      ** (16) Bytes of URL that correspond to the SCRIPT_NAME
      */
      fprintf(log,
        "%s,%s,\"%s://%s%s\",\"%s\","
           "%s,%d,%d,%d,%d,%d,%d,%d,%d,\"%s\",\"%s\",%d\n",
        zDate, zRemoteAddr, zHttp, Escape(zHttpHost), Escape(zScript),
        Escape(zReferer), zReplyStatus, nIn, nOut,
        (int)(self.ru_utime.tv_sec*1000000 + self.ru_utime.tv_usec),
        (int)(self.ru_stime.tv_sec*1000000 + self.ru_stime.tv_usec),
        (int)(children.ru_utime.tv_sec*1000000 + children.ru_utime.tv_usec),
        (int)(children.ru_stime.tv_sec*1000000 + children.ru_stime.tv_usec),
        (int)(now - beginTime),
        nRequest, Escape(zAgent), Escape(zRM),
        strlen(zHttp)+strlen(zHttpHost)+strlen(zRealScript)+3
      );



#endif
      fclose(log);
      nIn = nOut = 0;
    }
  }
  if( closeConnection ){
    exit(a);







|
|
|
|
|

|

>
>
>







235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
      ** (16) Bytes of URL that correspond to the SCRIPT_NAME
      */
      fprintf(log,
        "%s,%s,\"%s://%s%s\",\"%s\","
           "%s,%d,%d,%d,%d,%d,%d,%d,%d,\"%s\",\"%s\",%d\n",
        zDate, zRemoteAddr, zHttp, Escape(zHttpHost), Escape(zScript),
        Escape(zReferer), zReplyStatus, nIn, nOut,
        tvms(&self.ru_utime) - tvms(&priorSelf.ru_utime),
        tvms(&self.ru_stime) - tvms(&priorSelf.ru_stime),
        tvms(&children.ru_utime) - tvms(&priorChild.ru_utime),
        tvms(&children.ru_stime) - tvms(&priorChild.ru_stime),
        tvms(&now) - tvms(&beginTime),
        nRequest, Escape(zAgent), Escape(zRM),
        (int)(strlen(zHttp)+strlen(zHttpHost)+strlen(zRealScript)+3)
      );
      priorSelf = self;
      priorChild = children;
      beginTime = now;
#endif
      fclose(log);
      nIn = nOut = 0;
    }
  }
  if( closeConnection ){
    exit(a);
1460
1461
1462
1463
1464
1465
1466
1467
1468

1469
1470
1471
1472
1473
1474
1475
    while( (c = getc(in))!=EOF ){
      putc(c,stdout);
      nOut++;
    }
    fclose(in);
  }else if( countSlashes(zRealScript)!=countSlashes(zScript) ){
    /* The URI refers to a non-executable file so it is static content.  But
    /* there are extra terms in the URI past the end of the content.  We need
    ** to redirected to that relative URLs in the content will be right. */

    StartResponse("301 Moved Permanently");
    if( zServerPort==0 || zServerPort[0]==0 || strcmp(zServerPort,"80")==0 ){
      nOut += printf("Location: %s://%s%s\r\n",
                     zHttp, zServerName, zRealScript);
    }else{
      nOut += printf("Location: %s://%s:%s%s\r\n",
                     zHttp, zServerName, zServerPort, zRealScript);







|
|
>







1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
    while( (c = getc(in))!=EOF ){
      putc(c,stdout);
      nOut++;
    }
    fclose(in);
  }else if( countSlashes(zRealScript)!=countSlashes(zScript) ){
    /* The URI refers to a non-executable file so it is static content.  But
    ** there are extra terms in the URI past the end of the content.  We need
    ** to redirected to that relative URLs in the content will be right.
    */
    StartResponse("301 Moved Permanently");
    if( zServerPort==0 || zServerPort[0]==0 || strcmp(zServerPort,"80")==0 ){
      nOut += printf("Location: %s://%s%s\r\n",
                     zHttp, zServerName, zRealScript);
    }else{
      nOut += printf("Location: %s://%s:%s%s\r\n",
                     zHttp, zServerName, zServerPort, zRealScript);
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
  char *zPermUser = 0;      /* Run daemon with this user's permissions */
  const char *zPort = 0;    /* Implement an HTTP server process */
  int useChrootJail = 1;    /* True to use a change-root jail */
  struct passwd *pwd = 0;   /* Information about the user */

  /* Record the time when processing begins.
  */
  time(&beginTime);

  /* Parse command-line arguments
  */
  while( argc>1 && argv[1][0]=='-' ){
    char *z = argv[1];
    char *zArg = argc>=3 ? argv[2] : "0";
    if( z[0]=='-' && z[1]=='-' ) z++;







|







1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
  char *zPermUser = 0;      /* Run daemon with this user's permissions */
  const char *zPort = 0;    /* Implement an HTTP server process */
  int useChrootJail = 1;    /* True to use a change-root jail */
  struct passwd *pwd = 0;   /* Information about the user */

  /* Record the time when processing begins.
  */
  gettimeofday(&beginTime, 0);

  /* Parse command-line arguments
  */
  while( argc>1 && argv[1][0]=='-' ){
    char *z = argv[1];
    char *zArg = argc>=3 ? argv[2] : "0";
    if( z[0]=='-' && z[1]=='-' ) z++;