|
- #include "util.h"
-
- #include <stdio.h>
- #include <ctype.h> /**< isalnum isdigit */
- #include <string.h> /**< strncmp */
- #include <time.h> /**< strftime */
- #include <sys/time.h> /**< struct timeval */
- #include <sys/resource.h> /**< struct rusage, getrusage */
-
- // timeval -> microseconds
- static int64_t Tv2Ms(struct timeval *p)
- {
- return ((int64_t)p->tv_sec) * 1000000 + (int64_t)p->tv_usec;
- }
-
- /// Render seconds since 1970 as an RFC822 date string.
- /// Return a pointer to that string in a static buffer.
- static char *Rfc822Date(time_t t)
- {
- struct tm *tm;
- static char date[100];
-
- tm = gmtime(&t);
- strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S GMT", tm);
-
- return date;
- }
-
- char *Rfc822DateNow()
- {
- time_t now;
- time(&now);
- return Rfc822Date(now);
- }
-
- /// Parse an RFC822-formatted timestamp as we'd expect from HTTP and return
- /// a Unix epoch time. <= zero is returned on failure.
- time_t ParseRfc822Date(const char *zDate)
- {
- int mday, mon, year, yday, hour, min, sec;
- char zIgnore[4];
- char zMonth[4];
-
- static const char *const azMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
- if (7 == sscanf(zDate, "%3[A-Za-z], %d %3[A-Za-z] %d %d:%d:%d", zIgnore,
- &mday, zMonth, &year, &hour, &min, &sec))
- {
- if (year > 1900) year -= 1900;
-
- for (mon = 0; mon < 12; mon++)
- {
- if(!strncmp(azMonths[mon], zMonth, 3))
- {
- int nDay;
- int isLeapYr;
- static int priorDays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
- isLeapYr = year % 4 == 0 && (year % 100 != 0 || (year + 300) % 400==0);
- yday = priorDays[mon] + mday - 1;
-
- if(isLeapYr && mon > 1) yday++;
-
- nDay = (year - 70) * 365 + (year - 69) / 4 - year / 100 + (year + 300) / 400 + yday;
- return ((time_t)(nDay * 24 + hour) * 60 + min) * 60 + sec;
- }
- }
- }
-
- return 0;
- }
-
- void LogPrint(int lineNum)
- {
- struct timeval now;
- struct tm *ptm;
- struct rusage self;
- size_t sz;
- char date[200];
-
- gettimeofday(&now, 0);
- ptm = localtime(&now.tv_sec);
- strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", ptm);
- getrusage(RUSAGE_SELF, &self);
- /* Log record:
- ** (1) Date and time
- ** (2) IP address
- ** (3) URL being accessed
- ** (4) Referer
- ** (5) Reply status
- ** (6) Bytes received
- ** (7) Bytes sent
- ** (8) Self user time
- ** (9) Self system time
- ** (10) Total wall-clock time
- ** (11) Request number for same TCP/IP connection
- ** (12) User agent
- ** (13) Remote user
- ** (14) Bytes of URL that correspond to the SCRIPT_NAME
- ** (15) Line number in source file
- */
- // fprintf(stdout, "%s,%s,\"%s://%s%s\",\"%s\","
- // "%s,%d,%d,%lld,%lld,%lld,%lld,%lld,%d,\"%s\",\"%s\",%d,%d\n",
- // zDate, zRemoteAddr, zHttpScheme, Escape(zHttpHost), Escape(zScript),
- // Escape(zReferer), zReplyStatus, nIn, nOut,
- // Tv2Ms(&self.ru_utime) - Tv2Ms(&priorSelf.ru_utime),
- // Tv2Ms(&self.ru_stime) - Tv2Ms(&priorSelf.ru_stime),
- // Tv2Ms(&now) - Tv2Ms(&beginTime),
- // nRequest, Escape(zAgent), Escape(zRM),
- // (int)(strlen(zHttpScheme)+strlen(zHttpHost)+strlen(zRealScript)+3),
- // lineNum);
- // priorSelf = self;
- }
-
- int HttpUrlEncodeWithLength(const char *src, size_t srcsize, char *dst, size_t dstsize)
- {
- static const char *kDontEscape = "._-$,;~()";
- static const char *kHex = "0123456789abcdef";
-
- size_t i = 0;
- int ch;
- char *pos;
- const char *end;
-
- if (dst == NULL || dstsize < 1)
- {
- return 0;
- }
-
- if (src == NULL || srcsize == 0)
- {
- dst[0] = 0;
- return 0;
- }
-
- pos = dst;
- end = dst + dstsize - 1;
-
- while (i < srcsize && pos < end)
- {
- ch = src[i];
- if (isalnum(ch) || strchr(kDontEscape, ch) != NULL)
- {
- *pos = (char)ch;
- }
- else if (pos + 2 < end)
- {
- pos[0] = '%';
- pos[1] = kHex[ch >> 4];
- pos[2] = kHex[ch & 0xf];
- pos += 2;
- }
- else
- {
- break;
- }
-
- pos++;
- i++;
- }
-
- *pos = 0;
- return (i == srcsize) ? (int)(pos - dst) : -1;
- }
-
- int HttpUrlDecodeWithFormat(const char *src, char *dst, size_t dstsize, int is_form_url_encoded)
- {
- #define HEXTOI(x) (isdigit(x) ? ((x) - '0') : ((x) - 'W'))
- int i = 0, j = 0, a, b;
- int srcsize, dstlen;
-
- if (dst == NULL || dstsize < 1)
- {
- return 0;
- }
-
- if (src == NULL)
- {
- dst[0] = 0;
- return 0;
- }
-
- srcsize = (int)strlen(src);
- dstlen = (int)dstsize;
-
- while (i < srcsize && j < dstlen - 1)
- {
- if (i < srcsize - 2 && src[i] == '%' && isdigit(*(const uint8_t *)(src + i + 1)) && isxdigit(*(const uint8_t *)(src + i + 2)))
- {
- a = tolower(*(const uint8_t *)(src + i + 1));
- b = tolower(*(const uint8_t *)(src + i + 2));
- dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b));
- i += 2;
- }
- else if (is_form_url_encoded && src[i] == '+')
- {
- dst[j] = ' ';
- }
- else
- {
- dst[j] = src[i];
- }
- i++;
- j++;
- }
-
- dst[j] = 0;
- return (i >= srcsize) ? j : -1;
- }
|