Mercurial > hg > nginx-ranges
view src/core/ngx_times.c @ 34:aab2ea7c0458 NGINX_0_1_17
nginx 0.1.17
*) Change: the ngx_http_rewrite_module was rewritten from the scratch.
Now it is possible to redirect, to return the error codes, to check
the variables and referrers. The directives can be used inside
locations. The redirect directive was canceled.
*) Feature: the ngx_http_geo_module.
*) Feature: the proxy_set_x_var and fastcgi_set_var directives.
*) Bugfix: the location configuration with "=" modifier may be used in
another location.
*) Bugfix: the correct content type was set only for requests that use
small caps letters in extension.
*) Bugfix: if the proxy_pass or fastcgi_pass directives were set in the
location, and access was denied, and the error was redirected to a
static page, then the segmentation fault occurred.
*) Bugfix: if in a proxied "Location" header was a relative URL, then a
host name and a slash were added to them; bug appeared in 0.1.14.
*) Bugfix: the system error message was not logged on Linux.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 03 Feb 2005 00:00:00 +0300 |
parents | 45fe5b98a9de |
children | 2879cd3a40cb |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev */ #include <ngx_config.h> #include <ngx_core.h> ngx_epoch_msec_t ngx_elapsed_msec; ngx_epoch_msec_t ngx_old_elapsed_msec; ngx_epoch_msec_t ngx_start_msec; static ngx_tm_t ngx_cached_gmtime; static ngx_int_t ngx_gmtoff; /* * In the threaded mode only one thread updates the cached time and strings * and these operations are protected by the mutex. The reading of the cached * time and strings is not protected by the mutex. To avoid the race * conditions for non-atomic values we use the NGX_TIME_SLOTS slots to store * time value and strings. Thus thread may get the corrupted values only * if it is preempted while copying and then it is not scheduled to run * more than NGX_TIME_SLOTS seconds. */ #if (NGX_THREADS) #define NGX_TIME_SLOTS 60 static ngx_uint_t slot = NGX_TIME_SLOTS; static ngx_mutex_t *ngx_time_mutex; #else #define NGX_TIME_SLOTS 1 #define slot 0 #endif #if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE)) volatile time_t *ngx_cached_time; static time_t cached_time[NGX_TIME_SLOTS]; #else volatile time_t ngx_cached_time; #endif ngx_thread_volatile ngx_str_t ngx_cached_err_log_time; ngx_thread_volatile ngx_str_t ngx_cached_http_time; ngx_thread_volatile ngx_str_t ngx_cached_http_log_time; static u_char cached_err_log_time[NGX_TIME_SLOTS] [sizeof("1970/09/28 12:00:00")]; static u_char cached_http_time[NGX_TIME_SLOTS] [sizeof("Mon, 28 Sep 1970 06:00:00 GMT")]; static u_char cached_http_log_time[NGX_TIME_SLOTS] [sizeof("28/Sep/1970:12:00:00 +0600")]; static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; void ngx_time_init() { struct timeval tv; ngx_memzero(&ngx_cached_gmtime, sizeof(ngx_tm_t)); #ifdef ngx_tm_zone ngx_cached_gmtime.ngx_tm_zone = "GMT"; #endif ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1; ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1; #if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE)) ngx_cached_time = &cached_time[0]; #endif ngx_gettimeofday(&tv); ngx_start_msec = (ngx_epoch_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; ngx_old_elapsed_msec = 0; ngx_elapsed_msec = 0; #if !(NGX_WIN32) tzset(); #endif ngx_time_update(tv.tv_sec); } #if (NGX_THREADS) ngx_int_t ngx_time_mutex_init(ngx_log_t *log) { if (!(ngx_time_mutex = ngx_mutex_init(log, NGX_MUTEX_LIGHT))) { return NGX_ERROR; } return NGX_OK; } #endif void ngx_time_update(time_t s) { u_char *p; ngx_tm_t tm; if (ngx_time() == s) { return; } #if (NGX_THREADS) if (ngx_mutex_trylock(ngx_time_mutex) != NGX_OK) { return; } if (slot == NGX_TIME_SLOTS) { slot = 0; } else { slot++; } #if (NGX_THREADS && (NGX_TIME_T_SIZE > NGX_SIG_ATOMIC_T_SIZE)) ngx_cached_time = &cached_time[slot]; #endif #endif ngx_time() = s; ngx_gmtime(s, &ngx_cached_gmtime); p = cached_http_time[slot]; ngx_sprintf(p, "%s, %02d %s %4d %02d:%02d:%02d GMT", week[ngx_cached_gmtime.ngx_tm_wday], ngx_cached_gmtime.ngx_tm_mday, months[ngx_cached_gmtime.ngx_tm_mon - 1], ngx_cached_gmtime.ngx_tm_year, ngx_cached_gmtime.ngx_tm_hour, ngx_cached_gmtime.ngx_tm_min, ngx_cached_gmtime.ngx_tm_sec); ngx_cached_http_time.data = p; #if (NGX_HAVE_GETTIMEZONE) ngx_gmtoff = ngx_gettimezone(); ngx_gmtime(s + ngx_gmtoff * 60, &tm); #elif (NGX_HAVE_GMTOFF) ngx_localtime(&tm); ngx_gmtoff = tm.ngx_tm_gmtoff / 60; #else ngx_localtime(&tm); ngx_gmtoff = ngx_timezone(tm.ngx_tm_isdst); #endif p = cached_err_log_time[slot]; ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d", tm.ngx_tm_year, tm.ngx_tm_mon, tm.ngx_tm_mday, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); ngx_cached_err_log_time.data = p; p = cached_http_log_time[slot]; ngx_sprintf(p, "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d", tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1], tm.ngx_tm_year, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec, ngx_gmtoff < 0 ? '-' : '+', abs(ngx_gmtoff / 60), abs(ngx_gmtoff % 60)); ngx_cached_http_log_time.data = p; #if (NGX_THREADS) ngx_mutex_unlock(ngx_time_mutex); #endif } u_char *ngx_http_time(u_char *buf, time_t t) { ngx_tm_t tm; ngx_gmtime(t, &tm); return ngx_sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d GMT", week[tm.ngx_tm_wday], tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1], tm.ngx_tm_year, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); } u_char *ngx_http_cookie_time(u_char *buf, time_t t) { ngx_tm_t tm; ngx_gmtime(t, &tm); /* * Netscape 3.x does not understand 4-digit years at all and * 2-digit years more than "37" */ return ngx_sprintf(buf, (tm.ngx_tm_year > 2037) ? "%s, %02d-%s-%d %02d:%02d:%02d GMT": "%s, %02d-%s-%02d %02d:%02d:%02d GMT", week[tm.ngx_tm_wday], tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1], (tm.ngx_tm_year > 2037) ? tm.ngx_tm_year: tm.ngx_tm_year % 100, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); } void ngx_gmtime(time_t t, ngx_tm_t *tp) { ngx_int_t sec, min, hour, mday, mon, year, wday, yday, days; days = t / 86400; /* Jaunary 1, 1970 was Thursday */ wday = (4 + days) % 7; t %= 86400; hour = t / 3600; t %= 3600; min = t / 60; sec = t % 60; /* the algorithm based on Gauss's formula */ days = days - (31 + 28) + 719527; year = days * 400 / (365 * 400 + 100 - 4 + 1); yday = days - (365 * year + year / 4 - year / 100 + year / 400); mon = (yday + 31) * 12 / 367; mday = yday - (mon * 367 / 12 - 31); mon += 2; if (yday >= 306) { /* * there is no "yday" in Win32 SYSTEMTIME * * yday -= 306; */ year++; mon -= 12; if (mday == 0) { /* Jaunary 31 */ mon = 1; mday = 31; } else if (mon == 2) { if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) { if (mday > 29) { mon = 3; mday -= 29; } } else if (mday > 28) { mon = 3; mday -= 28; } } /* * there is no "yday" in Win32 SYSTEMTIME * * } else { * yday += 31 + 28; * * if ((year % 4 == 0) && (year % 100 || (year % 400 == 0))) { * yday++; * } */ } tp->ngx_tm_sec = (ngx_tm_sec_t) sec; tp->ngx_tm_min = (ngx_tm_min_t) min; tp->ngx_tm_hour = (ngx_tm_hour_t) hour; tp->ngx_tm_mday = (ngx_tm_mday_t) mday; tp->ngx_tm_mon = (ngx_tm_mon_t) mon; tp->ngx_tm_year = (ngx_tm_year_t) year; tp->ngx_tm_wday = (ngx_tm_wday_t) wday; }