nginx-0.0.1-2002-12-10-21:05:12 import

This commit is contained in:
Igor Sysoev 2002-12-10 18:05:12 +00:00
parent ef259d140f
commit b0869056bb
24 changed files with 722 additions and 382 deletions

View File

@ -18,6 +18,7 @@
/* */ /* */
static void ngx_set_signals(ngx_log_t *log);
static void ngx_open_listening_sockets(ngx_log_t *log); static void ngx_open_listening_sockets(ngx_log_t *log);
@ -42,6 +43,8 @@ int main(int argc, char *const *argv)
ngx_pool = ngx_create_pool(16 * 1024, &ngx_log); ngx_pool = ngx_create_pool(16 * 1024, &ngx_log);
/* */ /* */
ngx_set_signals(&ngx_log);
ngx_init_sockets(&ngx_log); ngx_init_sockets(&ngx_log);
/* TODO: read config */ /* TODO: read config */
@ -70,6 +73,20 @@ int main(int argc, char *const *argv)
return 0; return 0;
} }
static void ngx_set_signals(ngx_log_t *log)
{
struct sigaction sa;
ngx_memzero(&sa, sizeof(struct sigaction));
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGPIPE, &sa, NULL) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"sigaction(SIGPIPE, SIG_IGN) failed");
exit(1);
}
}
static void ngx_open_listening_sockets(ngx_log_t *log) static void ngx_open_listening_sockets(ngx_log_t *log)
{ {
int times, failed, reuseaddr, i; int times, failed, reuseaddr, i;

View File

@ -5,6 +5,7 @@
#include <ngx_log.h> #include <ngx_log.h>
#include <ngx_hunk.h> #include <ngx_hunk.h>
#include <ngx_alloc.h> #include <ngx_alloc.h>
#include <ngx_string.h>
#include <ngx_server.h> #include <ngx_server.h>
typedef struct ngx_connection_s ngx_connection_t; typedef struct ngx_connection_s ngx_connection_t;
@ -38,8 +39,7 @@ struct ngx_connection_s {
struct sockaddr *sockaddr; struct sockaddr *sockaddr;
socklen_t socklen; socklen_t socklen;
size_t addr; size_t addr;
char *addr_text; ngx_str_t addr_text;
size_t addr_textlen;
ngx_hunk_t *buffer; ngx_hunk_t *buffer;
unsigned int post_accept_timeout; unsigned int post_accept_timeout;

View File

@ -14,8 +14,7 @@ typedef struct {
struct sockaddr *sockaddr; struct sockaddr *sockaddr;
socklen_t socklen; socklen_t socklen;
size_t addr; size_t addr;
char *addr_text; ngx_str_t addr_text;
size_t addr_textlen;
int family; int family;
int type; int type;

View File

@ -74,7 +74,6 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
ngx_connections[fd].sockaddr = ngx_palloc(pool, s[i].socklen); ngx_connections[fd].sockaddr = ngx_palloc(pool, s[i].socklen);
ngx_connections[fd].addr = s[i].addr; ngx_connections[fd].addr = s[i].addr;
ngx_connections[fd].addr_text = s[i].addr_text; ngx_connections[fd].addr_text = s[i].addr_text;
ngx_connections[fd].addr_textlen = s[i].addr_textlen;
ngx_connections[fd].post_accept_timeout = s[i].post_accept_timeout; ngx_connections[fd].post_accept_timeout = s[i].post_accept_timeout;
ngx_connections[fd].server = s[i].server; ngx_connections[fd].server = s[i].server;

View File

@ -54,7 +54,7 @@ int ngx_event_accept(ngx_event_t *ev)
ngx_connections[s].family = cn->family; ngx_connections[s].family = cn->family;
ngx_connections[s].socklen = cn->socklen; ngx_connections[s].socklen = cn->socklen;
ngx_connections[s].addr = cn->addr; ngx_connections[s].addr = cn->addr;
ngx_connections[s].addr_textlen = cn->addr_textlen; ngx_connections[s].addr_text.len = cn->addr_text.len;
ngx_connections[s].post_accept_timeout = cn->post_accept_timeout; ngx_connections[s].post_accept_timeout = cn->post_accept_timeout;
ngx_read_events[s].data = ngx_write_events[s].data ngx_read_events[s].data = ngx_write_events[s].data

View File

@ -65,8 +65,9 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
ngx_chain_t *chain; ngx_chain_t *chain;
ngx_table_elt_t *header; ngx_table_elt_t *header;
/* "+ 4" is for "\r\n" after request line and at the header end */ /* 2 is for "\r\n" after request line
len = r->request_line.len + 4; and 2 is for "\r\n" at the header end */
len = r->request_line.len + 2 + 2;
/* "Connection: close\r\n" */ /* "Connection: close\r\n" */
len += sizeof(conn_close) - 1; len += sizeof(conn_close) - 1;
@ -79,8 +80,8 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
if (&header[i] == r->headers_in.connection) if (&header[i] == r->headers_in.connection)
continue; continue;
/* "+ 4" is for ": " and "\r\n" */ /* 2 is for ": " and 2 is for "\r\n" */
len += header[i].key.len + header[i].value.len + 4; len += header[i].key.len + 2 + header[i].value.len + 2;
} }
/* STUB */ len++; /* STUB */ len++;
@ -320,6 +321,7 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
ngx_http_proxy_process_status_line(r, p) ngx_http_proxy_process_status_line(r, p)
ngx_http_proxy_process_reponse_header(r, p) */ ngx_http_proxy_process_reponse_header(r, p) */
#if 0
do { do {
rc = (p->state_handler)(r, p); rc = (p->state_handler)(r, p);
@ -329,6 +331,7 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
/* rc == NGX_OK || rc == NGX_AGAIN */ /* rc == NGX_OK || rc == NGX_AGAIN */
} while (p->header_in->pos.mem < p->header_in->last.mem); } while (p->header_in->pos.mem < p->header_in->last.mem);
#endif
ev->event_handler = ngx_http_proxy_read_response_body; ev->event_handler = ngx_http_proxy_read_response_body;
if (p->header_in->end - p->header_in->last.mem == 0) if (p->header_in->end - p->header_in->last.mem == 0)
@ -342,11 +345,11 @@ static int ngx_http_proxy_process_status_line(ngx_http_request_t *r,
{ {
int rc; int rc;
ngx_log_debug(r->connection->log, "STATUS: %d" _ p->status);
rc = ngx_read_http_proxy_status_line(p); rc = ngx_read_http_proxy_status_line(p);
ngx_log_debug(r->connection->log, "STATUS: %d" _ p->status); if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) {
p->status = 200;
}
if (rc == NGX_OK) { if (rc == NGX_OK) {
/* STUB */ /* STUB */
@ -365,6 +368,11 @@ static int ngx_http_proxy_process_status_line(ngx_http_request_t *r,
/* STUB */ return NGX_ERROR; /* STUB */ return NGX_ERROR;
} }
static int ngx_http_proxy_process_response_header(ngx_http_request_t *r,
ngx_http_proxy_ctx_t *p)
{
}
static int ngx_http_proxy_read_response_body(ngx_event_t *ev) static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
{ {
int n; int n;
@ -560,8 +568,10 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
ctx->status = ctx->status * 10 + ch - '0'; ctx->status = ctx->status * 10 + ch - '0';
if (++ctx->status_count == 3) if (++ctx->status_count == 3) {
state = sw_space_after_status; state = sw_space_after_status;
ctx->status_line = p - 3;
}
break; break;
@ -569,7 +579,6 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
case sw_space_after_status: case sw_space_after_status:
switch (ch) { switch (ch) {
case ' ': case ' ':
ctx->status_text = p - 1;
state = sw_status_text; state = sw_status_text;
break; break;
case CR: case CR:

View File

@ -30,7 +30,7 @@ struct ngx_http_proxy_ctx_s {
int state; int state;
int status; int status;
int status_count; int status_count;
char *status_text; char *status_line;
char *request_end; char *request_end;
int (*state_handler)(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p); int (*state_handler)(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p);
}; };

View File

@ -11,17 +11,24 @@
static void *ngx_http_index_create_conf(ngx_pool_t *pool); static void *ngx_http_index_create_conf(ngx_pool_t *pool);
static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf, char *value); static void *ngx_http_index_merge_conf(ngx_pool_t *p,
void *parent, void *child);
static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf,
ngx_str_t *value);
static ngx_command_t ngx_http_index_commands[]; static ngx_command_t ngx_http_index_commands[];
ngx_http_module_t ngx_http_index_module = { ngx_http_module_t ngx_http_index_module = {
NGX_HTTP_MODULE, NGX_HTTP_MODULE,
NULL, /* create server config */ NULL, /* create server config */
ngx_http_index_create_conf, /* create location config */ ngx_http_index_create_conf, /* create location config */
ngx_http_index_commands, /* module directives */ ngx_http_index_commands, /* module directives */
NULL, /* init module */ NULL, /* init module */
NULL, /* translate handler */
NULL, /* init output body filter */ NULL, /* init output body filter */
}; };
@ -36,32 +43,32 @@ static ngx_command_t ngx_http_index_commands[] = {
}; };
int ngx_http_index_handler(ngx_http_request_t *r) int ngx_http_index_handler(ngx_http_request_t *r)
{ {
int index_len, i; int i;
char *name, *loc, *file; char *name, *file;
ngx_str_t loc, *index;
ngx_err_t err; ngx_err_t err;
ngx_fd_t fd; ngx_fd_t fd;
ngx_http_index_file_t *index;
ngx_http_index_conf_t *cf; ngx_http_index_conf_t *cf;
cf = (ngx_http_index_conf_t *) cf = (ngx_http_index_conf_t *)
ngx_get_module_loc_conf(r, ngx_http_index_module); ngx_get_module_loc_conf(r, ngx_http_index_module);
index_len = (*(r->uri_end - 1) == '/') ? cf->max_index_len : 0;
ngx_test_null(name, ngx_test_null(name,
ngx_palloc(r->pool, r->uri_end - r->uri_start + index_len ngx_palloc(r->pool,
+ r->server->doc_root_len), r->server->doc_root_len + r->uri.len
+ cf->max_index_len),
NGX_HTTP_INTERNAL_SERVER_ERROR); NGX_HTTP_INTERNAL_SERVER_ERROR);
loc = ngx_cpystrn(name, r->server->doc_root, r->server->doc_root_len); loc.data = ngx_cpystrn(name, r->server->doc_root, r->server->doc_root_len);
file = ngx_cpystrn(loc, r->uri_start, r->uri_end - r->uri_start + 1); file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1);
index = (ngx_http_index_file_t *) cf->indices->elts; index = (ngx_str_t *) cf->indices->elts;
for (i = 0; i < cf->indices->nelts; i++) { for (i = 0; i < cf->indices->nelts; i++) {
ngx_memcpy(file, index[i].name, index[i].len); ngx_memcpy(file, index[i].data, index[i].len + 1);
fd = ngx_open_file(name, NGX_FILE_RDONLY); fd = ngx_open_file(name, NGX_FILE_RDONLY);
if (fd == -1) { if (fd == -1) {
@ -75,15 +82,18 @@ int ngx_http_index_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_HTTP_INTERNAL_SERVER_ERROR;
} }
r->filename = name; r->filename.len = r->server->doc_root_len + r->uri.len + index[i].len;
r->filename.data = name;
r->fd = fd; r->fd = fd;
loc.len = r->uri.len + index[i].len;
return ngx_http_internal_redirect(r, loc); return ngx_http_internal_redirect(r, loc);
} }
return NGX_DECLINED; return NGX_DECLINED;
} }
static void *ngx_http_index_create_conf(ngx_pool_t *pool) static void *ngx_http_index_create_conf(ngx_pool_t *pool)
{ {
ngx_http_index_conf_t *conf; ngx_http_index_conf_t *conf;
@ -91,38 +101,42 @@ static void *ngx_http_index_create_conf(ngx_pool_t *pool)
ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), NULL); ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), NULL);
ngx_test_null(conf->indices, ngx_test_null(conf->indices,
ngx_create_array(pool, sizeof(ngx_http_index_file_t), 3), ngx_create_array(pool, sizeof(ngx_str_t), 3),
NULL); NULL);
return conf; return conf;
} }
static void *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) static void *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
{ {
ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent;
ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child;
ngx_http_index_file_t *index; ngx_str_t *index;
if (conf->max_index_len == 0) { if (conf->max_index_len == 0) {
if (prev->max_index_len != 0) if (prev->max_index_len != 0)
return prev; return prev;
ngx_test_null(index, ngx_push_array(conf->indices), NULL); ngx_test_null(index, ngx_push_array(conf->indices), NULL);
index->name = NGX_HTTP_INDEX; index->len = sizeof(NGX_HTTP_INDEX) - 1;
conf->max_index_len = index->len = sizeof(NGX_HTTP_INDEX) + 1; index->data = NGX_HTTP_INDEX;
conf->max_index_len = sizeof(NGX_HTTP_INDEX);
} }
return conf; return conf;
} }
static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf, char *value)
static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf,
ngx_str_t *value)
{ {
ngx_http_index_conf_t *cf = (ngx_http_index_conf_t *) conf; ngx_http_index_conf_t *cf = (ngx_http_index_conf_t *) conf;
ngx_http_index_file_t *index; ngx_str_t *index;
ngx_test_null(index, ngx_push_array(cf->indices), NULL); ngx_test_null(index, ngx_push_array(cf->indices), NULL);
index->name = value; index->len = value->len;
index->len = strlen(value) + 1; index->data = value->data;
if (cf->max_index_len < index->len) if (cf->max_index_len < index->len)
cf->max_index_len = index->len; cf->max_index_len = index->len;

View File

@ -14,11 +14,6 @@ typedef struct {
size_t max_index_len; size_t max_index_len;
} ngx_http_index_conf_t; } ngx_http_index_conf_t;
typedef struct {
char *name;
size_t len;
} ngx_http_index_file_t;
extern ngx_http_module_t ngx_http_index_module; extern ngx_http_module_t ngx_http_index_module;

View File

@ -40,11 +40,13 @@ int ngx_http_static_handler(ngx_http_request_t *r)
ctx = r->connection->log->data; ctx = r->connection->log->data;
ctx->action = "sending response"; ctx->action = "sending response";
r->fd = ngx_open_file(r->filename, NGX_FILE_RDONLY); if (r->fd != -1)
r->fd = ngx_open_file(r->filename.data, NGX_FILE_RDONLY);
if (r->fd == -1) { if (r->fd == -1) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_static_handler: " "ngx_http_static_handler: "
ngx_open_file_n " %s failed", r->filename); ngx_open_file_n " %s failed", r->filename.data);
return NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_HTTP_INTERNAL_SERVER_ERROR;
} }
@ -52,7 +54,7 @@ int ngx_http_static_handler(ngx_http_request_t *r)
if (ngx_stat_fd(r->fd, &r->fileinfo) == -1) { if (ngx_stat_fd(r->fd, &r->fileinfo) == -1) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_static_handler: " "ngx_http_static_handler: "
ngx_stat_fd_n " %s failed", r->filename); ngx_stat_fd_n " %s failed", r->filename.data);
/* close fd */ /* close fd */
return NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_HTTP_INTERNAL_SERVER_ERROR;
@ -64,25 +66,35 @@ int ngx_http_static_handler(ngx_http_request_t *r)
r->headers_out.last_modified = ngx_file_mtime(r->fileinfo); r->headers_out.last_modified = ngx_file_mtime(r->fileinfo);
*/ */
ngx_test_null(r->headers_out.content_type,
ngx_push_table(r->headers_out.headers),
NGX_HTTP_INTERNAL_SERVER_ERROR);
r->headers_out.content_type->key.len = 12;
r->headers_out.content_type->key.data = "Content-Type";
/* STUB */ /* STUB */
if (r->exten) { if (r->exten.len) {
if (strcasecmp(r->exten, "html") == 0) if (strcasecmp(r->exten.data, "html") == 0) {
r->headers_out.content_type = "text/html; charset=koi8-r"; r->headers_out.content_type->value.len = 25;
else if (strcasecmp(r->exten, "gif") == 0) r->headers_out.content_type->value.data =
r->headers_out.content_type = "image/gif"; "text/html; charset=koi8-r";
else if (strcasecmp(r->exten, "jpg") == 0) } else if (strcasecmp(r->exten.data, "gif") == 0) {
r->headers_out.content_type = "image/jpeg"; r->headers_out.content_type->value.len = 9;
else if (strcasecmp(r->exten, "pdf") == 0) r->headers_out.content_type->value.data = "image/gif";
r->headers_out.content_type = "application/pdf"; } else if (strcasecmp(r->exten.data, "jpg") == 0) {
r->headers_out.content_type->value.len = 10;
r->headers_out.content_type->value.data = "image/jpeg";
}
} else { } else {
r->headers_out.content_type = "text/html; charset=koi8-r"; r->headers_out.content_type->value.len = 25;
r->headers_out.content_type->value.data = "text/html; charset=koi8-r";
} }
/* STUB */ /* STUB */
rc = ngx_http_header_filter(r); rc = ngx_http_header_filter(r);
/* /*
rc = ngx_send_http_header(r->headers_out); rc = ngx_send_http_header(r);
*/ */
if (r->header_only) if (r->header_only)
return rc; return rc;

View File

@ -66,8 +66,8 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log)
ls->sockaddr = (struct sockaddr *) &addr; ls->sockaddr = (struct sockaddr *) &addr;
ls->socklen = sizeof(struct sockaddr_in); ls->socklen = sizeof(struct sockaddr_in);
ls->addr = offsetof(struct sockaddr_in, sin_addr); ls->addr = offsetof(struct sockaddr_in, sin_addr);
ls->addr_text = addr_text; ls->addr_text.len = INET_ADDRSTRLEN;
ls->addr_textlen = INET_ADDRSTRLEN; ls->addr_text.data = addr_text;
ls->backlog = -1; ls->backlog = -1;
ls->post_accept_timeout = 10000; ls->post_accept_timeout = 10000;
ls->nonblocking = 1; ls->nonblocking = 1;

View File

@ -12,6 +12,8 @@
#include <ngx_config_command.h> #include <ngx_config_command.h>
#define NGX_HTTP_VERSION_10 1000
#define NGX_HTTP_GET 1 #define NGX_HTTP_GET 1
#define NGX_HTTP_HEAD 2 #define NGX_HTTP_HEAD 2
#define NGX_HTTP_POST 3 #define NGX_HTTP_POST 3
@ -74,22 +76,28 @@ typedef struct {
typedef struct { typedef struct {
int status; int status;
int connection; ngx_str_t status_line;
ngx_table_elt_t *server;
ngx_table_elt_t *date;
ngx_table_elt_t *content_type;
ngx_table_elt_t *location;
ngx_table_elt_t *last_modified;
ngx_table_t *headers;
off_t content_length; off_t content_length;
char *location;
char *content_type;
char *charset; char *charset;
char *etag; char *etag;
char *server; time_t date_time;
time_t date; time_t last_modified_time;
time_t last_modified;
} ngx_http_headers_out_t; } ngx_http_headers_out_t;
typedef struct ngx_http_request_s ngx_http_request_t; typedef struct ngx_http_request_s ngx_http_request_t;
struct ngx_http_request_s { struct ngx_http_request_s {
char *filename; ngx_str_t filename;
char *location;
ngx_fd_t fd; ngx_fd_t fd;
void **ctx; void **ctx;
@ -116,8 +124,8 @@ struct ngx_http_request_s {
int http_minor; int http_minor;
ngx_str_t request_line; ngx_str_t request_line;
char *uri; ngx_str_t uri;
char *exten; ngx_str_t exten;
ngx_http_request_t *main; ngx_http_request_t *main;
ngx_connection_t *connection; ngx_connection_t *connection;
@ -132,7 +140,6 @@ struct ngx_http_request_s {
unsigned lingering_close:1; unsigned lingering_close:1;
unsigned header_read:1; unsigned header_read:1;
unsigned process_header:1;
unsigned header_timeout:1; unsigned header_timeout:1;
unsigned logging:1; unsigned logging:1;
@ -165,10 +172,15 @@ typedef struct {
typedef struct { typedef struct {
int index; int index;
void *(*create_srv_conf)(ngx_pool_t *p); void *(*create_srv_conf)(ngx_pool_t *p);
void *(*create_loc_conf)(ngx_pool_t *p); void *(*create_loc_conf)(ngx_pool_t *p);
ngx_command_t *commands; ngx_command_t *commands;
int (*init_module)(ngx_pool_t *p); int (*init_module)(ngx_pool_t *p);
int (*translate_handler)(ngx_http_request_t *r);
int (*init_output_body_filter)(int (**next_filter) int (*init_output_body_filter)(int (**next_filter)
(ngx_http_request_t *r, ngx_chain_t *ch)); (ngx_http_request_t *r, ngx_chain_t *ch));
} ngx_http_module_t; } ngx_http_module_t;

View File

@ -100,13 +100,16 @@ ngx_http_write_filter_set_stub(ngx_pool_t *pool, ngx_http_module_t **modules)
ngx_http_index_set_stub(ngx_pool_t *pool, ngx_http_module_t **modules) ngx_http_index_set_stub(ngx_pool_t *pool, ngx_http_module_t **modules)
{ {
int i; int i;
ngx_str_t index;
ngx_command_t *cmd; ngx_command_t *cmd;
for (i = 0; modules[i]; i++) { for (i = 0; modules[i]; i++) {
if (modules[i] == &ngx_http_index_module) { if (modules[i] == &ngx_http_index_module) {
for (cmd = modules[i]->commands; cmd->name; cmd++) { for (cmd = modules[i]->commands; cmd->name; cmd++) {
if (strcmp(cmd->name, "index") == 0) { if (strcmp(cmd->name, "index") == 0) {
cmd->set(pool, ngx_loc_conf[i], "index.html"); index.len = sizeof("index.html") - 1;
index.data = "index.html";
cmd->set(pool, ngx_loc_conf[i], &index);
} }
} }
} }

View File

@ -1,13 +1,21 @@
#include <ngx_config.h> #include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_config_command.h> #include <ngx_config_command.h>
#include <ngx_http.h> #include <ngx_http.h>
#include <ngx_http_core.h> #include <ngx_http_core.h>
#include <ngx_http_config.h> #include <ngx_http_config.h>
/* STUB */
#include <ngx_http_output_filter.h>
int ngx_http_static_handler(ngx_http_request_t *r);
int ngx_http_index_handler(ngx_http_request_t *r);
int ngx_http_proxy_handler(ngx_http_request_t *r);
/**/
static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool); static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool);
static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool); static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool);
static int ngx_http_core_translate_handler(ngx_http_request_t *r);
static ngx_command_t ngx_http_core_commands[]; static ngx_command_t ngx_http_core_commands[];
@ -15,10 +23,14 @@ static ngx_command_t ngx_http_core_commands[];
ngx_http_module_t ngx_http_core_module = { ngx_http_module_t ngx_http_core_module = {
NGX_HTTP_MODULE, NGX_HTTP_MODULE,
ngx_http_core_create_srv_conf, /* create server config */ ngx_http_core_create_srv_conf, /* create server config */
ngx_http_core_create_loc_conf, /* create location config */ ngx_http_core_create_loc_conf, /* create location config */
ngx_http_core_commands, /* module directives */ ngx_http_core_commands, /* module directives */
NULL, /* init module */
/* STUB */ NULL, /* init module */
ngx_http_core_translate_handler, /* translate handler */
NULL /* init output body filter */ NULL /* init output body filter */
}; };
@ -35,6 +47,168 @@ static ngx_command_t ngx_http_core_commands[] = {
}; };
int ngx_http_handler(ngx_http_request_t *r)
{
int rc, i;
r->connection->unexpected_eof = 0;
r->lingering_close = 1;
r->keepalive = 1;
#if 1
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
#endif
/* run translation phase */
for (i = 0; ngx_http_modules[i]; i++) {
if (ngx_http_modules[i]->translate_handler) {
rc = ngx_http_modules[i]->translate_handler(r);
if (rc == NGX_OK)
break;
if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
return ngx_http_special_response(r, rc);
}
}
rc = r->handler(r);
if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
return ngx_http_special_response(r, rc);
return rc;
}
static int ngx_http_core_translate_handler(ngx_http_request_t *r)
{
char *loc, *last;
ngx_err_t err;
ngx_table_elt_t *h;
/* TODO: find location conf */
if (r->uri.data[r->uri.len - 1] == '/') {
/* TODO: find index handler */
/* STUB */ r->handler = ngx_http_index_handler;
return NGX_OK;
}
r->filename.len = r->server->doc_root_len + r->uri.len + 2;
ngx_test_null(r->filename.data,
ngx_palloc(r->pool, r->filename.len + 1),
NGX_HTTP_INTERNAL_SERVER_ERROR);
loc = ngx_cpystrn(r->filename.data, r->server->doc_root,
r->server->doc_root_len);
last = ngx_cpystrn(loc, r->uri.data, r->uri.len + 1);
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename.data);
if (ngx_file_type(r->filename.data, &r->fileinfo) == -1) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
ngx_file_type_n " %s failed", r->filename.data);
if (err == NGX_ENOENT)
return NGX_HTTP_NOT_FOUND;
else
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
if (ngx_is_dir(r->fileinfo)) {
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->filename.data);
/* BROKEN: need to include server name */
ngx_test_null(h, ngx_push_table(r->headers_out.headers),
NGX_HTTP_INTERNAL_SERVER_ERROR);
*last++ = '/';
*last = '\0';
h->key.len = 8;
h->key.data = "Location" ;
h->value.len = last - loc;
h->value.data = loc;
r->headers_out.location = h;
return NGX_HTTP_MOVED_PERMANENTLY;
}
/* TODO: r->handler = loc_conf->default_handler; */
/* STUB */ r->handler = ngx_http_static_handler;
return NGX_OK;
}
int ngx_http_redirect(ngx_http_request_t *r, int redirect)
{
/* STUB */
/* log request */
return ngx_http_close_request(r);
}
int ngx_http_error(ngx_http_request_t *r, int error)
{
/* STUB */
ngx_log_debug(r->connection->log, "http error: %d" _ error);
/* log request */
return ngx_http_close_request(r);
}
int ngx_http_close_request(ngx_http_request_t *r)
{
ngx_assert((r->fd != -1), /* void */; , r->connection->log,
"file already closed");
if (r->fd != -1) {
if (ngx_close_file(r->fd) == -1)
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
ngx_close_file_n " failed");
}
/*
if (r->logging)
ngx_http_log_request(r);
*/
ngx_destroy_pool(r->pool);
ngx_log_debug(r->connection->log, "http close");
ngx_del_timer(r->connection->read);
ngx_del_timer(r->connection->write);
return NGX_DONE;
}
int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri)
{
ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri.data);
r->uri.len = uri.len;
r->uri.data = uri.data;
/* NEEDED ? */
r->uri_start = uri.data;
r->uri_end = uri.data + uri.len;
/**/
return ngx_http_handler(r);
}
static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool) static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool)
{ {
ngx_http_core_srv_conf_t *conf; ngx_http_core_srv_conf_t *conf;

View File

@ -22,22 +22,24 @@
int ngx_http_static_handler(ngx_http_request_t *r); int ngx_http_static_handler(ngx_http_request_t *r);
int ngx_http_index_handler(ngx_http_request_t *r); int ngx_http_index_handler(ngx_http_request_t *r);
int ngx_http_proxy_handler(ngx_http_request_t *r); int ngx_http_proxy_handler(ngx_http_request_t *r);
/* */ /**/
int ngx_http_init_connection(ngx_connection_t *c); int ngx_http_init_connection(ngx_connection_t *c);
static int ngx_http_init_request(ngx_event_t *ev); static int ngx_http_init_request(ngx_event_t *ev);
static int ngx_http_process_request(ngx_event_t *ev); static int ngx_http_process_request_header(ngx_event_t *ev);
static int ngx_http_process_request_line(ngx_http_request_t *r); static int ngx_http_process_request_line(ngx_http_request_t *r);
static int ngx_http_process_request_header(ngx_http_request_t *r); static int ngx_http_process_request_headers(ngx_http_request_t *r);
static int ngx_http_process_request_header_line(ngx_http_request_t *r); static int ngx_http_process_request_header_line(ngx_http_request_t *r);
static int ngx_http_event_handler(ngx_http_request_t *r);
static int ngx_http_block_read(ngx_event_t *ev); static int ngx_http_block_read(ngx_event_t *ev);
static int ngx_http_read_discarded_body(ngx_event_t *ev); static int ngx_http_read_discarded_body(ngx_event_t *ev);
static int ngx_http_event_handler(ngx_http_request_t *r); int ngx_http_handler(ngx_http_request_t *r);
static int ngx_http_handler(ngx_http_request_t *r);
static int ngx_http_set_default_handler(ngx_http_request_t *r); static int ngx_http_set_default_handler(ngx_http_request_t *r);
static int ngx_http_writer(ngx_event_t *ev); static int ngx_http_writer(ngx_event_t *ev);
@ -45,11 +47,13 @@ static int ngx_http_set_lingering_close(ngx_http_request_t *r);
static int ngx_http_keepalive_handler(ngx_event_t *ev); static int ngx_http_keepalive_handler(ngx_event_t *ev);
static int ngx_http_lingering_close(ngx_event_t *ev); static int ngx_http_lingering_close(ngx_event_t *ev);
static int ngx_http_special_response(ngx_http_request_t *r, int error); #if 0
static int ngx_http_redirect(ngx_http_request_t *r, int redirect); int ngx_http_special_response(ngx_http_request_t *r, int error);
static int ngx_http_error(ngx_http_request_t *r, int error); int ngx_http_redirect(ngx_http_request_t *r, int redirect);
int ngx_http_error(ngx_http_request_t *r, int error);
int ngx_http_close_request(ngx_http_request_t *r);
#endif
static int ngx_http_close_request(ngx_http_request_t *r);
static int ngx_http_close_connection(ngx_event_t *ev); static int ngx_http_close_connection(ngx_event_t *ev);
static size_t ngx_http_log_error(void *data, char *buf, size_t len); static size_t ngx_http_log_error(void *data, char *buf, size_t len);
@ -99,19 +103,22 @@ int ngx_http_init_connection(ngx_connection_t *c)
ngx_memcpy(addr, c->sockaddr, c->socklen); ngx_memcpy(addr, c->sockaddr, c->socklen);
c->sockaddr = addr; c->sockaddr = addr;
ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen), ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text.len),
NGX_ERROR); NGX_ERROR);
/* STUB: should be ngx_inet_ntop() */
#if (WIN32) #if (WIN32)
c->addr_text = inet_ntoa((struct in_addr *) c->addr_text.data = inet_ntoa((struct in_addr *)
((char *)c->sockaddr + c->addr)); ((char *)c->sockaddr + c->addr));
#else #else
inet_ntop(c->family, (char *)c->sockaddr + c->addr, inet_ntop(c->family, (char *)c->sockaddr + c->addr,
c->addr_text, c->addr_textlen); c->addr_text.data, c->addr_text.len);
#endif #endif
/**/
ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)), ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)),
NGX_ERROR); NGX_ERROR);
ctx->client = c->addr_text; ctx->client = c->addr_text.data;
ctx->action = "reading client request line"; ctx->action = "reading client request line";
c->log->data = ctx; c->log->data = ctx;
c->log->handler = ngx_http_log_error; c->log->handler = ngx_http_log_error;
@ -121,6 +128,7 @@ int ngx_http_init_connection(ngx_connection_t *c)
return ngx_http_init_request(ev); return ngx_http_init_request(ev);
} else { } else {
#endif #endif
/* STUB: post_accept_timeout should be in http_conf */
ngx_add_timer(ev, c->post_accept_timeout); ngx_add_timer(ev, c->post_accept_timeout);
#if (USE_KQUEUE) #if (USE_KQUEUE)
return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
@ -159,8 +167,10 @@ static int ngx_http_init_request(ngx_event_t *ev)
r->connection = c; r->connection = c;
r->server = srv; r->server = srv;
/* STUB */
r->srv_conf = ngx_srv_conf; r->srv_conf = ngx_srv_conf;
r->loc_conf = ngx_loc_conf; r->loc_conf = ngx_loc_conf;
/**/
if (c->buffer == NULL) { if (c->buffer == NULL) {
ngx_test_null(c->buffer, ngx_test_null(c->buffer,
@ -179,16 +189,15 @@ static int ngx_http_init_request(ngx_event_t *ev)
ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module), ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module),
ngx_http_close_request(r)); ngx_http_close_request(r));
ev->event_handler = ngx_http_process_request; ev->event_handler = ngx_http_process_request_header;
r->state_handler = ngx_http_process_request_line; r->state_handler = ngx_http_process_request_line;
r->process_header = 1;
r->header_timeout = 1; r->header_timeout = 1;
return ngx_http_process_request(ev); return ngx_http_process_request_header(ev);
} }
static int ngx_http_process_request(ngx_event_t *ev) static int ngx_http_process_request_header(ngx_event_t *ev)
{ {
int n, rc; int n, rc;
ngx_connection_t *c ; ngx_connection_t *c ;
@ -213,6 +222,8 @@ static int ngx_http_process_request(ngx_event_t *ev)
if (r->header_timeout) { if (r->header_timeout) {
r->header_timeout = 0; r->header_timeout = 0;
ngx_del_timer(ev); ngx_del_timer(ev);
/* STUB: r->server->header_timeout
OR r->srv_conf->header_timeout ? */
ngx_add_timer(ev, r->server->header_timeout); ngx_add_timer(ev, r->server->header_timeout);
} }
return NGX_AGAIN; return NGX_AGAIN;
@ -224,9 +235,8 @@ static int ngx_http_process_request(ngx_event_t *ev)
ngx_log_debug(ev->log, "http read %d" _ n); ngx_log_debug(ev->log, "http read %d" _ n);
if (n == 0) { if (n == 0) {
if (c->unexpected_eof)
ngx_log_error(NGX_LOG_INFO, c->log, 0, ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client prematurely closed connection"); "client has prematurely closed connection");
return ngx_http_close_request(r); return ngx_http_close_request(r);
} }
@ -235,7 +245,7 @@ static int ngx_http_process_request(ngx_event_t *ev)
/* state_handlers are called in following order: /* state_handlers are called in following order:
ngx_http_process_request_line(r) ngx_http_process_request_line(r)
ngx_http_process_request_header(r) */ ngx_http_process_request_headers(r) */
do { do {
rc = (r->state_handler)(r); rc = (r->state_handler)(r);
@ -243,10 +253,7 @@ static int ngx_http_process_request(ngx_event_t *ev)
if (rc == NGX_ERROR) if (rc == NGX_ERROR)
return rc; return rc;
/* rc == NGX_OK || rc == NGX_AGAIN */ } while (rc == NGX_AGAIN && r->header_in->pos.mem < r->header_in->last.mem);
} while (r->process_header
&& r->header_in->pos.mem < r->header_in->last.mem);
if (r->header_timeout) { if (r->header_timeout) {
r->header_timeout = 0; r->header_timeout = 0;
@ -254,6 +261,9 @@ static int ngx_http_process_request(ngx_event_t *ev)
ngx_add_timer(ev, r->server->header_timeout); ngx_add_timer(ev, r->server->header_timeout);
} }
if (rc == NGX_OK)
return ngx_http_event_handler(r);
else
return rc; return rc;
} }
@ -270,10 +280,10 @@ static int ngx_http_process_request_line(ngx_http_request_t *r)
c = r->connection; c = r->connection;
if (rc == NGX_OK) { if (rc == NGX_OK) {
len = r->uri_end - r->uri_start + 1; r->uri.len = r->uri_end - r->uri_start;
ngx_test_null(r->uri, ngx_palloc(r->pool, len), ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1),
ngx_http_close_request(r)); ngx_http_close_request(r));
ngx_cpystrn(r->uri, r->uri_start, len); ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
r->request_line.len = r->request_end - r->header_in->start; r->request_line.len = r->request_end - r->header_in->start;
ngx_test_null(r->request_line.data, ngx_test_null(r->request_line.data,
@ -299,27 +309,31 @@ static int ngx_http_process_request_line(ngx_http_request_t *r)
/* */ /* */
if (r->uri_ext) { if (r->uri_ext) {
ngx_test_null(r->exten, r->exten.len = r->uri_end - r->uri_ext;
ngx_palloc(r->pool, r->uri_end - r->uri_ext + 1), ngx_test_null(r->exten.data,
ngx_palloc(r->pool, r->exten.len + 1),
ngx_http_close_request(r)); ngx_http_close_request(r));
ngx_cpystrn(r->exten, r->uri_ext, r->uri_end - r->uri_ext + 1); ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
} }
ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s %s" _ ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s %s" _
r->method _ r->http_version _ r->uri _ r->exten); r->method _ r->http_version _
r->uri.data _ r->exten.data);
if (r->http_version == 9) if (r->http_version == 9)
return ngx_http_event_handler(r); return NGX_OK;
/* TODO: check too long URI - no space for header, compact buffer */ /* TODO: check too long URI - no space for header, compact buffer */
r->headers_in.headers = ngx_create_table(r->pool, 10); r->headers_in.headers = ngx_create_table(r->pool, 10);
/* THINK: when to create out.headers ? */
r->headers_out.headers = ngx_create_table(r->pool, 10);
r->state_handler = ngx_http_process_request_header; r->state_handler = ngx_http_process_request_headers;
ctx = r->connection->log->data; ctx = r->connection->log->data;
ctx->action = "reading client request headers"; ctx->action = "reading client request headers";
return NGX_OK; return NGX_AGAIN;
} }
if (r->header_in->last.mem >= r->header_in->end) { if (r->header_in->last.mem >= r->header_in->end) {
@ -342,13 +356,13 @@ static int ngx_http_process_request_line(ngx_http_request_t *r)
} }
static int ngx_http_process_request_header(ngx_http_request_t *r) static int ngx_http_process_request_headers(ngx_http_request_t *r)
{ {
int rc; int rc;
ngx_http_log_ctx_t *ctx; ngx_http_log_ctx_t *ctx;
for ( ;; ) { for ( ;; ) {
rc = ngx_read_http_header_line(r); rc = ngx_read_http_header_line(r, r->header_in);
/* TODO: check too long header, compact buffer */ /* TODO: check too long header, compact buffer */
@ -358,7 +372,7 @@ static int ngx_http_process_request_header(ngx_http_request_t *r)
} else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
ngx_log_debug(r->connection->log, "HTTP header done"); ngx_log_debug(r->connection->log, "HTTP header done");
return ngx_http_event_handler(r); return NGX_OK;
} else if (rc == NGX_AGAIN) { } else if (rc == NGX_AGAIN) {
return NGX_AGAIN; return NGX_AGAIN;
@ -408,90 +422,16 @@ static int ngx_http_process_request_header_line(ngx_http_request_t *r)
} }
/* ******************** */
void ngx_http_discard_body(ngx_http_request_t *r)
{
ngx_log_debug(r->connection->log, "set discard body");
ngx_del_timer(r->connection->read);
if (r->client_content_length)
r->connection->read->event_handler = ngx_http_read_discarded_body;
}
static int ngx_http_read_discarded_body(ngx_event_t *ev)
{
size_t size;
ssize_t n;
ngx_connection_t *c;
ngx_http_request_t *r;
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
ngx_log_debug(ev->log, "http read discarded body");
if (ev->timedout)
return NGX_ERROR;
if (r->discarded_buffer == NULL)
ngx_test_null(r->discarded_buffer,
ngx_palloc(r->pool, r->server->discarded_buffer_size),
NGX_ERROR);
size = r->client_content_length;
if (size > r->server->discarded_buffer_size)
size = r->server->discarded_buffer_size;
n = ngx_event_recv(c, r->discarded_buffer, size);
if (n == NGX_ERROR)
return NGX_ERROR;
if (n == NGX_AGAIN)
return NGX_OK;
r->client_content_length -= n;
/* XXX: what if r->client_content_length == 0 ? */
return NGX_OK;
}
static int ngx_http_discarded_read(ngx_event_t *ev)
{
ssize_t n;
ngx_connection_t *c;
ngx_http_request_t *r;
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
ngx_log_debug(ev->log, "http discarded read");
if (ev->timedout)
return NGX_ERROR;
if (r->discarded_buffer == NULL)
ngx_test_null(r->discarded_buffer,
ngx_palloc(r->pool, r->server->discarded_buffer_size),
NGX_ERROR);
n = ngx_event_recv(c, r->discarded_buffer,
r->server->discarded_buffer_size);
return n;
}
/* ******************** */
static int ngx_http_event_handler(ngx_http_request_t *r) static int ngx_http_event_handler(ngx_http_request_t *r)
{ {
int rc; int rc;
ngx_msec_t timeout; ngx_msec_t timeout;
ngx_log_debug(r->connection->log, "UA: '%s: %s'" _ ngx_del_timer(r->connection->read);
r->headers_in.user_agent->key.data _ r->header_timeout = 0;
r->headers_in.user_agent->value.data);
r->state_handler = NULL;
r->connection->read->event_handler = ngx_http_block_read;
rc = ngx_http_handler(r); rc = ngx_http_handler(r);
@ -553,22 +493,105 @@ static int ngx_http_event_handler(ngx_http_request_t *r)
r->connection->read->event_handler = ngx_http_keepalive_handler; r->connection->read->event_handler = ngx_http_keepalive_handler;
} }
static int ngx_http_handler(ngx_http_request_t *r)
static int ngx_http_block_read(ngx_event_t *ev)
{
ngx_log_debug(ev->log, "http read blocked");
ev->blocked = 1;
return ngx_del_event(ev, NGX_READ_EVENT);
}
/* FIND PLACE ******************** */
void ngx_http_discard_body(ngx_http_request_t *r)
{
ngx_log_debug(r->connection->log, "set discard body");
ngx_del_timer(r->connection->read);
if (r->client_content_length)
r->connection->read->event_handler = ngx_http_read_discarded_body;
}
static int ngx_http_read_discarded_body(ngx_event_t *ev)
{
size_t size;
ssize_t n;
ngx_connection_t *c;
ngx_http_request_t *r;
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
ngx_log_debug(ev->log, "http read discarded body");
if (ev->timedout)
return NGX_ERROR;
if (r->discarded_buffer == NULL)
ngx_test_null(r->discarded_buffer,
ngx_palloc(r->pool, r->server->discarded_buffer_size),
NGX_ERROR);
size = r->client_content_length;
if (size > r->server->discarded_buffer_size)
size = r->server->discarded_buffer_size;
n = ngx_event_recv(c, r->discarded_buffer, size);
if (n == NGX_ERROR)
return NGX_ERROR;
if (n == NGX_AGAIN)
return NGX_OK;
r->client_content_length -= n;
/* XXX: what if r->client_content_length == 0 ? */
return NGX_OK;
}
static int ngx_http_discarded_read(ngx_event_t *ev)
{
ssize_t n;
ngx_connection_t *c;
ngx_http_request_t *r;
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
ngx_log_debug(ev->log, "http discarded read");
if (ev->timedout)
return NGX_ERROR;
if (r->discarded_buffer == NULL)
ngx_test_null(r->discarded_buffer,
ngx_palloc(r->pool, r->server->discarded_buffer_size),
NGX_ERROR);
n = ngx_event_recv(c, r->discarded_buffer,
r->server->discarded_buffer_size);
return n;
}
/* ******************** */
#if 0
int ngx_http_handler(ngx_http_request_t *r)
{ {
int rc; int rc;
ngx_del_timer(r->connection->read);
r->header_timeout = 0;
r->process_header = 0;
r->state_handler = NULL;
r->connection->unexpected_eof = 0; r->connection->unexpected_eof = 0;
r->lingering_close = 1; r->lingering_close = 1;
r->connection->read->event_handler = ngx_http_block_read;
/* STUB: should find handler */ /* STUB: should find handler */
#if 0 #if 1
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
#endif #endif
rc = ngx_http_set_default_handler(r); rc = ngx_http_set_default_handler(r);
@ -580,23 +603,16 @@ static int ngx_http_handler(ngx_http_request_t *r)
return rc; return rc;
} }
#endif
int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri)
{
ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri);
r->uri = uri;
r->uri_start = uri;
r->uri_end = uri + strlen(uri);
return ngx_http_handler(r);
}
#if 0
static int ngx_http_set_default_handler(ngx_http_request_t *r) static int ngx_http_set_default_handler(ngx_http_request_t *r)
{ {
int err, rc; ngx_err_t err;
char *name, *loc, *file; char *name, *loc, *file;
#if 1 #if 0
/* STUB */ /* STUB */
r->handler = ngx_http_proxy_handler; r->handler = ngx_http_proxy_handler;
return NGX_OK; return NGX_OK;
@ -650,15 +666,7 @@ static int ngx_http_set_default_handler(ngx_http_request_t *r)
return NGX_OK; return NGX_OK;
} }
#endif
static int ngx_http_block_read(ngx_event_t *ev)
{
ngx_log_debug(ev->log, "http read blocked");
ev->blocked = 1;
return ngx_del_event(ev, NGX_READ_EVENT);
}
static int ngx_http_writer(ngx_event_t *ev) static int ngx_http_writer(ngx_event_t *ev)
@ -726,6 +734,7 @@ static int ngx_http_writer(ngx_event_t *ev)
c->read->event_handler = ngx_http_keepalive_handler; c->read->event_handler = ngx_http_keepalive_handler;
} }
static int ngx_http_set_lingering_close(ngx_http_request_t *r) static int ngx_http_set_lingering_close(ngx_http_request_t *r)
{ {
r->lingering_time = ngx_time() + r->server->lingering_time; r->lingering_time = ngx_time() + r->server->lingering_time;
@ -842,111 +851,6 @@ static int ngx_http_lingering_close(ngx_event_t *ev)
} }
static int ngx_http_special_response(ngx_http_request_t *r, int error)
{
return ngx_http_error(r, error);
}
static int ngx_http_redirect(ngx_http_request_t *r, int redirect)
{
/* STUB */
/* log request */
return ngx_http_close_request(r);
}
static int ngx_http_error(ngx_http_request_t *r, int error)
{
/* STUB */
ngx_log_debug(r->connection->log, "http error: %d" _ error);
/* log request */
return ngx_http_close_request(r);
}
#if 0
static int ngx_process_http_request(ngx_http_request_t *r)
{
int fd;
struct stat sb;
ngx_http_header_out_t *header_out;
ngx_chunk_t *header, *ch;
int index = (*(r->uri_end - 1) == '/') ? sizeof(NGX_INDEX) : 1;
char *name = ngx_palloc(r->pool,
r->uri_end - r->uri_start + strlen(ngx_root) + index);
strcpy(name, ngx_root);
strcat(name, r->uri_start);
if (*(r->uri_end - 1) == '/')
strcat(name, NGX_INDEX);
ngx_log_debug(r->connection->log, "HTTP URI: '%s'", name);
if ((fd = open(name, O_RDONLY)) == -1) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, errno,
"open %s failed", name);
return -1;
}
if (fstat(fd, &sb) == -1) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, errno,
"fstat %s failed", name);
return -1;
}
header_out = ngx_palloc(r->pool, sizeof(ngx_http_header_out_t));
header_out->status = NGX_HTTP_OK;
header_out->content_length = sb.st_size;
header_out->last_modified = sb.st_mtime;
header_out->content_type = "text/html";
header_out->charset = "koi8-r";
header_out->date = time(NULL);
header_out->connection = NGX_HTTP_CONN_CLOSE;
/*
header_out->connection = NGX_HTTP_CONN_KEEP_ALIVE;
r->connection->read->event_handler = ngx_http_init_request;
*/
header = ngx_http_header(r, header_out);
ch = ngx_palloc(r->pool, sizeof(ngx_chunk_t));
ch->ident = fd;
ch->offset = 0;
ch->size = sb.st_size;
ch->next = NULL;
header->next = ch;
ngx_event_write(r->connection, header);
return 0;
}
#endif
static int ngx_http_close_request(ngx_http_request_t *r)
{
/*
if (r->logging)
ngx_http_log_request(r);
*/
ngx_destroy_pool(r->pool);
ngx_log_debug(r->connection->log, "http close");
ngx_del_timer(r->connection->read);
ngx_del_timer(r->connection->write);
return NGX_DONE;
}
static int ngx_http_close_connection(ngx_event_t *ev) static int ngx_http_close_connection(ngx_event_t *ev)
{ {
int i, len; int i, len;

View File

@ -9,5 +9,5 @@ ngx_http_get_time(char *buf, time_t t)
struct tm *tp; struct tm *tp;
tp = gmtime(&t); tp = gmtime(&t);
return strftime(buf, 31, "%a, %d %b %Y %H:%M:%S GMT", tp); return strftime(buf, 30, "%a, %d %b %Y %H:%M:%S GMT", tp);
} }

View File

@ -4,83 +4,187 @@
#include <ngx_config.h> #include <ngx_config.h>
#include <ngx_core.h> #include <ngx_core.h>
#include <ngx_string.h> #include <ngx_string.h>
#include <ngx_table.h>
#include <ngx_hunk.h> #include <ngx_hunk.h>
#include <ngx_http.h> #include <ngx_http.h>
typedef struct { #if 0
int len;
char *line; ngx_http_module_t ngx_http_header_filter_module = {
} line; NGX_HTTP_MODULE,
NULL, /* create server config */
NULL, /* create location config */
NULL, /* module directives */
NULL, /* init module */
NULL, /* translate handler */
ngx_http_header_filter_init /* init output header filter */
NULL /* init output body filter */
};
#endif
static line http_codes[] = { static char server_string[] = "Server: " NGINX_VER CRLF;
{ 6, "200 OK" }
static ngx_str_t http_codes[] = {
{ 6, "200 OK" },
{ 21, "301 Moved Permanently" },
{ 15, "400 Bad Request" },
{ 0, NULL },
{ 0, NULL },
{ 13, "403 Forbidden" },
{ 13, "404 Not Found" }
}; };
int ngx_http_header_filter(ngx_http_request_t *r) int ngx_http_header_filter(ngx_http_request_t *r)
{ {
int status; int len, status, i;
ngx_hunk_t *h; ngx_hunk_t *h;
ngx_chain_t *ch; ngx_chain_t *ch;
ngx_table_elt_t *header;
ngx_test_null(h, ngx_create_temp_hunk(r->pool, 1024, 0, 64), if (r->http_version < NGX_HTTP_VERSION_10)
NGX_ERROR); return NGX_OK;
/* 9 is for "HTTP/1.1 ", 2 is for trailing "\r\n"
and 2 is for end of header */
len = 9 + 2 + 2;
/* status line */
if (r->headers_out.status_line.len) {
len += r->headers_out.status_line.len;
} else {
if (r->headers_out.status < NGX_HTTP_MOVED_PERMANENTLY)
status = r->headers_out.status - NGX_HTTP_OK; status = r->headers_out.status - NGX_HTTP_OK;
ngx_memcpy(h->last.mem, "HTTP/1.1 ", 9); else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST)
h->last.mem += 9; status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1;
ngx_memcpy(h->last.mem, http_codes[status].line, http_codes[status].len);
h->last.mem += http_codes[status].len;
*(h->last.mem++) = CR; *(h->last.mem++) = LF;
#if 1 else
r->keepalive = 1; status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 1;
ngx_memcpy(h->last.mem, "Connection: keep-alive" CRLF, 24);
h->last.mem += 24; len += http_codes[status].len;
}
if (r->headers_out.server && r->headers_out.server->key.len) {
len += r->headers_out.server->key.len
+ r->headers_out.server->value.len + 2;
} else {
len += sizeof(server_string) - 1;
}
if (r->headers_out.date && r->headers_out.date->key.len) {
len += r->headers_out.date->key.len
+ r->headers_out.date->value.len + 2;
} else {
/* "Date: ... \r\n"; */
len += 37;
}
/* 2^64 is 20 characters */
if (r->headers_out.content_length >= 0)
len += 48;
#if 0
if (r->headers_out.content_type.len)
len += r->headers_out.content_type.len + 16;
#endif #endif
if (r->keepalive)
len += 24;
else
len += 19;
header = (ngx_table_elt_t *) r->headers_out.headers->elts;
for (i = 0; i < r->headers_out.headers->nelts; i++) {
if (header[i].key.len == 0)
continue;
len += header[i].key.len + 2 + header[i].value.len + 2;
}
ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR);
/* "HTTP/1.1 " */
ngx_memcpy(h->last.mem, "HTTP/1.1 ", 9);
h->last.mem += 9;
/* status line */
if (r->headers_out.status_line.len) {
ngx_memcpy(h->last.mem, r->headers_out.status_line.data,
r->headers_out.status_line.len);
h->last.mem += r->headers_out.status_line.len;
} else {
ngx_memcpy(h->last.mem, http_codes[status].data,
http_codes[status].len);
h->last.mem += http_codes[status].len;
}
*(h->last.mem++) = CR; *(h->last.mem++) = LF;
if (!(r->headers_out.server && r->headers_out.server->key.len)) {
ngx_memcpy(h->last.mem, server_string, sizeof(server_string) - 1);
h->last.mem += sizeof(server_string) - 1;
}
if (!(r->headers_out.date && r->headers_out.date->key.len)) {
ngx_memcpy(h->last.mem, "Date: ", 6); ngx_memcpy(h->last.mem, "Date: ", 6);
h->last.mem += 6; h->last.mem += 6;
h->last.mem += ngx_http_get_time(h->last.mem, time(NULL)); h->last.mem += ngx_http_get_time(h->last.mem, time(NULL));
*(h->last.mem++) = CR; *(h->last.mem++) = LF; *(h->last.mem++) = CR; *(h->last.mem++) = LF;
}
/* 2^64 is 20 characters */ /* 2^64 is 20 characters */
if (r->headers_out.content_length) if (r->headers_out.content_length >= 0)
h->last.mem += ngx_snprintf(h->last.mem, 49, "Content-Length: %d" CRLF, h->last.mem += ngx_snprintf(h->last.mem, 49, "Content-Length: %u" CRLF,
r->headers_out.content_length); r->headers_out.content_length);
/* check */ #if 0
if (r->headers_out.content_type.len) {
ngx_memcpy(h->last.mem, "Content-Type: ", 14);
h->last.mem += 14;
ngx_memcpy(h->last.mem, r->headers_out.content_type.data,
r->headers_out.content_type.len);
h->last.mem += r->headers_out.content_type.len;
*(h->last.mem++) = CR; *(h->last.mem++) = LF;
}
#endif
if (r->headers_out.content_type) if (r->keepalive) {
h->last.mem += ngx_snprintf(h->last.mem, 100, "Content-Type: %s" CRLF, ngx_memcpy(h->last.mem, "Connection: keep-alive" CRLF, 24);
r->headers_out.content_type); h->last.mem += 24;
ngx_memcpy(h->last.mem, "Server: ", 8);
h->last.mem += 8;
if (r->headers_out.server) {
h->last.mem = ngx_cpystrn(h->last.mem, r->headers_out.server,
h->end - h->last.mem);
/* check space */
} else { } else {
ngx_memcpy(h->last.mem, NGINX_VER, sizeof(NGINX_VER) - 1); ngx_memcpy(h->last.mem, "Connection: close" CRLF, 19);
h->last.mem += sizeof(NGINX_VER) - 1; h->last.mem += 19;
} }
for (i = 0; i < r->headers_out.headers->nelts; i++) {
if (header[i].key.len == 0)
continue;
ngx_memcpy(h->last.mem, header[i].key.data, header[i].key.len);
h->last.mem += header[i].key.len;
*(h->last.mem++) = ':' ; *(h->last.mem++) = ' ' ;
ngx_memcpy(h->last.mem, header[i].value.data, header[i].value.len);
h->last.mem += header[i].value.len;
*(h->last.mem++) = CR; *(h->last.mem++) = LF; *(h->last.mem++) = CR; *(h->last.mem++) = LF;
}
/* end of HTTP header */ /* end of HTTP header */
*(h->last.mem++) = CR; *(h->last.mem++) = LF; *(h->last.mem++) = CR; *(h->last.mem++) = LF;
ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), NGX_ERROR);
/* STUB */
-1);
/*
NGX_HTTP_FILTER_ERROR);
*/
ch->hunk = h; ch->hunk = h;
ch->next = NULL; ch->next = NULL;

View File

@ -9,7 +9,9 @@ extern ngx_http_module_t ngx_http_index_module;
ngx_http_module_t *ngx_http_modules[] = { ngx_http_module_t *ngx_http_modules[] = {
&ngx_http_write_filter_module, &ngx_http_write_filter_module,
&ngx_http_output_filter_module, &ngx_http_output_filter_module,
&ngx_http_core_module,
&ngx_http_index_module, &ngx_http_index_module,
&ngx_http_core_module,
NULL NULL
}; };

View File

@ -20,10 +20,14 @@ static ngx_command_t ngx_http_output_filter_commands[];
ngx_http_module_t ngx_http_output_filter_module = { ngx_http_module_t ngx_http_output_filter_module = {
NGX_HTTP_MODULE, NGX_HTTP_MODULE,
NULL, /* create server config */ NULL, /* create server config */
ngx_http_output_filter_create_conf, /* create location config */ ngx_http_output_filter_create_conf, /* create location config */
ngx_http_output_filter_commands, /* module directives */ ngx_http_output_filter_commands, /* module directives */
NULL, /* init module */ NULL, /* init module */
NULL, /* translate handler */
ngx_http_output_filter_init /* init output body filter */ ngx_http_output_filter_init /* init output body filter */
}; };

View File

@ -312,7 +312,7 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
} }
} }
int ngx_read_http_header_line(ngx_http_request_t *r) int ngx_read_http_header_line(ngx_http_request_t *r, ngx_hunk_t *h)
{ {
char c, ch; char c, ch;
char *p; char *p;
@ -329,14 +329,14 @@ int ngx_read_http_header_line(ngx_http_request_t *r)
} state; } state;
state = r->state; state = r->state;
p = r->header_in->pos.mem; p = h->pos.mem;
while (p < r->header_in->last.mem && state < sw_done) { while (p < h->last.mem && state < sw_done) {
ch = *p++; ch = *p++;
/* /*
printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s", printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
state, p, r->header_in->last.mem, ch, p); state, p, h->last.mem, ch, p);
*/ */
switch (state) { switch (state) {
@ -470,7 +470,7 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
} }
} }
r->header_in->pos.mem = p; h->pos.mem = p;
if (state == sw_done) { if (state == sw_done) {
r->state = sw_start; r->state = sw_start;

View File

@ -0,0 +1,64 @@
time_t ngx_http_parse_time()
{
enum {
sw_start = 0,
} state;
state = sw_start;
while () {
switch (state) {
case sw_start:
if (ch == ' ') {
ansi = 1;
state = sw_month;
} else if (ch == ',')
state = sw_day_first_digit;
break;
case sw_day_first_digit:
if (ch == ' ')
break;
if (ch >= '0' && ch <= '9') {
day = ch - '0';
state = sw_day;
break;
}
return NGX_ERROR;
case sw_day:
if (ansi && ch == ' ') {
state = sw_hour_first_digit;
break;
}
if (ch >= '0' && ch <= '9') {
day = ch - '0';
state = ansi ? sw_space_before_hour : sw_before_month;
break;
}
return NGX_ERROR;
case sw_before_month:
if (ch == ' ') {
rfc822 = 1;
}
if (ch == '-') {
rfc850 = 1;
}
case sw_space_before_hour:
}
}
}

View File

@ -0,0 +1,21 @@
#include <ngx_config.h>
#if 0
#include <ngx_core.h>
#endif
#include <ngx_http.h>
int ngx_http_special_response(ngx_http_request_t *r, int error)
{
switch (error) {
default:
r->headers_out.status = error;
return ngx_http_header_filter(r);
}
return ngx_http_error(r, error);
}

View File

@ -15,10 +15,14 @@ static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool);
ngx_http_module_t ngx_http_write_filter_module = { ngx_http_module_t ngx_http_write_filter_module = {
NGX_HTTP_MODULE, NGX_HTTP_MODULE,
NULL, /* create server config */ NULL, /* create server config */
ngx_http_write_filter_create_conf, /* create location config */ ngx_http_write_filter_create_conf, /* create location config */
ngx_http_write_filter_commands, /* module directives */ ngx_http_write_filter_commands, /* module directives */
NULL, /* init module */ NULL, /* init module */
NULL, /* translate handler */
NULL /* init output body filter */ NULL /* init output body filter */
}; };

View File

@ -12,6 +12,9 @@ typedef struct stat ngx_file_info_t;
#define ngx_open_file open #define ngx_open_file open
#define ngx_open_file_n "open()" #define ngx_open_file_n "open()"
#define ngx_close_file close
#define ngx_close_file_n "close()"
#define ngx_read_file_n "read()" #define ngx_read_file_n "read()"
#define NGX_FILE_RDONLY O_RDONLY #define NGX_FILE_RDONLY O_RDONLY