diff --git a/src/core/ngx_array.h b/src/core/ngx_array.h index d6443d6a7..9cef9f33a 100644 --- a/src/core/ngx_array.h +++ b/src/core/ngx_array.h @@ -6,13 +6,13 @@ #include -typedef struct { +struct ngx_array_s { void *elts; int nelts; size_t size; int nalloc; ngx_pool_t *pool; -} ngx_array_t; +}; ngx_array_t *ngx_create_array(ngx_pool_t *p, int n, size_t size); diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 97819b6ff..b2c3d554d 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -6,6 +6,7 @@ typedef struct ngx_module_s ngx_module_t; typedef struct ngx_conf_s ngx_conf_t; typedef struct ngx_cycle_s ngx_cycle_t; typedef struct ngx_log_s ngx_log_t; +typedef struct ngx_array_s ngx_array_t; typedef struct ngx_open_file_s ngx_open_file_t; typedef struct ngx_command_s ngx_command_t; diff --git a/src/core/ngx_crc.h b/src/core/ngx_crc.h index df6488967..c6234c37a 100644 --- a/src/core/ngx_crc.h +++ b/src/core/ngx_crc.h @@ -7,7 +7,7 @@ ngx_inline static uint32_t ngx_crc(char *data, size_t len) { uint32_t sum; - + for (sum = 0; len; len--) { /* * gcc 2.95.2 x86 and icc 7.1.006 compile that operator diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c index 4cbd8fc2c..3b29bec07 100644 --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -14,7 +14,7 @@ int ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain) if (tf->file.fd == NGX_INVALID_FILE) { rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool, tf->persistent); - + if (rc == NGX_ERROR || rc == NGX_AGAIN) { return rc; } diff --git a/src/core/ngx_garbage_collector.h b/src/core/ngx_garbage_collector.h index 1164484b1..5bc8471dc 100644 --- a/src/core/ngx_garbage_collector.h +++ b/src/core/ngx_garbage_collector.h @@ -17,7 +17,7 @@ struct ngx_gc_s { }; -int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, +int ngx_garbage_collector_temp_handler(ngx_gc_t *ctx, ngx_str_t *name, ngx_dir_t *dir); diff --git a/src/core/ngx_hunk.c b/src/core/ngx_hunk.c index 2785c39d4..d6aa0a40e 100644 --- a/src/core/ngx_hunk.c +++ b/src/core/ngx_hunk.c @@ -108,7 +108,7 @@ void ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy, if (te->next == NULL) { te->next = *out; break; - } + } } } diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c index 3f578fc7f..b615c7ea2 100644 --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -22,7 +22,7 @@ static ngx_str_t errlog_name = ngx_string("errlog"); static ngx_command_t ngx_errlog_commands[] = { {ngx_string("error_log"), - NGX_MAIN_CONF|NGX_CONF_TAKE12, + NGX_MAIN_CONF|NGX_CONF_1MORE, ngx_set_error_log, 0, 0, @@ -51,6 +51,11 @@ static const char *err_levels[] = { "warn", "notice", "info", "debug" }; +static const char *debug_levels[] = { + "debug", "debug_alloc", "debug_event", "debug_http" +}; + + #if (HAVE_VARIADIC_MACROS) void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...) @@ -262,9 +267,18 @@ ngx_log_t *ngx_log_init_errlog() } -ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_str_t *name) +ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args) { ngx_log_t *log; + ngx_str_t *value, *name; + + if (args) { + value = args->elts; + name = &value[1]; + + } else { + name = NULL; + } ngx_test_null(log, ngx_pcalloc(cycle->pool, sizeof(ngx_log_t)), NULL); ngx_test_null(log->file, ngx_conf_open_file(cycle, name), NULL); @@ -279,7 +293,7 @@ ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_str_t *name) static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_int_t i; + ngx_int_t i, n, d; ngx_str_t *value; value = cf->args->elts; @@ -291,16 +305,43 @@ static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) cf->cycle->log->file->name = value[1]; } - if (cf->args->nelts == 3) { - for (i = 1; i <= /* STUB ??? */ NGX_LOG_DEBUG; i++) { - if (ngx_strcmp(value[2].data, err_levels[i]) == 0) { - cf->cycle->log->log_level = i; - break; + for (i = 2; i < cf->args->nelts; i++) { + + for (n = 1; n < NGX_LOG_DEBUG; n++) { + if (ngx_strcmp(value[i].data, err_levels[n]) == 0) { + + if (cf->cycle->log->log_level != 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid log level \"%s\"", + value[i].data); + return NGX_CONF_ERROR; + } + + cf->cycle->log->log_level = n; + continue; } } - if (i > NGX_LOG_DEBUG) { + + d = NGX_LOG_DEBUG_FIRST; + for (n = 0; n < /* STUB */ 3; n++) { + if (ngx_strcmp(value[i].data, debug_levels[n]) == 0) { + if (cf->cycle->log->log_level & ~NGX_LOG_DEBUG_ALL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid log level \"%s\"", + value[i].data); + return NGX_CONF_ERROR; + } + + cf->cycle->log->log_level |= d; + d <<= 1; + continue; + } + } + + + if (cf->cycle->log->log_level == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid log level \"%s\"", value[2].data); + "invalid log level \"%s\"", value[i].data); return NGX_CONF_ERROR; } } diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h index 59ca1f9c4..71da9d524 100644 --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -16,7 +16,13 @@ #define NGX_LOG_INFO 7 #define NGX_LOG_DEBUG 8 -#define NGX_LOG_DEBUG_HTTP 0x80 +#define NGX_LOG_DEBUG_ALLOC 0x10 +#define NGX_LOG_DEBUG_EVENT 0x20 +#define NGX_LOG_DEBUG_HTTP 0x40 + +#define NGX_LOG_DEBUG_FIRST NGX_LOG_DEBUG +#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_HTTP +#define NGX_LOG_DEBUG_ALL 0xfffffff8 /* @@ -212,7 +218,7 @@ void ngx_assert_core(ngx_log_t *log, const char *fmt, ...); #define ngx_log_copy_log(new, old) ngx_memcpy(new, old, sizeof(ngx_log_t)) ngx_log_t *ngx_log_init_errlog(); -ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_str_t *name); +ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args); extern ngx_module_t ngx_errlog_module; diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c index 377f998de..a5d47d58c 100644 --- a/src/core/ngx_regex.c +++ b/src/core/ngx_regex.c @@ -30,7 +30,7 @@ ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, re = pcre_compile(pattern->data, (int) options, &errstr, &erroff, NULL); if (re == NULL) { - if ((size_t) erroff == pattern->len) { + if ((size_t) erroff == pattern->len) { ngx_snprintf(err->data, err->len - 1, "pcre_compile() failed: %s in \"%s\"", errstr, pattern->data); diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c index a1ffdceb5..bc0cb1684 100644 --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -116,11 +116,11 @@ void ngx_gmtime(time_t t, ngx_tm_t *tp) t %= 86400; hour = t / 3600; t %= 3600; - min = t / 60; + 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); diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index c2170250d..ee7ab0f43 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -36,9 +36,11 @@ struct ngx_event_s { /* * The inline of "ngx_rbtree_t rbtree;". * - * It allows to pack rbtree_color and variuos event bit flags into - * the single int. We also use "unsigned char" and then "usigned short" - * because otherwise MSVC 6.0 uses an additional int for bit flags. + * It allows to pack the rbtree_color and the variuos event bit flags into + * the single "int". We also use "unsigned char" and then "usigned short" + * because otherwise MSVC 6.0 uses an additional "int" for the bit flags. + * We use "char rbtree_color" instead of "unsigned int rbtree_color:1" + * because it preserves the bits order on the big endian platforms. */ ngx_int_t rbtree_key; diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index ea63724e9..9a08e00f5 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -199,7 +199,14 @@ void ngx_event_accept(ngx_event_t *ev) rev->log = log; wev->log = log; - /* TODO: x86: MT: lock xadd, MP: lock xadd, shared */ + /* + * In the multithreaded model the connection counter is updated by + * the main thread only that accept()s connections. + * + * TODO: MP: - allocated in a shared memory + * - atomic increment (x86: lock xadd) + * or protection by critical section or mutex + */ c->number = ngx_connection_counter++; ngx_log_debug(ev->log, "accept: %d, %d" _ s _ c->number); diff --git a/src/event/ngx_event_thread.c b/src/event/ngx_event_thread.c new file mode 100644 index 000000000..527b49cd0 --- /dev/null +++ b/src/event/ngx_event_thread.c @@ -0,0 +1,129 @@ + +volitile int ngx_last_posted_event; + + +typedef struct { + ngx_tid_t tid; + ngx_cv_t cv; +} ngx_thread_data_t; + +static ngx_thread_data_t *threead_data; + + + + + +{ + + err = ngx_thread_cond_wait(ngx_thread_data_cv, ngx_thread_data_mutex); + + tid = ngx_thread_self(); + + for (i = 0; i < thread_data_n; i++) { + if (thread_data[i].tid == tid) { + cv = thread_data[i].cv; + break; + } + } + + if (i == thread_data_n) { + error + return + } + + + for ( ;; ) { + + err = ngx_thread_cond_wait(cv, ngx_posted_events_mutex); + if (err) { + ngx_log_error(NGX_ALERT, log, err, + ngx_thread_cond_wait_n " failed, thread is exiting"); + return; + } + + for ( ;; ) { + ev = NULL; + + for (i = ngx_last_posted_event; i > 0; i--) { + ev = ngx_posted_events[i]; + + if (ev == NULL) { + continue; + } + + err = ngx_thread_mutex_trylock(ev->mutex); + + if (err == 0) { + ngx_posted_events[i] = NULL; + + while (ngx_posted_events[ngx_last_posted_event] == NULL) { + ngx_last_posted_event--; + } + + break; + } + + if (err == NGX_EBUSY) { + ev = NULL; + continue; + } + + ngx_log_error(NGX_ALERT, log, err, + ngx_thread_mutex_unlock_n " failed, + thread is exiting"); + + ngx_worker_thread_error(); + return; + } + + err = ngx_thread_mutex_unlock(ngx_posted_events_mutex); + if (err) { + ngx_log_error(NGX_ALERT, log, err, + ngx_thread_mutex_unlock_n + " failed, thread exiting"); + return; + } + + if (ev == NULL) { + break; + } + + ngx_event_handle_event(ev); + + err = ngx_thread_mutex_unlock(ev->mutex); + if (err) { + ngx_log_error(NGX_ALERT, log, err, + ngx_thread_mutex_unlock_n + " failed, thread exiting"); + + ngx_worker_thread_error(); + return; + } + + err = ngx_thread_mutex_lock(ngx_posted_events_mutex); + if (err) { + ngx_log_error(NGX_ALERT, log, err, + ngx_thread_mutex_lock_n + " failed, thread exiting"); + return; + } + } + + if (restart) { + ngx_log_error(NGX_INFO, log, 0, "thread is exiting"); + return; + } + } +} + +ngx_worker_thread_error() +{ + ngx_err_t err; + + err = ngx_thread_mutex_unlock(ngx_posted_events_mutex); + if (err) { + ngx_log_error(NGX_ALERT, log, err, + ngx_thread_mutex_unlock_n + " failed, thread exiting"); + } +} diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index e8b78f498..84396a948 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -384,7 +384,7 @@ void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev) ngx_connection_t *c; ngx_http_request_t *r; ngx_http_proxy_ctx_t *p; - + ngx_log_debug(rev->log, "busy lock"); c = rev->data; @@ -594,7 +594,7 @@ static char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, char *buf, *buf++ = '-'; } else { - buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expired); + buf += ngx_snprintf(buf, NGX_TIME_T_LEN, TIME_T_FMT, p->state->expired); } *buf++ = '/'; @@ -603,7 +603,7 @@ static char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, char *buf, *buf++ = '-'; } else { - buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->bl_time); + buf += ngx_snprintf(buf, NGX_TIME_T_LEN, TIME_T_FMT, p->state->bl_time); } *buf++ = '/'; @@ -635,7 +635,7 @@ static char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, char *buf, *buf++ = '-'; } else { - buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expires); + buf += ngx_snprintf(buf, NGX_TIME_T_LEN, TIME_T_FMT, p->state->expires); } *buf++ = ' '; diff --git a/src/http/modules/proxy/ngx_http_proxy_header.c b/src/http/modules/proxy/ngx_http_proxy_header.c index 76d33211c..0c44a5248 100644 --- a/src/http/modules/proxy/ngx_http_proxy_header.c +++ b/src/http/modules/proxy/ngx_http_proxy_header.c @@ -23,7 +23,7 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p, if (&h[i] == headers_in->connection) { continue; } - + if (p->accel) { if (&h[i] == headers_in->date || &h[i] == headers_in->accept_ranges) { @@ -34,12 +34,12 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p, && !p->lcf->pass_x_accel_expires) { continue; - } - + } + if (&h[i] == headers_in->server && !p->lcf->pass_server) { continue; - } - + } + if (&h[i] == headers_in->location) { if (ngx_http_proxy_rewrite_location_header(p, &h[i]) == NGX_ERROR) @@ -48,9 +48,9 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p, } continue; - } + } } - + if (&h[i] == headers_in->content_type) { r->headers_out.content_type = &h[i]; r->headers_out.content_type->key.len = 0; @@ -61,9 +61,9 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p, { return NGX_ERROR; } - + *ho = h[i]; - + /* * ngx_http_header_filter() does not handle specially * the following headers if they are set: @@ -122,7 +122,7 @@ static int ngx_http_proxy_rewrite_location_header(ngx_http_proxy_ctx_t *p, r->headers_out.location->value.len = uc->location->len + (loc->value.len - uc->url.len) + 1; r->headers_out.location->value.data = - ngx_palloc(r->pool, r->headers_out.location->value.len); + ngx_palloc(r->pool, r->headers_out.location->value.len); if (r->headers_out.location->value.data == NULL) { return NGX_ERROR; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 547e028e5..2f5c92345 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1354,12 +1354,14 @@ static char *ngx_set_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *lcf = conf; +#if 0 ngx_str_t *value; value = cf->args->elts; +#endif ngx_test_null(lcf->err_log, - ngx_log_create_errlog(cf->cycle, &value[1]), + ngx_log_create_errlog(cf->cycle, cf->args), NGX_CONF_ERROR); return NGX_CONF_OK; diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c index 6e39f45b8..49f1dba2d 100644 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -158,8 +158,7 @@ static int ngx_http_header_filter(ngx_http_request_t *r) if (r->headers_out.content_length == NULL) { if (r->headers_out.content_length_n >= 0) { - /* 2^64 */ - len += sizeof("Content-Length: 18446744073709551616" CRLF) - 1; + len += sizeof("Content-Length: ") - 1 + NGX_OFF_T_LEN + 2; } } @@ -238,49 +237,18 @@ static int ngx_http_header_filter(ngx_http_request_t *r) if (!(r->headers_out.date && r->headers_out.date->key.len)) { h->last = ngx_cpymem(h->last, "Date: ", sizeof("Date: ") - 1); -#if (NGX_HTTP_LOG_ALL_HEADERS_OUT) - p = h->last; -#endif h->last = ngx_cpymem(h->last, ngx_cached_http_time.data, ngx_cached_http_time.len); -#if (NGX_HTTP_LOG_ALL_HEADERS_OUT) - r->headers_out.date = ngx_palloc(r->pool, sizeof(ngx_table_elt_t)); - if (r->headers_out.date == NULL) { - return NGX_ERROR; - } - - r->headers_out.date->key.len = 0; - r->headers_out.date->key.data = NULL; - r->headers_out.date->value.len = h->last - p; - r->headers_out.date->value.data = p; -#endif - *(h->last++) = CR; *(h->last++) = LF; } if (r->headers_out.content_length == NULL) { if (r->headers_out.content_length_n >= 0) { -#if (NGX_HTTP_LOG_ALL_HEADERS_OUT) - p = h->last + sizeof("Content-Length: ") - 1; -#endif - h->last += ngx_snprintf(h->last, /* 2^64 */ - sizeof("Content-Length: 18446744073709551616" CRLF), - "Content-Length: " OFF_T_FMT CRLF, - r->headers_out.content_length_n); - -#if (NGX_HTTP_LOG_ALL_HEADERS_OUT) - r->headers_out.content_length = ngx_palloc(r->pool, - sizeof(ngx_table_elt_t)); - if (r->headers_out.content_length == NULL) { - return NGX_ERROR; - } - - r->headers_out.content_length->key.len = 0; - r->headers_out.content_length->key.data = NULL; - r->headers_out.content_length->value.len = h->last - p - 2; - r->headers_out.content_length->value.data = p; -#endif + h->last += ngx_snprintf(h->last, + sizeof("Content-Length: ") + NGX_OFF_T_LEN + 2, + "Content-Length: " OFF_T_FMT CRLF, + r->headers_out.content_length_n); } } @@ -332,24 +300,8 @@ static int ngx_http_header_filter(ngx_http_request_t *r) { h->last = ngx_cpymem(h->last, "Last-Modified: ", sizeof("Last-Modified: ") - 1); -#if (NGX_HTTP_LOG_ALL_HEADERS_OUT) - p = h->last; -#endif h->last += ngx_http_time(h->last, r->headers_out.last_modified_time); -#if (NGX_HTTP_LOG_ALL_HEADERS_OUT) - r->headers_out.last_modified = ngx_palloc(r->pool, - sizeof(ngx_table_elt_t)); - if (r->headers_out.last_modified == NULL) { - return NGX_ERROR; - } - - r->headers_out.last_modified->key.len = 0; - r->headers_out.last_modified->key.data = NULL; - r->headers_out.last_modified->value.len = h->last - p; - r->headers_out.last_modified->value.data = p; -#endif - *(h->last++) = CR; *(h->last++) = LF; } diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c index 48ebd01a5..ff943950c 100644 --- a/src/http/ngx_http_log_handler.c +++ b/src/http/ngx_http_log_handler.c @@ -21,10 +21,15 @@ static char *ngx_http_log_length(ngx_http_request_t *r, char *buf, uintptr_t data); static char *ngx_http_log_header_in(ngx_http_request_t *r, char *buf, uintptr_t data); +static char *ngx_http_log_connection_header_out(ngx_http_request_t *r, + char *buf, uintptr_t data); +static char *ngx_http_log_transfer_encoding_header_out(ngx_http_request_t *r, + char *buf, + uintptr_t data); static char *ngx_http_log_unknown_header_in(ngx_http_request_t *r, char *buf, uintptr_t data); static char *ngx_http_log_header_out(ngx_http_request_t *r, char *buf, - uintptr_t data); + uintptr_t data); static char *ngx_http_log_unknown_header_out(ngx_http_request_t *r, char *buf, uintptr_t data); @@ -104,7 +109,7 @@ ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { ngx_http_log_time }, { ngx_string("request"), 0, ngx_http_log_request }, { ngx_string("status"), 3, ngx_http_log_status }, - { ngx_string("length"), NGX_OFF_LEN, ngx_http_log_length }, + { ngx_string("length"), NGX_OFF_T_LEN, ngx_http_log_length }, { ngx_string("i"), NGX_HTTP_LOG_ARG, ngx_http_log_header_in }, { ngx_string("o"), NGX_HTTP_LOG_ARG, ngx_http_log_header_out }, { ngx_null_string, 0, NULL } @@ -212,18 +217,6 @@ static char *ngx_http_log_time(ngx_http_request_t *r, char *buf, uintptr_t data) { return ngx_cpymem(buf, ngx_cached_http_log_time.data, ngx_cached_http_log_time.len); - -#if 0 - ngx_tm_t tm; - - ngx_localtime(&tm); - - return buf + ngx_snprintf(buf, sizeof("28/Sep/1970:12:00:00"), - "%02d/%s/%d:%02d:%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); -#endif } @@ -250,7 +243,7 @@ static char *ngx_http_log_status(ngx_http_request_t *r, char *buf, static char *ngx_http_log_length(ngx_http_request_t *r, char *buf, uintptr_t data) { - return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_T_FMT, + return buf + ngx_snprintf(buf, NGX_OFF_T_LEN + 1, OFF_T_FMT, r->connection->sent); } @@ -357,11 +350,36 @@ static char *ngx_http_log_header_out(ngx_http_request_t *r, char *buf, ngx_http_log_op_t *op; if (r) { + + /* run-time execution */ + + if (r->http_version < NGX_HTTP_VERSION_10) { + if (buf) { + *buf = '-'; + } + + return buf + 1; + } + h = *(ngx_table_elt_t **) ((char *) &r->headers_out + data); if (h == NULL) { - /* no header */ + /* + * No header pointer was found. + * However, some headers: "Date", "Server", "Content-Length", + * and "Last-Modified" have a special handling in the header filter + * but we do not set up their pointers in the filter because + * they are too seldom needed to be logged. + */ + + if (data == offsetof(ngx_http_headers_out_t, date)) { + if (buf == NULL) { + return (char *) ngx_cached_http_time.len; + } + return ngx_cpymem(buf, ngx_cached_http_time.data, + ngx_cached_http_time.len); + } if (data == offsetof(ngx_http_headers_out_t, server)) { if (buf == NULL) { @@ -370,6 +388,36 @@ static char *ngx_http_log_header_out(ngx_http_request_t *r, char *buf, return ngx_cpymem(buf, NGINX_VER, sizeof(NGINX_VER) - 1); } + if (data == offsetof(ngx_http_headers_out_t, content_length)) { + if (r->headers_out.content_length_n == -1) { + if (buf) { + *buf = '-'; + } + return buf + 1; + } + + if (buf == NULL) { + return (char *) NGX_OFF_T_LEN; + } + return buf + ngx_snprintf(buf, NGX_OFF_T_LEN + 2, OFF_T_FMT, + r->headers_out.content_length_n); + } + + if (data == offsetof(ngx_http_headers_out_t, last_modified)) { + if (r->headers_out.last_modified_time == -1) { + if (buf) { + *buf = '-'; + } + return buf + 1; + } + + if (buf == NULL) { + return (char *) sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; + } + return buf + ngx_http_time(buf, + r->headers_out.last_modified_time); + } + if (buf) { *buf = '-'; } @@ -406,6 +454,21 @@ static char *ngx_http_log_header_out(ngx_http_request_t *r, char *buf, } } + if (s->len == sizeof("Connection") - 1 + && ngx_strncasecmp(s->data, "Connection", s->len) == 0) + { + op->op = ngx_http_log_connection_header_out; + op->data = NULL; + return NULL; + } + + if (s->len == sizeof("Transfer-Encoding") - 1 + && ngx_strncasecmp(s->data, "Transfer-Encoding", s->len) == 0) { + op->op = ngx_http_log_transfer_encoding_header_out; + op->data = NULL; + return NULL; + } + op->op = ngx_http_log_unknown_header_out; op->data = (uintptr_t) s; @@ -413,6 +476,41 @@ static char *ngx_http_log_header_out(ngx_http_request_t *r, char *buf, } +static char *ngx_http_log_connection_header_out(ngx_http_request_t *r, + char *buf, uintptr_t data) +{ + if (buf == NULL) { + return (char *) ((r->keepalive) ? sizeof("keep-alive") - 1: + sizeof("close") - 1); + } + + if (r->keepalive) { + return ngx_cpymem(buf, "keep-alive", sizeof("keep-alive") - 1); + + } else { + return ngx_cpymem(buf, "close", sizeof("close") - 1); + } +} + + +static char *ngx_http_log_transfer_encoding_header_out(ngx_http_request_t *r, + char *buf, + uintptr_t data) +{ + if (buf == NULL) { + return (char *) ((r->chunked) ? sizeof("chunked") - 1 : 1); + } + + if (r->chunked) { + return ngx_cpymem(buf, "chunked", sizeof("chunked") - 1); + } + + *buf = '-'; + + return buf + 1; +} + + static char *ngx_http_log_unknown_header_out(ngx_http_request_t *r, char *buf, uintptr_t data) { diff --git a/src/http/ngx_http_log_handler.h b/src/http/ngx_http_log_handler.h index 3d8481c96..eb55f09f7 100644 --- a/src/http/ngx_http_log_handler.h +++ b/src/http/ngx_http_log_handler.h @@ -17,8 +17,8 @@ typedef char *(*ngx_http_log_op_pt) (ngx_http_request_t *r, char *buf, /* STUB */ #define NGX_INT32_LEN sizeof("-2147483648") - 1 -#define NGX_TIME_LEN sizeof("-2147483648") - 1 -#define NGX_OFF_LEN sizeof("-9223372036854775808") - 1 +#define NGX_TIME_T_LEN sizeof("-2147483648") - 1 +#define NGX_OFF_T_LEN sizeof("-9223372036854775808") - 1 typedef struct { diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c index 8199d0b6a..66e11b939 100644 --- a/src/os/unix/ngx_freebsd_rfork_thread.c +++ b/src/os/unix/ngx_freebsd_rfork_thread.c @@ -1,9 +1,6 @@ #include #include -#include -#include -#include extern int __isthreaded;