215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
zPath = g.zTop;
if( zPath[0]==0 ) zPath = "/";
}
if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){
zSecure = " secure;";
}
if( lifetime>0 ){
lifetime += (int)time(0);
blob_appendf(&extraHeader,
"Set-Cookie: %s=%t; Path=%s; expires=%z; HttpOnly;%s Version=1\r\n",
zName, zValue, zPath, cgi_rfc822_datestamp(lifetime), zSecure);
}else{
blob_appendf(&extraHeader,
"Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n",
zName, zValue, zPath, zSecure);
}
}
|
<
|
|
|
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
zPath = g.zTop;
if( zPath[0]==0 ) zPath = "/";
}
if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){
zSecure = " secure;";
}
if( lifetime>0 ){
blob_appendf(&extraHeader,
"Set-Cookie: %s=%t; Path=%s; max-age=%d; HttpOnly;%s Version=1\r\n",
zName, zValue, zPath, lifetime, zSecure);
}else{
blob_appendf(&extraHeader,
"Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n",
zName, zValue, zPath, zSecure);
}
}
|
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
}else if( etag_tag()!=0 ){
fprintf(g.httpOut, "ETag: %s\r\n", etag_tag());
fprintf(g.httpOut, "Cache-Control: max-age=%d\r\n", etag_maxage());
}else{
fprintf(g.httpOut, "Cache-control: no-cache\r\n");
}
if( blob_size(&extraHeader)>0 ){
fprintf(g.httpOut, "%s", blob_buffer(&extraHeader));
}
/* Add headers to turn on useful security options in browsers. */
fprintf(g.httpOut, "X-Frame-Options: SAMEORIGIN\r\n");
|
>
>
>
>
|
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
|
fprintf(g.httpOut, "Cache-Control: max-age=31536000\r\n");
}else if( etag_tag()!=0 ){
fprintf(g.httpOut, "ETag: %s\r\n", etag_tag());
fprintf(g.httpOut, "Cache-Control: max-age=%d\r\n", etag_maxage());
}else{
fprintf(g.httpOut, "Cache-control: no-cache\r\n");
}
if( etag_mtime()>0 ){
fprintf(g.httpOut, "Last-Modified: %s\r\n",
cgi_rfc822_datestamp(etag_mtime()));
}
if( blob_size(&extraHeader)>0 ){
fprintf(g.httpOut, "%s", blob_buffer(&extraHeader));
}
/* Add headers to turn on useful security options in browsers. */
fprintf(g.httpOut, "X-Frame-Options: SAMEORIGIN\r\n");
|
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
|
** Parse an RFC822-formatted timestamp as we'd expect from HTTP and return
** a Unix epoch time. <= zero is returned on failure.
**
** Note that this won't handle all the _allowed_ HTTP formats, just the
** most popular one (the one generated by cgi_rfc822_datestamp(), actually).
*/
time_t cgi_rfc822_parsedate(const char *zDate){
struct tm t;
char zIgnore[16];
char zMonth[16];
memset(&t, 0, sizeof(t));
if( 7==sscanf(zDate, "%12[A-Za-z,] %d %12[A-Za-z] %d %d:%d:%d", zIgnore,
&t.tm_mday, zMonth, &t.tm_year, &t.tm_hour, &t.tm_min,
&t.tm_sec)){
if( t.tm_year > 1900 ) t.tm_year -= 1900;
for(t.tm_mon=0; azMonths[t.tm_mon]; t.tm_mon++){
if( !fossil_strnicmp( azMonths[t.tm_mon], zMonth, 3 )){
return mkgmtime(&t);
}
}
}
return 0;
}
/*
** Convert a struct tm* that represents a moment in UTC into the number
** of seconds in 1970, UTC.
*/
time_t mkgmtime(struct tm *p){
time_t t;
int nDay;
int isLeapYr;
/* Days in each month: 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 */
static int priorDays[] = { 0, 31, 59, 90,120,151,181,212,243,273,304,334 };
if( p->tm_mon<0 ){
int nYear = (11 - p->tm_mon)/12;
p->tm_year -= nYear;
p->tm_mon += nYear*12;
}else if( p->tm_mon>11 ){
p->tm_year += p->tm_mon/12;
p->tm_mon %= 12;
}
isLeapYr = p->tm_year%4==0 && (p->tm_year%100!=0 || (p->tm_year+300)%400==0);
p->tm_yday = priorDays[p->tm_mon] + p->tm_mday - 1;
if( isLeapYr && p->tm_mon>1 ) p->tm_yday++;
nDay = (p->tm_year-70)*365 + (p->tm_year-69)/4 -p->tm_year/100 +
(p->tm_year+300)/400 + p->tm_yday;
t = ((nDay*24 + p->tm_hour)*60 + p->tm_min)*60 + p->tm_sec;
return t;
}
/*
** Check the objectTime against the If-Modified-Since request header. If the
** object time isn't any newer than the header, we immediately send back
** a 304 reply and exit.
*/
|
|
|
|
|
|
>
|
<
<
|
|
|
|
>
|
<
<
<
|
<
<
|
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
<
|
|
>
>
>
|
|
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
|
** Parse an RFC822-formatted timestamp as we'd expect from HTTP and return
** a Unix epoch time. <= zero is returned on failure.
**
** Note that this won't handle all the _allowed_ HTTP formats, just the
** most popular one (the one generated by cgi_rfc822_datestamp(), actually).
*/
time_t cgi_rfc822_parsedate(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", 0};
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; azMonths[mon]; 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 };
if( mon<0 ){
int nYear = (11 - mon)/12;
year -= nYear;
mon += nYear*12;
}else if( mon>11 ){
year += mon/12;
mon %= 12;
}
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;
}
/*
** Check the objectTime against the If-Modified-Since request header. If the
** object time isn't any newer than the header, we immediately send back
** a 304 reply and exit.
*/
|