nginx-0.0.1-2003-11-28-20:41:47 import

This commit is contained in:
Igor Sysoev 2003-11-28 17:41:47 +00:00
parent 877df63f34
commit c2bba092eb
8 changed files with 371 additions and 74 deletions

View File

@ -117,12 +117,12 @@ ngx_log_debug(r->connection->log, "index cache get: %x" _ cache);
redirect.len = cache->data.value.len;
if (!(redirect.data = ngx_palloc(r->pool, redirect.len + 1))) {
ngx_http_cache_unlock(ilcf->cache, cache);
ngx_http_cache_unlock(ilcf->cache, cache, r->connection->log);
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_memcpy(redirect.data, cache->data.value.data, redirect.len + 1);
ngx_http_cache_unlock(ilcf->cache, cache);
ngx_http_cache_unlock(ilcf->cache, cache, r->connection->log);
return ngx_http_internal_redirect(r, &redirect, NULL);
}
@ -230,7 +230,8 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
{
cache->accessed = ngx_cached_time;
cache->updated = ngx_cached_time;
ngx_http_cache_unlock(ilcf->cache, cache);
ngx_http_cache_unlock(ilcf->cache, cache,
r->connection->log);
return ngx_http_internal_redirect(r, &redirect, NULL);
@ -270,7 +271,7 @@ ngx_log_debug(r->connection->log, "index cache alloc: %x" _ cache);
}
if (cache) {
ngx_http_cache_unlock(ilcf->cache, cache);
ngx_http_cache_unlock(ilcf->cache, cache, r->connection->log);
}
return ngx_http_internal_redirect(r, &redirect, NULL);

View File

@ -41,9 +41,10 @@ ngx_module_t ngx_http_static_module = {
ngx_int_t ngx_http_static_translate_handler(ngx_http_request_t *r)
{
ngx_int_t rc, level;
char *location, *last, *path;
uint32_t crc;
char *location, *last;
ngx_int_t rc, level;
ngx_str_t name;
ngx_err_t err;
ngx_http_cache_t *cache;
ngx_http_cache_conf_t *ccf;
@ -55,62 +56,67 @@ ngx_int_t ngx_http_static_translate_handler(ngx_http_request_t *r)
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (r->uri.data[r->uri.len - 1] == '/') {
if (r->path.data == NULL) {
ngx_test_null(r->path.data,
ngx_palloc(r->pool,
clcf->doc_root.len + r->uri.len),
NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_cpystrn(ngx_cpymem(r->path.data, clcf->doc_root.data,
clcf->doc_root.len),
r->uri.data, r->uri.len + 1);
/* there is no index handler */
} else {
r->path.data[r->path.len] = '\0';
if (!(path = ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len))) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_cpystrn(ngx_cpymem(path, clcf->doc_root.data, clcf->doc_root.len),
r->uri.data, r->uri.len + 1);
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"directory index of \"%s\" is forbidden", r->path.data);
"directory index of \"%s\" is forbidden", path);
return NGX_HTTP_FORBIDDEN;
}
/* "+ 2" is for trailing '/' in possible redirect and '\0' */
ngx_test_null(r->file.name.data,
/* "+ 2" is for a trailing '/' in a possible redirect and '\0' */
ngx_test_null(name.data,
ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2),
NGX_HTTP_INTERNAL_SERVER_ERROR);
location = ngx_cpymem(r->file.name.data, clcf->doc_root.data,
clcf->doc_root.len),
location = ngx_cpymem(name.data, clcf->doc_root.data, clcf->doc_root.len);
last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1);
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ data);
ccf = ngx_http_get_module_loc_conf(r, ngx_http_cache_module);
if (ccf->open_files) {
cache = ngx_http_cache_get(ccf->open_files, &r->file.name, &crc);
if (r->cache == NULL) {
ngx_log_debug(r->connection->log, "cache get: %x" _ cache);
/* look up an open files cache */
if (cache
&& ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
|| ccf->open_files->update >= ngx_cached_time - cache->updated))
{
cache->refs++;
r->file.fd = cache->fd;
r->file.name = cache->key;
r->content_handler = ngx_http_static_handler;
ccf = ngx_http_get_module_loc_conf(r, ngx_http_cache_module);
return NGX_OK;
if (ccf->open_files) {
cache = ngx_http_cache_get(ccf->open_files, &name, &crc);
ngx_log_debug(r->connection->log, "cache get: %x" _ cache);
if (cache
&& ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
|| ccf->open_files->update
>= ngx_cached_time - cache->updated))
{
r->cache = cache;
r->content_handler = ngx_http_static_handler;
return NGX_OK;
}
} else {
cache = NULL;
}
} else {
cache = NULL;
cache = r->cache;
}
#if (WIN9X)
if (ngx_win32_version < NGX_WIN_NT) {
@ -121,10 +127,10 @@ ngx_log_debug(r->connection->log, "cache get: %x" _ cache);
* so we need to check its type before the opening
*/
if (ngx_file_info(r->file.name.data, &r->file.info) == NGX_FILE_ERROR) {
if (ngx_file_info(name.data, &r->file.info) == NGX_FILE_ERROR) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
ngx_file_info_n " \"%s\" failed", r->file.name.data);
ngx_file_info_n " \"%s\" failed", name.data);
if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
return NGX_HTTP_NOT_FOUND;
@ -138,7 +144,7 @@ ngx_log_debug(r->connection->log, "cache get: %x" _ cache);
}
if (ngx_is_dir(&r->file.info)) {
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ name.data);
if (!(r->headers_out.location =
ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
@ -159,6 +165,7 @@ ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
#endif
if (r->file.fd == NGX_INVALID_FILE) {
r->file.fd = ngx_open_file(r->file.name.data,
NGX_FILE_RDONLY, NGX_FILE_OPEN);
@ -282,6 +289,7 @@ static int ngx_http_static_handler(ngx_http_request_t *r)
ngx_hunk_t *h;
ngx_chain_t out;
ngx_http_type_t *type;
ngx_http_cleanup_t *cleanup;
ngx_http_log_ctx_t *ctx;
ngx_http_core_loc_conf_t *clcf;
@ -294,6 +302,10 @@ static int ngx_http_static_handler(ngx_http_request_t *r)
ctx = r->connection->log->data;
ctx->action = "sending response to client";
if (!(cleanup = ngx_push_array(&r->cleanup))) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
if (r->file.fd == NGX_INVALID_FILE) {
r->file.fd = ngx_open_file(r->file.name.data,
NGX_FILE_RDONLY, NGX_FILE_OPEN);
@ -316,6 +328,10 @@ static int ngx_http_static_handler(ngx_http_request_t *r)
}
}
cleanup->data.file.fd = r->file.fd;
cleanup->data.file.name = r->file.name.data;
cleanup->cache = 0;
if (!r->file.info_valid) {
if (ngx_fd_info(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
@ -379,7 +395,6 @@ static int ngx_http_static_handler(ngx_http_request_t *r)
ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)),
NGX_HTTP_INTERNAL_SERVER_ERROR);
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {

View File

@ -48,8 +48,11 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log);
/**/
void ngx_http_init_connection(ngx_connection_t *c);
int ngx_http_parse_request_line(ngx_http_request_t *r);
int ngx_http_parse_complex_uri(ngx_http_request_t *r);
int ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h);
int ngx_http_find_server_conf(ngx_http_request_t *r);
void ngx_http_handler(ngx_http_request_t *r);
void ngx_http_finalize_request(ngx_http_request_t *r, int error);

View File

@ -176,6 +176,29 @@ ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache,
}
void ngx_http_cache_unlock(ngx_http_cache_hash_t *hash,
ngx_http_cache_t *cache, ngx_log_t *log)
{
ngx_mutex_lock(&hash->mutex);
cache->refs--;
if (cache->refs == 0 && cache->deleted) {
ngx_log_debug(log, "CLOSE FILE: %d" _ cache->fd);
if (cache->fd != NGX_INVALID_FILE) {
if (ngx_close_file(cache->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_close_file_n " \"%s\" failed",
cache->key.data);
}
}
cache->key.data = NULL;
}
ngx_mutex_unlock(&hash->mutex);
}
int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq)
{
ssize_t n;

View File

@ -74,12 +74,6 @@ typedef struct {
} ngx_http_cache_conf_t;
#define ngx_http_cache_unlock(ch, ce) \
ngx_mutex_lock(&ch->mutex); \
ce->refs--; \
ngx_mutex_unlock(&ch->mutex);
#define NGX_HTTP_CACHE_STALE 1
#define NGX_HTTP_CACHE_AGED 2
@ -96,6 +90,9 @@ ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *cache,
ngx_http_cache_t *ngx_http_cache_alloc(ngx_http_cache_hash_t *cache,
ngx_str_t *key, uint32_t crc,
ngx_log_t *log);
void ngx_http_cache_unlock(ngx_http_cache_hash_t *hash,
ngx_http_cache_t *cache, ngx_log_t *log);
int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
ngx_dir_t *dir);

View File

@ -5,8 +5,7 @@
int ngx_http_parse_request_line(ngx_http_request_t *r)
{
char ch;
char *p;
char ch, *p;
enum {
sw_start = 0,
sw_G,
@ -198,9 +197,7 @@ int ngx_http_parse_request_line(ngx_http_request_t *r)
state = sw_uri;
break;
case '/':
#if (WIN32)
r->complex_uri = 1;
#endif
break;
case '?':
r->args_start = p;
@ -421,11 +418,11 @@ int ngx_http_parse_request_line(ngx_http_request_t *r)
}
}
int ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h)
{
char c, ch;
char *p;
enum {
char c, ch, *p;
enum {
sw_start = 0,
sw_name,
sw_space_before_value,
@ -622,3 +619,197 @@ int ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h)
return NGX_AGAIN;
}
}
int ngx_http_parse_complex_uri(ngx_http_request_t *r)
{
char c, ch, decoded, *p, *u;
enum {
sw_usual = 0,
sw_slash,
sw_dot,
sw_dot_dot,
#if (WIN32)
sw_dot_dot_dot,
#endif
sw_quoted,
sw_quoted_second
} state, quoted_state;
decoded = '\0';
quoted_state = sw_usual;
state = sw_usual;
p = r->uri_start;
u = r->uri.data;
ch = *p++;
while (p < r->uri_start + r->uri.len + 1) {
ngx_log_debug(r->connection->log, "S: %d UN: '%x:%c', URI: '%c'" _
state _ ch _ ch _ *u);
switch (state) {
case sw_usual:
switch(ch) {
case '/':
state = sw_slash;
*u++ = ch;
break;
case '%':
quoted_state = state;
state = sw_quoted;
break;
default:
*u++ = ch;
break;
}
ch = *p++;
break;
case sw_slash:
switch(ch) {
case '/':
break;
case '.':
state = sw_dot;
*u++ = ch;
break;
case '%':
quoted_state = state;
state = sw_quoted;
break;
default:
state = sw_usual;
*u++ = ch;
break;
}
ch = *p++;
break;
case sw_dot:
switch(ch) {
case '/':
state = sw_slash;
u--;
break;
case '.':
state = sw_dot_dot;
*u++ = ch;
break;
case '%':
quoted_state = state;
state = sw_quoted;
break;
default:
state = sw_usual;
*u++ = ch;
break;
}
ch = *p++;
break;
case sw_dot_dot:
switch(ch) {
case '/':
state = sw_slash;
u -= 4;
if (u < r->uri.data) {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
while (*(u - 1) != '/') {
u--;
}
break;
case '%':
quoted_state = state;
state = sw_quoted;
break;
#if (WIN32)
case '.':
state = sw_dot_dot_dot;
*u++ = ch;
break;
#endif
default:
state = sw_usual;
*u++ = ch;
break;
}
ch = *p++;
break;
#if (WIN32)
case sw_dot_dot_dot:
switch(ch) {
case '/':
state = sw_slash;
u -= 5;
if (u < r->uri.data) {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
while (*u != '/') {
u--;
}
if (u < r->uri.data) {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
while (*(u - 1) != '/') {
u--;
}
break;
case '%':
quoted_state = state;
state = sw_quoted;
break;
default:
state = sw_usual;
*u++ = ch;
break;
}
ch = *p++;
break;
#endif
case sw_quoted:
if (ch >= '0' && ch <= '9') {
decoded = ch - '0';
state = sw_quoted_second;
ch = *p++;
break;
}
c = ch | 0x20;
if (c >= 'a' && c <= 'f') {
decoded = c - 'a' + 10;
state = sw_quoted_second;
ch = *p++;
break;
}
return NGX_HTTP_PARSE_INVALID_REQUEST;
case sw_quoted_second:
if (ch >= '0' && ch <= '9') {
ch = (decoded << 4) + ch - '0';
state = quoted_state;
break;
}
c = ch | 0x20;
if (c >= 'a' && c <= 'f') {
ch = (decoded << 4) + c - 'a' + 10;
state = quoted_state;
break;
}
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
}
r->uri.len = u - r->uri.data;
r->uri.data[r->uri.len] = '\0';
return NGX_OK;
}

View File

@ -225,6 +225,21 @@ ngx_log_debug(rev->log, "IN: %08x" _ in_port);
return;
}
r->cleanup.elts = ngx_palloc(r->pool, 5 * sizeof(ngx_http_cleanup_t));
if (r->cleanup.elts == NULL) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_http_close_connection(c);
return;
}
/*
* set by ngx_pcalloc():
*
* r->cleanup.nelts = 0;
*/
r->cleanup.nalloc = 5;
r->cleanup.size = sizeof(ngx_http_cleanup_t);
r->cleanup.pool = r->pool;
/* TODO: ngx_init_table */
if (!(r->headers_out.headers = ngx_create_table(r->pool, 20))) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@ -289,7 +304,7 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
/* the request line has been parsed successfully */
/* TODO: we need to handle such URIs */
if (r->complex_uri || r->unusual_uri) {
if (r->unusual_uri) {
r->request_line.len = r->request_end - r->request_start;
r->request_line.data = r->request_start;
r->request_line.data[r->request_line.len] = '\0';
@ -313,6 +328,20 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
}
/* copy unparsed URI */
r->unparsed_uri.len = r->uri_end - r->uri_start;
r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
if (r->unparsed_uri.data == NULL) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_http_close_connection(c);
return;
}
ngx_cpystrn(r->unparsed_uri.data, r->uri_start,
r->unparsed_uri.len + 1);
/* copy URI */
if (r->args_start) {
@ -327,22 +356,13 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
return;
}
ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
if (r->complex_uri) {
rc = ngx_http_parse_complex_uri(r);
/* copy unparsed URI */
r->unparsed_uri.len = r->uri_end - r->uri_start;
r->unparsed_uri.data = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
if (r->unparsed_uri.data == NULL) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_http_close_connection(c);
return;
} else {
ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
}
ngx_cpystrn(r->unparsed_uri.data, r->uri_start,
r->unparsed_uri.len + 1);
r->request_line.len = r->request_end - r->request_start;
@ -369,6 +389,16 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
}
if (rc != NGX_OK) {
/*
* we check ngx_http_parse_complex_uri() result here to log
* the request line
*/
ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST);
return;
}
if (r->uri_ext) {
/* copy URI extention */
@ -1356,7 +1386,9 @@ int ngx_http_send_last(ngx_http_request_t *r)
void ngx_http_close_request(ngx_http_request_t *r, int error)
{
ngx_int_t i;
ngx_http_log_ctx_t *ctx;
ngx_http_cleanup_t *cleanup;
ngx_log_debug(r->connection->log, "close http request");
@ -1372,6 +1404,22 @@ void ngx_http_close_request(ngx_http_request_t *r, int error)
ngx_http_log_handler(r);
cleanup = r->cleanup.elts;
for (i = 0; i < r->cleanup.nelts; i++) {
if (cleanup[i].cache) {
ngx_http_cache_unlock(cleanup[i].data.cache.hash,
cleanup[i].data.cache.cache,
r->connection->log);
continue;
}
if (ngx_close_file(cleanup[i].data.file.fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
ngx_close_file_n " \"%s\" failed",
cleanup[i].data.file.name);
}
}
if (r->file.fd != NGX_INVALID_FILE) {
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,

View File

@ -144,17 +144,34 @@ typedef struct {
} ngx_http_headers_out_t;
typedef struct {
union {
struct {
ngx_fd_t fd;
char *name;
} file;
struct {
ngx_http_cache_hash_t *hash;
ngx_http_cache_t *cache;
} cache;
} data;
unsigned cache:1;
} ngx_http_cleanup_t;
typedef int (*ngx_http_handler_pt)(ngx_http_request_t *r);
struct ngx_http_request_s {
ngx_connection_t *connection;
ngx_connection_t *connection;
void **ctx;
void **main_conf;
void **srv_conf;
void **loc_conf;
void **ctx;
void **main_conf;
void **srv_conf;
void **loc_conf;
ngx_http_cache_t *cache;
ngx_http_cache_t *cache;
ngx_file_t file;
@ -199,6 +216,8 @@ struct ngx_http_request_s {
void (*request_body_handler) (void *data);
void *data;
ngx_array_t cleanup;
char *discarded_buffer;
void **err_ctx;
int err_status;