nginx-0.0.1-2003-01-09-08:36:00 import

This commit is contained in:
Igor Sysoev 2003-01-09 05:36:00 +00:00
parent c1817846d2
commit 4e9393a054
34 changed files with 1732 additions and 1033 deletions

View File

@ -36,7 +36,7 @@ ngx_pool_t *ngx_pool;
int ngx_connection_counter;
ngx_array_t *ngx_listening_sockets;
ngx_array_t ngx_listening_sockets;
int main(int argc, char *const *argv)
@ -56,9 +56,9 @@ int main(int argc, char *const *argv)
ngx_init_sockets(&ngx_log);
/* TODO: read config */
ngx_init_array(ngx_listening_sockets, ngx_pool, 10, sizeof(ngx_listen_t),
1);
#if 1
ngx_memzero(&conf, sizeof(ngx_conf_t));
ngx_test_null(conf.args,
ngx_create_array(ngx_pool, 10, sizeof(ngx_str_t)), 1);
@ -69,16 +69,16 @@ int main(int argc, char *const *argv)
conf_file.len = sizeof("nginx.conf") - 1;
conf_file.data = "nginx.conf";
ngx_conf_parse(&conf, &conf_file);
#endif
ngx_test_null(ngx_listening_sockets,
ngx_create_array(ngx_pool, 10, sizeof(ngx_listen_t)), 1);
if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) {
exit(1);
}
#if 0
/* STUB */
/* TODO: init chain of global modules (like ngx_http.c),
they would init its modules and ngx_listening_sockets */
ngx_http_init(ngx_pool, &ngx_log);
#endif
ngx_open_listening_sockets(&ngx_log);
@ -86,7 +86,7 @@ int main(int argc, char *const *argv)
/* TODO: fork */
ngx_pre_thread(ngx_listening_sockets, ngx_pool, &ngx_log);
ngx_pre_thread(&ngx_listening_sockets, ngx_pool, &ngx_log);
/* TODO: threads */
@ -125,10 +125,10 @@ static void ngx_open_listening_sockets(ngx_log_t *log)
failed = 0;
/* for each listening socket */
ls = (ngx_listen_t *) ngx_listening_sockets->elts;
for (i = 0; i < ngx_listening_sockets->nelts; i++) {
ls = (ngx_listen_t *) ngx_listening_sockets.elts;
for (i = 0; i < ngx_listening_sockets.nelts; i++) {
if (ls[i].done)
if (ls[i].bound)
continue;
if (ls[i].inherited) {
@ -137,7 +137,7 @@ static void ngx_open_listening_sockets(ngx_log_t *log)
/* TODO: nonblocking */
/* TODO: deferred accept */
ls[i].done = 1;
ls[i].bound = 1;
continue;
}
@ -194,7 +194,7 @@ static void ngx_open_listening_sockets(ngx_log_t *log)
/* TODO: deferred accept */
ls[i].fd = s;
ls[i].done = 1;
ls[i].bound = 1;
}
if (!failed)

View File

@ -10,7 +10,7 @@
#define NGX_MAX_ALLOC_FROM_POOL (8192 - sizeof(ngx_pool_t))
#define NGX_DEFAULT_POOL_SIZE (16 * 1024)
#define ngx_test_null(p, alloc, rc) if ((p = alloc) == NULL) return rc
#define ngx_test_null(p, alloc, rc) if ((p = alloc) == NULL) { return rc; }
typedef struct ngx_pool_large_s ngx_pool_large_t;

View File

@ -2,19 +2,17 @@
#include <ngx_config.h>
#include <ngx_alloc.h>
#include <ngx_string.h>
#include <ngx_array.h>
ngx_array_t *ngx_create_array(ngx_pool_t *p, int n, size_t size)
{
ngx_array_t *a;
a = ngx_palloc(p, sizeof(ngx_array_t));
if (a == NULL)
return NULL;
ngx_test_null(a, ngx_palloc(p, sizeof(ngx_array_t)), NULL);
a->elts = ngx_palloc(p, n * size);
if (a->elts == NULL)
return NULL;
ngx_test_null(a->elts, ngx_palloc(p, n * size), NULL);
a->pool = p;
a->nelts = 0;
@ -24,24 +22,31 @@ ngx_array_t *ngx_create_array(ngx_pool_t *p, int n, size_t size)
return a;
}
void ngx_destroy_array(ngx_array_t *a)
{
ngx_pool_t *p = a->pool;
ngx_pool_t *p;
if (a->elts + a->size * a->nalloc == p->last)
p = a->pool;
if (a->elts + a->size * a->nalloc == p->last) {
p->last -= a->size * a->nalloc;
}
if ((char *) a + sizeof(ngx_array_t) == p->last)
if ((char *) a + sizeof(ngx_array_t) == p->last) {
p->last = (char *) a;
}
}
void *ngx_push_array(ngx_array_t *a)
{
void *elt;
void *elt, *new;
ngx_pool_t *p;
/* array is full */
if (a->nelts == a->nalloc) {
ngx_pool_t *p = a->pool;
p = a->pool;
/* array allocation is the last in the pool */
if (a->elts + a->size * a->nelts == p->last
@ -52,11 +57,9 @@ void *ngx_push_array(ngx_array_t *a)
/* allocate new array */
} else {
void *new = ngx_palloc(p, 2 * a->nalloc * a->size);
if (new == NULL)
return NULL;
ngx_test_null(new, ngx_palloc(p, 2 * a->nalloc * a->size), NULL);
memcpy(new, a->elts, a->nalloc * a->size);
ngx_memcpy(new, a->elts, a->nalloc * a->size);
a->elts = new;
a->nalloc *= 2;
}

View File

@ -20,4 +20,9 @@ void ngx_destroy_array(ngx_array_t *a);
void *ngx_push_array(ngx_array_t *a);
#define ngx_init_array(a, p, n, s, rc) \
ngx_test_null(a.elts, ngx_palloc(p, n * s), rc); \
a.nelts = 0; a.size = s; a.nalloc = n; a.pool = p;
#endif /* _NGX_ARRAY_H_INCLUDED_ */

View File

@ -13,10 +13,11 @@ static int argument_number[] = {
static int ngx_conf_read_token(ngx_conf_t *cf);
int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
{
int rc, i;
char *error;
int i, rc, found;
char *rv;
void *conf, **pconf;
ngx_str_t *name;
ngx_fd_t fd;
ngx_conf_file_t *prev;
@ -29,13 +30,13 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
"ngx_conf_file: "
ngx_open_file_n " %s failed", filename->data);
return NGX_ERROR;
return NGX_CONF_ERROR;
}
prev = cf->conf_file;
ngx_test_null(cf->conf_file,
ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)),
NGX_ERROR);
NGX_CONF_ERROR);
if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) {
ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
@ -45,7 +46,7 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
ngx_test_null(cf->conf_file->hunk,
ngx_create_temp_hunk(cf->pool, 1024, 0, 0),
NGX_ERROR);
NGX_CONF_ERROR);
cf->conf_file->file.fd = fd;
cf->conf_file->file.name.len = filename->len;
@ -59,22 +60,29 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
/* NGX_OK, NGX_ERROR, NGX_CONF_FILE_DONE, NGX_CONF_BLOCK_DONE */
if (rc == NGX_ERROR || rc == NGX_CONF_FILE_DONE) {
return rc;
ngx_log_debug(cf->log, "token %d" _ rc);
if (rc == NGX_ERROR) {
return NGX_CONF_ERROR;
}
if (rc != NGX_OK) {
return NGX_CONF_OK;
}
if (cf->handler) {
if ((*cf->handler)(cf) == NGX_ERROR) {
return NGX_ERROR;
if ((*cf->handler)(cf) == NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
continue;
}
name = (ngx_str_t *) cf->args->elts;
found = 0;
for (i = 0; ngx_modules[i]; i++) {
for (i = 0; !found && ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NULL
&& ngx_modules[i]->type != cf->type)
{
@ -93,86 +101,56 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data);
cmd->set(cf, cmd, NULL);
if (!(cmd->type & argument_number[cf->args->nelts - 1])) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"invalid number arguments in "
"directive \"%s\" in %s:%d",
name->data,
cf->conf_file->file.name.data,
cf->conf_file->line);
return NGX_CONF_ERROR;
}
conf = NULL;
if (cf->ctx) {
pconf = *(void **) ((char *) cf->ctx + cmd->conf);
if (pconf) {
conf = pconf[ngx_modules[i]->index];
}
}
rv = cmd->set(cf, cmd, conf);
ngx_log_debug(cf->log, "rv: %d" _ rv);
if (rv == NGX_CONF_OK) {
found = 1;
break;
} else if (rv == NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
} else {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"%s", rv);
return NGX_CONF_ERROR;
}
}
cmd++;
}
}
#if 0
cmd = ngx_conf_find_token(cf);
if (cmd == NULL) {
if (!found) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"unknown directive \"%s\" in %s:%d",
cf->name, cf->file->name, cf->file->line);
return NGX_ERROR;
name->data,
cf->conf_file->file.name.data,
cf->conf_file->line);
return NGX_CONF_ERROR;
}
if (cmd->type & argument_number[cf->args->nelts - 1]) {
error = cmd->set(cf, cmd->offset, cf->args);
if (error) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"%s in directive \"%s\" in %s:%d",
error, cf->name, cf->file->name, cf->file->line);
return NGX_ERROR;
}
}
#endif
#if 0
if (cmd->type == NGX_CONF_CONTAINER) {
ngx_conf_parse(cf, cmd->container, NULL);
} else if (cmd->type == NGX_CONF_FLAG) {
if (cf->args->nelts != 1) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"invalid number of arguments "
"in directive \"%s\" in %s:%d",
cf->name, cf->file->name, cf->file->line);
return NGX_ERROR;
}
if (ngx_strcasecmp(cf->args->elts[0], "on") == 0) {
flag = 1;
} else if (ngx_strcasecmp(cf->args->elts[0], "off") == 0) {
flag = 0;
} else {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"invalid flag in directive \"%s\" in %s:%d",
cf->name, cf->file->name, cf->file->line);
return NGX_ERROR;
}
rv = cmd->set(cf, cmd->offset, flag);
if (rv) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"%s in directive \"%s\" in %s:%d",
rv, cf->name, cf->file->name, cf->file->line);
return NGX_ERROR;
}
} else if (cmd->type & argument_number[args->nelts]) {
rv = cmd->set(cf, cmd->offset, cf->args);
if (rv) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"%s in directive \"%s\" in %s:%d",
rv, cf->name, cf->file->name, cf->file->line);
return NGX_ERROR;
}
} else {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"invalid number of arguments "
"in directive \"%s\" in %s:%d",
cf->name, cf->file->name, cf->file->line);
return NGX_ERROR;
}
#endif
}
if (filename) {
@ -182,11 +160,11 @@ ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data);
ngx_log_error(NGX_LOG_ERR, cf->log, ngx_errno,
ngx_close_file_n " %s failed",
cf->conf_file->file.name.data);
return NGX_ERROR;
return NGX_CONF_ERROR;
}
}
return NGX_OK;
return NGX_CONF_OK;
}
@ -391,6 +369,20 @@ ngx_log_debug(cf->log, "FOUND %d:'%s'" _ word->len _ word->data);
}
char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
{
ngx_str_t *field, *value;
field = (ngx_str_t *) conf + cmd->offset;
value = (ngx_str_t *) cf->args->elts;
field->len = value->len;
field->data = value->data;
return NGX_CONF_OK;
}
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
{
int size;
@ -405,7 +397,7 @@ char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
*(int *) (conf + cmd->offset) = size;
return NULL;
return NGX_CONF_OK;
}
@ -423,5 +415,5 @@ char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
*(int *) (conf + cmd->offset) = size;
return NULL;
return NGX_CONF_OK;
}

View File

@ -15,15 +15,16 @@
#define NGX_CONF_NOARGS 1
#define NGX_CONF_TAKE1 2
#define NGX_CONF_TAKE2 4
#define NGX_CONF_ARGS_NUMBER 0x0ffff
#define NGX_CONF_ANY 0x10000
#define NGX_CONF_BLOCK 0x20000
#define NGX_CONF_ARGS_NUMBER 0x00ffff
#define NGX_CONF_ANY 0x010000
#define NGX_CONF_BLOCK 0x020000
#define NGX_CONF_UNSET -1
#define NGX_CONF_ERROR (char *) -1
#define NGX_CONF_OK NULL
#define NGX_CONF_ERROR (void *) -1
#define NGX_CONF_BLOCK_DONE 1
#define NGX_CONF_FILE_DONE 2
@ -46,6 +47,7 @@ struct ngx_command_s {
typedef struct {
int index;
void *ctx;
ngx_command_t *commands;
int type;
@ -70,13 +72,21 @@ struct ngx_conf_s {
void *ctx;
int type;
int (*handler)(ngx_conf_t *cf);
char *(*handler)(ngx_conf_t *cf);
};
int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename);
#define ngx_conf_merge(conf, prev, default) \
if (conf == NGX_CONF_UNSET) { \
conf = (prev == NGX_CONF_UNSET) ? default : prev; \
}
char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename);
char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);

View File

@ -30,16 +30,18 @@ struct ngx_connection_s {
off_t sent;
ngx_log_t *log;
int (*handler)(ngx_connection_t *c);
ngx_server_t *server;
void *ctx;
ngx_server_t *servers;
ngx_pool_t *pool;
ngx_log_t *log;
int family;
struct sockaddr *sockaddr;
socklen_t socklen;
size_t addr;
int addr;
int addr_text_max_len;
ngx_str_t addr_text;
ngx_hunk_t *buffer;

View File

@ -12,27 +12,32 @@ typedef struct {
ngx_socket_t fd;
struct sockaddr *sockaddr;
socklen_t socklen;
size_t addr;
socklen_t socklen; /* size of sockaddr */
int addr; /* offset to address in sockaddr */
int addr_text_max_len;
ngx_str_t addr_text;
int family;
int type;
int protocol;
int flags;
int flags; /* Winsock2 flags */
int (*handler)(ngx_connection_t *c); /* handler of accepted
connection */
void *ctx; /* ngx_http_conf_ctx_t, for example */
void *servers; /* array of ngx_http_in_addr_t, for example */
ngx_log_t *log;
void *server;
int (*handler)(ngx_connection_t *c);
int backlog;
time_t post_accept_timeout;
time_t post_accept_timeout; /* should be here because
of the deferred accept */
unsigned done:1;
unsigned inherited:1;
unsigned bound:1; /* already bound */
unsigned inherited:1; /* inherited from previous process */
unsigned nonblocking:1;
#if 0
unsigned overlapped:1;
unsigned overlapped:1; /* Winsock2 overlapped */
#endif
unsigned shared:1; /* shared between threads or processes */
#if (HAVE_DEFERRED_ACCEPT)
@ -41,4 +46,7 @@ typedef struct {
} ngx_listen_t;
extern ngx_array_t ngx_listening_sockets;
#endif /* _NGX_LISTEN_H_INCLUDED_ */

View File

@ -18,7 +18,8 @@ typedef struct {
#define ngx_memzero ZeroMemory
#define strcasecmp stricmp
#define ngx_strcasecmp stricmp
#define ngx_strncmp strncmp
#define ngx_strcmp strcmp
#define ngx_snprintf _snprintf
@ -28,6 +29,7 @@ typedef struct {
#define ngx_memzero bzero
#define ngx_strncmp strncmp
#define ngx_strcmp strcmp
#define ngx_snprintf snprintf

View File

@ -84,8 +84,9 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
/* STUB */
int max_connections = 512;
if (ngx_init_events(max_connections, log) == NGX_ERROR)
if (ngx_init_events(max_connections, log) == NGX_ERROR) {
exit(1);
}
ngx_connections = ngx_alloc(sizeof(ngx_connection_t)
* max_connections, log);
@ -101,43 +102,44 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
c = &ngx_connections[fd];
ev = &ngx_read_events[fd];
ngx_memzero(&ngx_connections[fd], sizeof(ngx_connection_t));
ngx_memzero(&ngx_read_events[fd], sizeof(ngx_event_t));
ngx_memzero(c, sizeof(ngx_connection_t));
ngx_memzero(ev, sizeof(ngx_event_t));
ngx_connections[fd].fd = fd;
ngx_connections[fd].family = s[i].family;
ngx_connections[fd].socklen = s[i].socklen;
ngx_connections[fd].sockaddr = ngx_palloc(pool, s[i].socklen);
ngx_connections[fd].addr = s[i].addr;
ngx_connections[fd].addr_text = s[i].addr_text;
ngx_connections[fd].post_accept_timeout = s[i].post_accept_timeout;
c->fd = fd;
c->family = s[i].family;
c->socklen = s[i].socklen;
c->sockaddr = ngx_palloc(pool, s[i].socklen);
c->addr = s[i].addr;
c->addr_text = s[i].addr_text;
c->addr_text_max_len = s[i].addr_text_max_len;
c->post_accept_timeout = s[i].post_accept_timeout;
ngx_connections[fd].server = s[i].server;
ngx_connections[fd].handler = s[i].handler;
ngx_connections[fd].log = s[i].log;
c->handler = s[i].handler;
c->ctx = s[i].ctx;
c->servers = s[i].servers;
c->log = s[i].log;
ngx_test_null(ngx_read_events[fd].log,
ngx_test_null(ev->log,
ngx_palloc(pool, sizeof(ngx_log_t)), /* void */ ; );
ngx_memcpy(ngx_read_events[fd].log, ngx_connections[fd].log,
sizeof(ngx_log_t));
ngx_memcpy(ev->log, c->log, sizeof(ngx_log_t));
c->read = ev;
ngx_read_events[fd].data = &ngx_connections[fd];
ngx_read_events[fd].event_handler = &ngx_event_accept;
ngx_read_events[fd].listening = 1;
ev->data = c;
ev->event_handler = &ngx_event_accept;
ev->listening = 1;
ev->index = NGX_INVALID_INDEX;
ngx_read_events[fd].available = 0;
ev->available = 0;
#if (HAVE_DEFERRED_ACCEPT)
ngx_read_events[fd].deferred_accept = s[i].deferred_accept;
ev->deferred_accept = s[i].deferred_accept;
#endif
ngx_add_event(&ngx_read_events[fd], NGX_READ_EVENT, 0);
ngx_add_event(ev, NGX_READ_EVENT, 0);
}
}
void ngx_worker(ngx_log_t *log)
{
while (1) {
for ( ;; ) {
ngx_log_debug(log, "ngx_worker cycle");
ngx_process_events(log);

View File

@ -98,12 +98,14 @@ typedef struct {
/*
NGX_LEVEL_EVENT (default) select, poll, /dev/poll, kqueue
requires to read whole data
NGX_ONESHOT_EVENT select, poll, kqueue
NGX_CLEAR_EVENT kqueue
NGX_ONESHOT_EVENT select, poll, /dev/poll(*), kqueue, epoll(*)
(*) - additional syscall
NGX_CLEAR_EVENT kqueue, epoll
NGX_AIO_EVENT overlapped, aio_read, aioread
no need to add or delete events
NGX_CLOSE_EVENT kqueue: kqueue deletes events for file that closed
/dev/poll: need to flush events before closing
*/
#define NGX_CLOSE_EVENT 1

View File

@ -59,7 +59,7 @@ int ngx_event_accept(ngx_event_t *ev)
c->family = ac->family;
c->socklen = ac->socklen;
c->addr = ac->addr;
c->addr_text.len = ac->addr_text.len;
c->addr_text_max_len = ac->addr_text_max_len;
c->post_accept_timeout = ac->post_accept_timeout;
rev->index = wev->index = NGX_INVALID_INDEX;
@ -77,7 +77,7 @@ int ngx_event_accept(ngx_event_t *ev)
wev->timer_handler = rev->timer_handler = ngx_event_close_connection;
wev->close_handler = rev->close_handler = ngx_event_close_connection;
c->server = ac->server;
c->ctx = ac->ctx;
c->servers = ac->servers;
c->log = rev->log = wev->log = ev->log;

View File

@ -102,7 +102,9 @@ ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in,
sent = rc > 0 ? rc: 0;
#if (NGX_DEBUG_EVENT_WRITE)
ngx_log_debug(c->log, "sendv: " QD_FMT _ sent);
#endif
}
#if (HAVE_MAX_SENDFILE_IOVEC)
}
@ -115,17 +117,21 @@ ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in,
for (ch = in; ch; ch = ch->next) {
ngx_log_debug(c->log, "ch event write: %x %qx %qd" _
#if (NGX_DEBUG_EVENT_WRITE)
ngx_log_debug(c->log, "event write: %x " QX_FMT " " QD_FMT _
ch->hunk->type _
ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
#endif
if (sent >= ch->hunk->last.file - ch->hunk->pos.file) {
sent -= ch->hunk->last.file - ch->hunk->pos.file;
ch->hunk->pos.file = ch->hunk->last.file;
#if (NGX_DEBUG_EVENT_WRITE)
ngx_log_debug(c->log, "event write: " QX_FMT " 0 " QD_FMT _
ch->hunk->pos.file _ sent);
#endif
/*
if (ch->hunk->type & NGX_HUNK_LAST)
@ -137,9 +143,11 @@ ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in,
ch->hunk->pos.file += sent;
ngx_log_debug(c->log, "event write: %qx %qd" _
#if (NGX_DEBUG_EVENT_WRITE)
ngx_log_debug(c->log, "event write: " QX_FMT " " QD_FMT _
ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
#endif
break;
}

View File

@ -39,13 +39,15 @@ int ngx_http_proxy_handler(ngx_http_request_t *r)
p = (ngx_http_proxy_ctx_t *)
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
if (p == NULL)
if (p == NULL) {
ngx_http_create_ctx(r, p, ngx_http_proxy_module_ctx,
sizeof(ngx_http_proxy_ctx_t));
}
chain = ngx_http_proxy_create_request(r);
if (chain == NULL)
if (chain == NULL) {
return NGX_ERROR;
}
p->out = chain;
@ -75,11 +77,13 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
header = (ngx_table_elt_t *) r->headers_in.headers->elts;
for (i = 0; i < r->headers_in.headers->nelts; i++) {
if (&header[i] == r->headers_in.host)
if (&header[i] == r->headers_in.host) {
continue;
}
if (&header[i] == r->headers_in.connection)
if (&header[i] == r->headers_in.connection) {
continue;
}
/* 2 is for ": " and 2 is for "\r\n" */
len += header[i].key.len + 2 + header[i].value.len + 2;
@ -98,11 +102,13 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
hunk->last.mem += sizeof(conn_close) - 1;
for (i = 0; i < r->headers_in.headers->nelts; i++) {
if (&header[i] == r->headers_in.host)
if (&header[i] == r->headers_in.host) {
continue;
}
if (&header[i] == r->headers_in.connection)
if (&header[i] == r->headers_in.connection) {
continue;
}
ngx_memcpy(hunk->last.mem, header[i].key.data, header[i].key.len);
hunk->last.mem += header[i].key.len;
@ -157,9 +163,10 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
"setsockopt(SO_RCVBUF) failed");
if (ngx_close_socket(s) == -1)
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
return NGX_ERROR;
}
@ -170,9 +177,10 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
ngx_nonblocking_n " failed");
if (ngx_close_socket(s) == -1)
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
return NGX_ERROR;
}
@ -184,9 +192,10 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
if (err != NGX_EINPROGRESS) {
ngx_log_error(NGX_LOG_ERR, c->log, err, "connect() failed");
if (ngx_close_socket(s) == -1)
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
return NGX_ERROR;
}
@ -207,7 +216,6 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
pc->data = r;
pc->fd = s;
pc->server = c->server;
pc->servers = c->servers;
pc->log = rev->log = wev->log = c->log;
@ -220,14 +228,16 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
rev->event_handler = ngx_http_proxy_read_response_header;
#if (HAVE_CLEAR_EVENT)
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK)
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) {
#else
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK)
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK) {
#endif
return NGX_ERROR;
}
if (rc == -1)
if (rc == -1) {
return ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT);
}
wev->write = 1;
wev->ready = 1;
@ -249,8 +259,9 @@ static int ngx_http_proxy_send_request(ngx_event_t *ev)
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
chain = ngx_event_write(c, p->out, 0);
if (chain == (ngx_chain_t *) -1)
if (chain == (ngx_chain_t *) -1) {
return NGX_ERROR;
}
p->out = chain;
@ -266,8 +277,9 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
ngx_http_request_t *r;
ngx_http_proxy_ctx_t *p;
if (ev->timedout)
if (ev->timedout) {
return NGX_ERROR;
}
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
@ -330,8 +342,9 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
do {
rc = (p->state_handler)(r, p);
if (rc == NGX_ERROR)
if (rc == NGX_ERROR) {
return rc;
}
/* rc == NGX_OK || rc == NGX_AGAIN */
@ -339,8 +352,9 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
#endif
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) {
return ngx_http_proxy_read_response_body(ev);
}
return NGX_WAITING;
}
@ -406,11 +420,15 @@ static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
#if (HAVE_KQUEUE)
#if !(USE_KQUEUE)
if (ngx_event_type == NGX_KQUEUE_EVENT)
if (ngx_event_type == NGX_KQUEUE_EVENT) {
#endif
/* do not allocate new block if there is EOF */
if (ev->eof && ev->available == 0)
if (ev->eof && ev->available == 0) {
left = 1;
}
#if !(USE_KQUEUE)
}
#endif
#endif
if (left == 0) {
ngx_test_null(ph, ngx_push_array(p->hunks), NGX_ERROR);
@ -427,11 +445,13 @@ static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
ngx_log_debug(c->log, "READ:%d" _ n);
if (n == NGX_AGAIN)
if (n == NGX_AGAIN) {
return NGX_WAITING;
}
if (n == NGX_ERROR)
if (n == NGX_ERROR) {
return NGX_ERROR;
}
h->last.mem += n;
left = h->end - h->last.mem;
@ -475,11 +495,13 @@ static int ngx_http_proxy_write_to_client(ngx_event_t *ev)
h = ((ngx_hunk_t **) p->hunks->elts)[p->hunk_n];
rc = ngx_http_output_filter(r, h);
if (rc != NGX_OK)
if (rc != NGX_OK) {
return rc;
}
if (p->hunk_n >= p->hunks->nelts)
if (p->hunk_n >= p->hunks->nelts) {
break;
}
p->hunk_n++;
@ -519,12 +541,15 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
/* "HTTP/" */
case sw_start:
if (p + 3 >= ctx->header_in->last.mem)
if (p + 3 >= ctx->header_in->last.mem) {
return NGX_AGAIN;
}
if (ch != 'H' || *p != 'T' || *(p + 1) != 'T' || *(p + 2) != 'P'
|| *(p + 3) != '/')
{
return NGX_HTTP_PROXY_PARSE_NO_HEADER;
}
p += 4;
state = sw_first_major_digit;
@ -532,8 +557,9 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
/* first digit of major HTTP version */
case sw_first_major_digit:
if (ch < '1' || ch > '9')
if (ch < '1' || ch > '9') {
return NGX_HTTP_PROXY_PARSE_NO_HEADER;
}
state = sw_major_digit;
break;
@ -545,15 +571,17 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
break;
}
if (ch < '0' || ch > '9')
if (ch < '0' || ch > '9') {
return NGX_HTTP_PROXY_PARSE_NO_HEADER;
}
break;
/* first digit of minor HTTP version */
case sw_first_minor_digit:
if (ch < '0' || ch > '9')
if (ch < '0' || ch > '9') {
return NGX_HTTP_PROXY_PARSE_NO_HEADER;
}
state = sw_minor_digit;
break;
@ -565,15 +593,17 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
break;
}
if (ch < '0' || ch > '9')
if (ch < '0' || ch > '9') {
return NGX_HTTP_PROXY_PARSE_NO_HEADER;
}
break;
/* HTTP status code */
case sw_status:
if (ch < '0' || ch > '9')
if (ch < '0' || ch > '9') {
return NGX_HTTP_PROXY_PARSE_NO_HEADER;
}
ctx->status = ctx->status * 10 + ch - '0';
@ -630,10 +660,13 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
ctx->header_in->pos.mem = p;
if (state == sw_done) {
if (ctx->request_end == NULL)
if (ctx->request_end == NULL) {
ctx->request_end = p - 1;
}
ctx->state = sw_start;
return NGX_OK;
} else {
ctx->state = state;
return NGX_AGAIN;

View File

@ -9,11 +9,12 @@
#include <ngx_http.h>
#include <ngx_http_config.h>
#include <ngx_http_core_module.h>
#include <ngx_http_index_handler.h>
static void *ngx_http_index_create_conf(ngx_pool_t *pool);
static void *ngx_http_index_merge_conf(ngx_pool_t *p,
static char *ngx_http_index_merge_conf(ngx_pool_t *p,
void *parent, void *child);
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
char *conf);
@ -50,6 +51,7 @@ ngx_http_module_t ngx_http_index_module_ctx = {
ngx_module_t ngx_http_index_module = {
0, /* module index */
&ngx_http_index_module_ctx, /* module context */
ngx_http_index_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
@ -66,17 +68,22 @@ int ngx_http_index_handler(ngx_http_request_t *r)
ngx_fd_t fd;
ngx_http_index_conf_t *cf;
ngx_http_core_loc_conf_t *core_cf;
cf = (ngx_http_index_conf_t *)
ngx_http_get_module_loc_conf(r, ngx_http_index_module_ctx);
core_cf = (ngx_http_core_loc_conf_t *)
ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
ngx_test_null(name,
ngx_palloc(r->pool,
r->server->doc_root_len + r->uri.len
core_cf->doc_root.len + r->uri.len
+ cf->max_index_len),
NGX_HTTP_INTERNAL_SERVER_ERROR);
loc.data = ngx_cpystrn(name, r->server->doc_root, r->server->doc_root_len);
loc.data = ngx_cpystrn(name, core_cf->doc_root.data,
core_cf->doc_root.len + 1);
file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1);
index = (ngx_str_t *) cf->indices->elts;
@ -101,7 +108,7 @@ int ngx_http_index_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
r->file.name.len = r->server->doc_root_len + r->uri.len + index[i].len;
r->file.name.len = core_cf->doc_root.len + r->uri.len + index[i].len;
r->file.name.data = name;
r->file.fd = fd;
@ -117,17 +124,34 @@ static void *ngx_http_index_create_conf(ngx_pool_t *pool)
{
ngx_http_index_conf_t *conf;
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)),
NGX_CONF_ERROR);
ngx_test_null(conf->indices,
ngx_create_array(pool, sizeof(ngx_str_t), 3),
NULL);
NGX_CONF_ERROR);
return conf;
}
static void *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
static char *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 *conf = (ngx_http_index_conf_t *) child;
ngx_str_t *index;
ngx_test_null(index, ngx_push_array(conf->indices), NGX_CONF_ERROR);
index->len = sizeof(NGX_HTTP_INDEX) - 1;
index->data = NGX_HTTP_INDEX;
conf->max_index_len = sizeof(NGX_HTTP_INDEX);
return NULL;
}
#if 0
static char *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 *conf = (ngx_http_index_conf_t *) child;
@ -146,7 +170,7 @@ static void *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
return conf;
}
#endif
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
char *conf)

View File

@ -117,6 +117,9 @@ int ngx_http_static_handler(ngx_http_request_t *r)
} 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 if (strcasecmp(r->exten.data, "pdf") == 0) {
r->headers_out.content_type->value.len = 15;
r->headers_out.content_type->value.data = "application/pdf";
}
} else {

View File

@ -5,15 +5,343 @@
#include <ngx_listen.h>
#include <ngx_http.h>
#include <ngx_http_config.h>
#include <ngx_http_core_module.h>
extern ngx_array_t *ngx_listening_sockets;
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
int ngx_http_max_module;
ngx_array_t ngx_http_servers; /* array of ngx_http_core_srv_conf_t */
int ngx_http_post_accept_timeout = 10000;
int ngx_http_connection_pool_size = 16384;
int ngx_http_request_pool_size = 16384;
int ngx_http_client_header_timeout = 20000;
int ngx_http_client_header_buffer_size = 1024;
/* STUB: per location */
int ngx_http_lingering_timeout = 5000;
int ngx_http_lingering_time = 30;
/**/
int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
static ngx_str_t http_name = ngx_string("http");
static ngx_command_t ngx_http_commands[] = {
{ngx_string("http"),
NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_http_block,
0,
0},
{ngx_string(""), 0, NULL, 0, 0}
};
ngx_module_t ngx_http_module = {
0, /* module index */
&http_name, /* module context */
ngx_http_commands, /* module directives */
NGX_CORE_MODULE_TYPE, /* module type */
NULL /* init module */
};
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
{
int i, s, l, p, a, n, start;
int port_found, addr_found, virtual_names;
char *rv;
struct sockaddr_in *addr_in;
ngx_array_t in_ports;
ngx_listen_t *ls;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *prev;
ngx_http_in_port_t *in_port;
ngx_http_in_addr_t *in_addr, *inaddr;
ngx_http_core_srv_conf_t **cscf;
ngx_http_listen_t *lscf;
ngx_http_server_name_t *s_name, *name;;
ngx_init_array(ngx_http_servers, cf->pool, 10,
sizeof(ngx_http_core_srv_conf_t *), NGX_CONF_ERROR);
ngx_test_null(ctx,
ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
NGX_CONF_ERROR);
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
/* STUB */
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
module->index = ngx_http_max_module;
ngx_modules[i]->index = ngx_http_max_module++;
}
/* null loc_conf */
ngx_test_null(ctx->loc_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
NGX_CONF_ERROR);
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->create_loc_conf) {
ngx_test_null(ctx->loc_conf[module->index],
module->create_loc_conf(cf->pool),
NGX_CONF_ERROR);
}
}
prev = cf->ctx;
cf->ctx = ctx;
cf->type = NGX_HTTP_MODULE_TYPE;
rv = ngx_conf_parse(cf, NULL);
cf->ctx = prev;
if (rv != NGX_CONF_OK)
return rv;
ngx_http_init_filters(cf->pool, ngx_modules);
#if 1
ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t),
NGX_CONF_ERROR);
cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts;
for (s = 0; s < ngx_http_servers.nelts; s++) {
lscf = (ngx_http_listen_t *) cscf[s]->listen.elts;
for (l = 0; l < cscf[s]->listen.nelts; l++) {
port_found = 0;
/* AF_INET only */
in_port = (ngx_http_in_port_t *) in_ports.elts;
for (p = 0; p < in_ports.nelts; p++) {
if (lscf[l].port == in_port[p].port) {
port_found = 1;
addr_found = 0;
in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts;
for (a = 0; a < in_port[p].addr.nelts; a++) {
if (lscf[l].addr == in_addr[a].addr) {
s_name = (ngx_http_server_name_t *)
cscf[s]->server_names.elts;
for (n = 0; n < cscf[s]->server_names.nelts; n++) {
ngx_test_null(name,
ngx_push_array(&in_addr[a].names),
NGX_CONF_ERROR);
name->name = s_name[n].name;
name->core_srv_conf = s_name[n].core_srv_conf;
}
if (lscf[l].flags & NGX_HTTP_DEFAULT_SERVER) {
if (in_addr[a].flags
& NGX_HTTP_DEFAULT_SERVER) {
ngx_log_error(NGX_LOG_ERR, cf->log, 0,
"duplicate default server in %s:%d",
lscf[l].conf_file->file.name.data,
lscf[l].line);
return NGX_CONF_ERROR;
}
in_addr[a].flags |= NGX_HTTP_DEFAULT_SERVER;
in_addr[a].core_srv_conf = cscf[s];
}
addr_found = 1;
break;
/* "*:XX" is the last resort */
} else if (in_addr[p].addr == INADDR_ANY) {
ngx_test_null(inaddr,
ngx_push_array(&in_port[p].addr),
NGX_CONF_ERROR);
ngx_memcpy(inaddr, &in_addr[a],
sizeof(ngx_http_in_addr_t));
inaddr->addr = lscf[l].addr;
inaddr->flags = lscf[l].flags;
inaddr->core_srv_conf = cscf[s];
ngx_init_array(inaddr->names, cf->pool, 10,
sizeof(ngx_http_server_name_t),
NGX_CONF_ERROR);
addr_found = 1;
break;
}
}
if (!addr_found) {
ngx_test_null(inaddr,
ngx_push_array(&in_port[p].addr),
NGX_CONF_ERROR);
inaddr->addr = lscf[l].addr;
inaddr->flags = lscf[l].flags;
inaddr->core_srv_conf = cscf[s];
ngx_init_array(inaddr->names, cf->pool, 10,
sizeof(ngx_http_server_name_t),
NGX_CONF_ERROR);
}
}
}
if (!port_found) {
ngx_test_null(in_port,
ngx_push_array(&in_ports),
NGX_CONF_ERROR);
in_port->port = lscf[l].port;
ngx_init_array(in_port->addr, cf->pool, 10,
sizeof(ngx_http_in_addr_t),
NGX_CONF_ERROR);
ngx_test_null(inaddr, ngx_push_array(&in_port[p].addr),
NGX_CONF_ERROR);
inaddr->addr = lscf[l].addr;
inaddr->flags = lscf[l].flags;
inaddr->core_srv_conf = cscf[s];
ngx_init_array(inaddr->names, cf->pool, 10,
sizeof(ngx_http_server_name_t),
NGX_CONF_ERROR);
}
}
}
/* AF_INET only */
in_port = (ngx_http_in_port_t *) in_ports.elts;
for (p = 0; p < in_ports.nelts; p++) {
in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts;
for (a = 0; a < in_port[p].addr.nelts; a++) {
virtual_names = 0;
name = (ngx_http_server_name_t *) in_addr[a].names.elts;
for (n = 0; n < in_addr[a].names.nelts; n++) {
if (in_addr[a].core_srv_conf != name[n].core_srv_conf) {
virtual_names = 1;
break;
}
}
/* if all server names point to the same server
then we do not need to check them at run time */
if (!virtual_names) {
in_addr[a].names.nelts = 0;
}
}
/* if there is binding to "*:XX" then we need to bind to "*:XX" only
and ignore other binding */
if (in_addr[a - 1].addr == INADDR_ANY) {
start = a - 1;
} else {
start = 0;
}
in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts;
for (a = start; a < in_port[p].addr.nelts; a++) {
ngx_test_null(ls, ngx_push_array(&ngx_listening_sockets),
NGX_CONF_ERROR);
ngx_memzero(ls, sizeof(ngx_listen_t));
ngx_test_null(addr_in,
ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)),
NGX_CONF_ERROR);
addr_in->sin_family = AF_INET;
addr_in->sin_addr.s_addr = in_addr[a].addr;
addr_in->sin_port = htons(in_port[p].port);
ngx_test_null(ls->addr_text.data,
ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6),
NGX_CONF_ERROR);
ls->addr_text.len =
ngx_snprintf(ls->addr_text.data
+ ngx_inet_ntop(AF_INET,
&in_addr[a].addr,
ls->addr_text.data,
INET_ADDRSTRLEN),
6, ":%d", in_port[p].port);
ls->family = AF_INET;
ls->type = SOCK_STREAM;
ls->protocol = IPPROTO_IP;
#if (NGX_OVERLAPPED)
ls->flags = WSA_FLAG_OVERLAPPED;
#endif
ls->sockaddr = (struct sockaddr *) addr_in;
ls->socklen = sizeof(struct sockaddr_in);
ls->addr = offsetof(struct sockaddr_in, sin_addr);
ls->addr_text_max_len = INET_ADDRSTRLEN;
ls->backlog = -1;
ls->post_accept_timeout = ngx_http_post_accept_timeout;
ls->nonblocking = 1;
ls->handler = ngx_http_init_connection;
ls->log = cf->log;
ls->ctx = ctx;
ls->servers = &in_port[p].addr;
if (in_port[p].addr.nelts == 1) {
in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts;
if (in_addr[a].names.nelts == 0) {
ls->ctx = in_addr->core_srv_conf->ctx;
ls->servers = NULL;
}
}
}
}
#endif
return NGX_CONF_OK;
}
#if 0
/* STUB */
static struct sockaddr_in addr;
static char addr_text[22];
static ngx_http_server_t ngx_http_server;
int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log)
{
@ -40,8 +368,8 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log)
ngx_http_config_modules(pool, ngx_modules);
#if 0
#if 0
/* STUB */
ngx_http_output_filter_set_stub(pool, ngx_http_modules);
ngx_http_write_filter_set_stub(pool, ngx_http_modules);
@ -49,9 +377,10 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log)
ngx_http_init_modules(pool, ngx_http_modules);
#endif
ngx_http_init_filters(pool, ngx_modules);
ls = ngx_push_array(ngx_listening_sockets);
ls = ngx_push_array(&ngx_listening_sockets);
ngx_memzero(ls, sizeof(ngx_listen_t));
addr.sin_family = AF_INET;
@ -85,3 +414,4 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log)
}
/**/
#endif

View File

@ -114,8 +114,8 @@ struct ngx_http_request_s {
#endif
void **ctx;
void **loc_conf;
void **srv_conf;
void **loc_conf;
ngx_pool_t *pool;
ngx_hunk_t *header_in;
@ -139,7 +139,6 @@ struct ngx_http_request_s {
ngx_http_request_t *main;
ngx_connection_t *connection;
ngx_http_server_t *server;
int filter;
@ -192,9 +191,9 @@ typedef struct {
int index;
void *(*create_srv_conf)(ngx_pool_t *p);
void *(*init_srv_conf)(ngx_pool_t *p, void *conf);
char *(*init_srv_conf)(ngx_pool_t *p, void *conf);
void *(*create_loc_conf)(ngx_pool_t *p);
void *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf);
char *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf);
int (*translate_handler)(ngx_http_request_t *r);
@ -238,6 +237,19 @@ int ngx_http_discard_body(ngx_http_request_t *r);
extern int ngx_max_module;
extern ngx_array_t ngx_http_servers;
extern int ngx_http_post_accept_timeout;
extern int ngx_http_connection_pool_size;
extern int ngx_http_request_pool_size;
extern int ngx_http_client_header_timeout;
extern int ngx_http_client_header_buffer_size;
extern int ngx_http_discarded_buffer_size;
extern int ngx_http_lingering_timeout;
extern int ngx_http_lingering_time;
extern ngx_http_module_t *ngx_http_modules[];

View File

@ -1,316 +0,0 @@
/* TODO:
ngx_http_conf_ctx_t ctx; on stack or in pool ? */
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_conf_file.h>
#include <ngx_http.h>
#include <ngx_http_core.h>
#include <ngx_http_config.h>
#include <ngx_http_write_filter.h>
#include <ngx_http_output_filter.h>
#include <ngx_http_index_handler.h>
/* STUB */
void **ngx_srv_conf;
void **ngx_loc_conf;
/**/
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
void **null_loc_conf;
static ngx_command_t ngx_http_commands[] = {
{ngx_string("http"),
NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_http_block,
0,
0},
{ngx_string(""), 0, NULL, 0, 0}
};
ngx_module_t ngx_http_module = {
NULL, /* module context */
ngx_http_commands, /* module directives */
NGX_CORE_MODULE_TYPE, /* module type */
NULL /* init module */
};
static ngx_command_t ngx_http_core_commands[] = {
{ngx_string("server"),
NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_server_block,
NGX_HTTP_MODULE_TYPE,
0},
{ngx_string(""), 0, NULL, 0, 0}
};
static ngx_http_module_t ngx_http_core_module_ctx = {
NGX_HTTP_MODULE,
NULL, /* create server config */
NULL, /* init server config */
NULL, /* create location config */
NULL, /* merge location config */
NULL, /* translate handler */
NULL, /* output header filter */
NULL, /* next output header filter */
NULL, /* output body filter */
NULL /* next output body filter */
};
ngx_module_t ngx_http_core_module = {
&ngx_http_core_module_ctx, /* module context */
ngx_http_core_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
NULL /* init module */
};
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
{
int i;
ngx_http_module_t *module;
ngx_http_conf_ctx_t ctx;
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
module->index = ngx_http_max_module++;
}
ngx_test_null(null_loc_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
NGX_CONF_ERROR);
ctx.srv_conf = NULL;
ctx.loc_conf = null_loc_conf;
ctx.locations = NULL;
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->create_loc_conf) {
ngx_test_null(null_loc_conf[module->index],
module->create_loc_conf(cf->pool),
NGX_CONF_ERROR);
}
}
cf->ctx = &ctx;
cf->type = NGX_HTTP_MODULE_TYPE;
return ngx_conf_parse(cf, NULL);
}
static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
{
int i, j;
char *rv;
void ***loc_conf; /* YES! 3 stars */
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *prev;
ngx_test_null(ctx,
ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
NGX_CONF_ERROR);
/* server config */
ngx_test_null(ctx->srv_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
NGX_CONF_ERROR);
/* server location config */
ngx_test_null(ctx->loc_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
NGX_CONF_ERROR);
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->create_srv_conf) {
ngx_test_null(ctx->srv_conf[module->index],
module->create_srv_conf(cf->pool),
NGX_CONF_ERROR);
}
if (module->create_loc_conf) {
ngx_test_null(ctx->loc_conf[module->index],
module->create_loc_conf(cf->pool),
NGX_CONF_ERROR);
}
}
prev = cf->ctx;
cf->ctx = ctx;
rv = ngx_conf_parse(cf, NULL);
cf->ctx = prev;
if (rv != NULL)
return rv;
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->init_srv_conf) {
if (module->init_srv_conf(cf->pool,
ctx->srv_conf[module->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
}
if (module->merge_loc_conf) {
if (module->merge_loc_conf(cf->pool,
prev->loc_conf[module->index],
ctx->loc_conf[module->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
loc_conf = (void ***)ctx->locations->elts;
for (j = 0; j < ctx->locations->nelts; j++) {
if (module->merge_loc_conf(cf->pool,
ctx->loc_conf[module->index],
loc_conf[j][module->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
}
}
}
return NULL;
}
#if 0
int ngx_location_block(ngx_conf_t *cf)
{
ngx_http_conf_ctx_t *ctx, *prev;
ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
NGX_ERROR);
ctx->srv_conf = cf->ctx->srv_conf;
ngx_test_null(ctx->loc_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_max_module),
NGX_ERROR);
for (i = 0; modules[i]; i++) {
if (modules[i]->create_loc_conf)
ngx_test_null(ctx->loc_conf[i],
modules[i]->create_loc_conf(cf->pool),
NGX_ERROR);
if (ngx_http_core_module.index == i)
ctx->loc_conf[i].location = cf->args[0];
}
push
return ngx_conf_parse(cf);
}
#endif
int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules)
{
int i;
ngx_http_module_t *module;
for (i = 0; modules[i]; i++) {
if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) modules[i]->ctx;
module->index = i;
}
ngx_http_max_module = i;
#if 0
ngx_test_null(ngx_srv_conf,
ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module),
NGX_ERROR);
ngx_test_null(ngx_loc_conf,
ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module),
NGX_ERROR);
for (i = 0; modules[i]; i++) {
if (modules[i]->create_srv_conf)
ngx_srv_conf[i] = modules[i]->create_srv_conf(pool);
if (modules[i]->create_loc_conf)
ngx_loc_conf[i] = modules[i]->create_loc_conf(pool);
}
#endif
}
void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules)
{
int i;
ngx_http_module_t *module;
int (*ohf)(ngx_http_request_t *r);
int (*obf)(ngx_http_request_t *r, ngx_chain_t *ch);
ohf = NULL;
obf = NULL;
for (i = 0; modules[i]; i++) {
if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) modules[i]->ctx;
if (module->output_header_filter) {
module->next_output_header_filter = ohf;
ohf = module->output_header_filter;
}
if (module->output_body_filter) {
module->next_output_body_filter = obf;
obf = module->output_body_filter;
}
}
ngx_http_top_header_filter = ohf;
}

View File

@ -9,12 +9,15 @@
typedef struct {
void **srv_conf;
void **loc_conf;
ngx_array_t *locations;
} ngx_http_conf_ctx_t;
#define NGX_HTTP_SRV_CONF offsetof(ngx_http_conf_ctx_t, srv_conf)
#define NGX_HTTP_LOC_CONF offsetof(ngx_http_conf_ctx_t, loc_conf)
#define NGX_HTTP_MAIN_CONF 0x1000000
#define NGX_HTTP_SRV_CONF 0x2000000
#define NGX_HTTP_LOC_CONF 0x6000000
#define NGX_HTTP_SRV_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, srv_conf)
#define NGX_HTTP_LOC_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, loc_conf)
int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules);

View File

@ -1,335 +0,0 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_conf_file.h>
#include <ngx_http.h>
#include <ngx_http_core.h>
#include <ngx_http_config.h>
/* STUB */
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_loc_conf(ngx_pool_t *pool);
static int ngx_http_core_translate_handler(ngx_http_request_t *r);
int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
int ngx_http_max_module;
#if 0
static ngx_command_t ngx_http_core_commands[] = {
{ngx_string("send_timeout"),
NGX_CONF_TAKE1,
ngx_conf_set_time_slot,
NGX_HTTP_LOC_CONF,
offsetof(ngx_http_core_loc_conf_t, send_timeout)},
{ngx_string(""), 0, NULL, 0, 0}
};
#endif
ngx_http_module_t ngx_http_core_module_ctx = {
NGX_HTTP_MODULE,
ngx_http_core_create_srv_conf, /* create server config */
NULL, /* init server config */
ngx_http_core_create_loc_conf, /* create location config */
NULL, /* merge location config */
ngx_http_core_translate_handler, /* translate handler */
NULL, /* output header filter */
NULL, /* next output header filter */
NULL, /* output body filter */
NULL, /* next output body filter */
};
#if 0
ngx_module_t ngx_http_core_module = {
&ngx_http_core_module_ctx, /* module context */
ngx_http_core_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
NULL /* init module */
};
#endif
int ngx_http_handler(ngx_http_request_t *r)
{
int rc, i;
ngx_http_module_t *module;
r->connection->unexpected_eof = 0;
r->lingering_close = 1;
r->keepalive = 0;
#if 0
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
#endif
/* run translation phase */
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->translate_handler == NULL) {
continue;
}
rc = module->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->file.name.len = r->server->doc_root_len + r->uri.len + 2;
ngx_test_null(r->file.name.data,
ngx_palloc(r->pool, r->file.name.len + 1),
NGX_HTTP_INTERNAL_SERVER_ERROR);
loc = ngx_cpystrn(r->file.name.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->file.name.data);
#if (WIN9X)
/* There is no way to open file or directory in Win9X with
one syscall: Win9X has not FILE_FLAG_BACKUP_SEMANTICS flag.
so we need to check its type before opening */
#if 0 /* OLD: ngx_file_type() is to be removed */
if (ngx_file_type(r->file.name.data, &r->file.info) == -1) {
#endif
r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
"ngx_http_core_translate_handler: "
ngx_file_type_n " %s failed", r->file.name.data);
if (err == ERROR_FILE_NOT_FOUND) {
return NGX_HTTP_NOT_FOUND;
} else if (err == ERROR_PATH_NOT_FOUND) {
return NGX_HTTP_NOT_FOUND;
} else {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
}
#else
if (r->file.fd == NGX_INVALID_FILE) {
r->file.fd = ngx_open_file(r->file.name.data, NGX_FILE_RDONLY);
}
if (r->file.fd == NGX_INVALID_FILE) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_core_handler: "
ngx_open_file_n " %s failed", r->file.name.data);
if (err == NGX_ENOENT) {
return NGX_HTTP_NOT_FOUND;
} else {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
}
if (!r->file.info_valid) {
if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_core_handler: "
ngx_stat_fd_n " %s failed", r->file.name.data);
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_core_handler: "
ngx_close_file_n " %s failed", r->file.name.data);
}
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
r->file.info_valid = 1;
}
#endif
if (ngx_is_dir(r->file.info)) {
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
#if !(WIN9X)
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_core_handler: "
ngx_close_file_n " %s failed", r->file.name.data);
}
#endif
/* 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_send_header(ngx_http_request_t *r)
{
return (*ngx_http_top_header_filter)(r);
}
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 */
ngx_http_special_response(r, error);
return ngx_http_close_request(r);
}
int ngx_http_close_request(ngx_http_request_t *r)
{
ngx_log_debug(r->connection->log, "CLOSE#: %d" _ r->file.fd);
ngx_http_log_handler(r);
ngx_assert((r->file.fd != NGX_INVALID_FILE), /* void */ ; ,
r->connection->log, "file already closed");
if (r->file.fd != NGX_INVALID_FILE) {
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
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)
{
ngx_http_core_srv_conf_t *conf;
ngx_test_null(conf,
ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)),
NULL);
return conf;
}
static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool)
{
ngx_http_core_loc_conf_t *conf;
ngx_test_null(conf,
ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)),
NULL);
conf->send_timeout = 10;
/*
conf->send_timeout = NGX_CONF_UNSET;
*/
return conf;
}

View File

@ -1,30 +0,0 @@
#ifndef _NGX_HTTP_CORE_H_INCLUDED_
#define _NGX_HTTP_CORE_H_INCLUDED_
#include <ngx_http.h>
typedef struct {
int dummy;
} ngx_http_core_conf_t;
typedef struct {
int dummy;
} ngx_http_core_srv_conf_t;
typedef struct {
time_t send_timeout;
} ngx_http_core_loc_conf_t;
extern ngx_http_module_t ngx_http_core_module_ctx;
extern ngx_module_t ngx_http_core_module;
extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
extern int ngx_http_max_module;
#endif /* _NGX_HTTP_CORE_H_INCLUDED_ */

View File

@ -0,0 +1,710 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_conf_file.h>
#include <ngx_http.h>
#include <ngx_http_config.h>
#include <ngx_http_core_module.h>
#if 0
#include <ngx_http_write_filter.h>
#include <ngx_http_output_filter.h>
#include <ngx_http_index_handler.h>
#endif
/* 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 char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd,
char *dummy);
static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool);
static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf);
static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool);
static ngx_command_t ngx_http_core_commands[] = {
{ngx_string("server"),
NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_server_block,
0,
0},
{ngx_string("location"),
NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
ngx_location_block,
0,
0},
{ngx_string("root"),
NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, doc_root)},
{ngx_string("send_timeout"),
NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
ngx_conf_set_time_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, send_timeout)},
{ngx_string(""), 0, NULL, 0, 0}
};
ngx_http_module_t ngx_http_core_module_ctx = {
NGX_HTTP_MODULE,
ngx_http_core_create_srv_conf, /* create server config */
ngx_http_core_init_srv_conf, /* init server config */
ngx_http_core_create_loc_conf, /* create location config */
NULL, /* merge location config */
ngx_http_core_translate_handler, /* translate handler */
NULL, /* output header filter */
NULL, /* next output header filter */
NULL, /* output body filter */
NULL /* next output body filter */
};
ngx_module_t ngx_http_core_module = {
0, /* module index */
&ngx_http_core_module_ctx, /* module context */
ngx_http_core_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
NULL /* init module */
};
int ngx_http_handler(ngx_http_request_t *r)
{
int rc, i;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx;
r->connection->unexpected_eof = 0;
r->lingering_close = 1;
r->keepalive = 0;
ctx = (ngx_http_conf_ctx_t *) r->connection->ctx;
r->srv_conf = ctx->srv_conf;
r->loc_conf = ctx->loc_conf;
ngx_log_debug(r->connection->log, "srv_conf: %0x" _ r->srv_conf);
ngx_log_debug(r->connection->log, "loc_conf: %0x" _ r->loc_conf);
ngx_log_debug(r->connection->log, "servers: %0x" _ r->connection->servers);
#if 1
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
#endif
/* run translation phase */
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->translate_handler == NULL) {
continue;
}
rc = module->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;
}
int ngx_http_core_translate_handler(ngx_http_request_t *r)
{
int i, rc;
char *location, *last;
ngx_err_t err;
ngx_table_elt_t *h;
ngx_http_core_srv_conf_t *scf;
ngx_http_core_loc_conf_t **lcf, *loc_conf;
scf = (ngx_http_core_srv_conf_t *)
ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx);
/* find location config */
lcf = (ngx_http_core_loc_conf_t **) scf->locations.elts;
for (i = 0; i < scf->locations.nelts; i++) {
ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data);
if (r->uri.len < lcf[i]->name.len) {
continue;
}
rc = ngx_strncmp(r->uri.data, lcf[i]->name.data, lcf[i]->name.len);
if (rc < 0) {
break;
}
if (rc == 0) {
r->loc_conf = lcf[i]->loc_conf;
}
}
if (r->uri.data[r->uri.len - 1] == '/') {
/* TODO: find index handler */
/* STUB */ r->handler = ngx_http_index_handler;
return NGX_OK;
}
loc_conf = (ngx_http_core_loc_conf_t *)
ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
r->file.name.len = loc_conf->doc_root.len + r->uri.len;
ngx_test_null(r->file.name.data,
ngx_palloc(r->pool, r->file.name.len + 1),
NGX_HTTP_INTERNAL_SERVER_ERROR);
location = ngx_cpystrn(r->file.name.data, loc_conf->doc_root.data,
loc_conf->doc_root.len + 1);
last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1);
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _
r->file.name.data);
#if (WIN9X)
/* There is no way to open file or directory in Win9X with
one syscall: Win9X has not FILE_FLAG_BACKUP_SEMANTICS flag.
so we need to check its type before opening */
r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
"ngx_http_core_translate_handler: "
ngx_file_type_n " %s failed", r->file.name.data);
if (err == ERROR_FILE_NOT_FOUND) {
return NGX_HTTP_NOT_FOUND;
} else if (err == ERROR_PATH_NOT_FOUND) {
return NGX_HTTP_NOT_FOUND;
} else {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
}
#else
if (r->file.fd == NGX_INVALID_FILE) {
r->file.fd = ngx_open_file(r->file.name.data, NGX_FILE_RDONLY);
}
if (r->file.fd == NGX_INVALID_FILE) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_core_handler: "
ngx_open_file_n " %s failed", r->file.name.data);
if (err == NGX_ENOENT) {
return NGX_HTTP_NOT_FOUND;
#if (WIN32)
} else if (err == ERROR_PATH_NOT_FOUND) {
return NGX_HTTP_NOT_FOUND;
#endif
} else {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
}
if (!r->file.info_valid) {
if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_core_handler: "
ngx_stat_fd_n " %s failed", r->file.name.data);
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_core_handler: "
ngx_close_file_n " %s failed", r->file.name.data);
}
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
r->file.info_valid = 1;
}
#endif
if (ngx_is_dir(r->file.info)) {
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
#if !(WIN9X)
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_core_handler: "
ngx_close_file_n " %s failed", r->file.name.data);
}
#endif
/* 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 - location;
h->value.data = location;
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_send_header(ngx_http_request_t *r)
{
return (*ngx_http_top_header_filter)(r);
}
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 */
ngx_http_special_response(r, error);
return ngx_http_close_request(r);
}
int ngx_http_close_request(ngx_http_request_t *r)
{
ngx_log_debug(r->connection->log, "CLOSE#: %d" _ r->file.fd);
ngx_http_log_handler(r);
ngx_assert((r->file.fd != NGX_INVALID_FILE), /* void */ ; ,
r->connection->log, "file already closed");
if (r->file.fd != NGX_INVALID_FILE) {
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
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);
}
#if 0
void *ngx_http_find_server_conf(ngx_http_request_t *r)
{
int i;
ngx_http_listen_t *fs, *ls;
ngx_http_server_name_t *n;
fs = NULL;
ls = (ngx_http_listen_t *) http->ports.elts;
for (i = 0; i < http->ports.nelts; i++) {
if (s->family != ls[i].family || s->port != ls[i].port) {
continue;
}
if (s->family == AF_INET) {
if (ls[i].addr == INADDR_ANY || ls[i].addr == s->addr) {
fs = &ls[i];
break;
}
} else {
/* STUB: AF_INET only */
}
}
if (fs == NULL) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"unknown local socket %s:%d",
s->addr_text.data, s->port);
return NULL;
}
if (r->headers_in.host && fs->server_names.nelts) {
n = (ngx_http_server_name_t *) fs->server_names.elts;
for (i = 0; i < fs->server_names.nelts; i++) {
if (r->headers_in.host->value.len != n[i].name.len) {
continue;
}
if (ngx_strcmp(r->headers_in.host->value.data, n[i].name.data) == 0) {
return n[i].srv_conf;
}
}
}
return fs->srv_conf;
}
#endif
static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
{
int i, j;
char *rv;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *prev;
ngx_http_core_srv_conf_t *scf;
ngx_http_core_loc_conf_t **lcf;
ngx_test_null(ctx,
ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
NGX_CONF_ERROR);
/* server config */
ngx_test_null(ctx->srv_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
NGX_CONF_ERROR);
/* server location config */
ngx_test_null(ctx->loc_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
NGX_CONF_ERROR);
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->create_srv_conf) {
ngx_test_null(ctx->srv_conf[module->index],
module->create_srv_conf(cf->pool),
NGX_CONF_ERROR);
ngx_log_debug(cf->log, "srv_conf: %d:%0x" _
module->index _ ctx->loc_conf[module->index]);
}
if (module->create_loc_conf) {
ngx_test_null(ctx->loc_conf[module->index],
module->create_loc_conf(cf->pool),
NGX_CONF_ERROR);
ngx_log_debug(cf->log, "srv loc_conf: %d:%0x" _
module->index _ ctx->loc_conf[module->index]);
}
}
prev = cf->ctx;
cf->ctx = ctx;
rv = ngx_conf_parse(cf, NULL);
cf->ctx = prev;
if (rv != NGX_CONF_OK)
return rv;
scf = ctx->srv_conf[ngx_http_core_module_ctx.index];
scf->ctx = ctx;
lcf = (ngx_http_core_loc_conf_t **)scf->locations.elts;
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->init_srv_conf) {
if (module->init_srv_conf(cf->pool,
ctx->srv_conf[module->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
}
if (module->merge_loc_conf) {
if (module->merge_loc_conf(cf->pool,
prev->loc_conf[module->index],
ctx->loc_conf[module->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
for (j = 0; j < scf->locations.nelts; j++) {
ngx_log_debug(cf->log, "%d:%0x" _ j _ lcf[j]);
ngx_log_debug(cf->log, "%d:'%s'" _ lcf[j]->name.len _ lcf[j]->name.data);
if (module->merge_loc_conf(cf->pool,
ctx->loc_conf[module->index],
lcf[j]->loc_conf[module->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
}
}
}
return NGX_CONF_OK;
}
static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
{
int i;
char *rv;
void **loc;
ngx_str_t *location;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *prev;
ngx_http_core_srv_conf_t *scf;
ngx_http_core_loc_conf_t *lcf;
ngx_test_null(ctx,
ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
NGX_CONF_ERROR);
prev = (ngx_http_conf_ctx_t *) cf->ctx;
ctx->srv_conf = prev->srv_conf;
ngx_test_null(ctx->loc_conf,
ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
NGX_CONF_ERROR);
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->create_loc_conf) {
ngx_test_null(ctx->loc_conf[module->index],
module->create_loc_conf(cf->pool),
NGX_CONF_ERROR);
ngx_log_debug(cf->log, "loc_conf: %d:%0x" _
module->index _ ctx->loc_conf[module->index]);
}
}
lcf = (ngx_http_core_loc_conf_t *)
ctx->loc_conf[ngx_http_core_module_ctx.index];
location = (ngx_str_t *) cf->args->elts;
lcf->name.len = location[1].len;
lcf->name.data = location[1].data;
lcf->loc_conf = ctx->loc_conf;
scf = (ngx_http_core_srv_conf_t *)
ctx->srv_conf[ngx_http_core_module_ctx.index];
ngx_test_null(loc, ngx_push_array(&scf->locations), NGX_CONF_ERROR);
*loc = lcf;
ngx_log_debug(cf->log, "%0x:%s" _ lcf _ lcf->name.data);
cf->ctx = ctx;
rv = ngx_conf_parse(cf, NULL);
cf->ctx = prev;
return rv;
}
int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules)
{
int i;
ngx_http_module_t *module;
for (i = 0; modules[i]; i++) {
if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) modules[i]->ctx;
module->index = i;
}
ngx_http_max_module = i;
#if 0
ngx_test_null(ngx_srv_conf,
ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module),
NGX_ERROR);
ngx_test_null(ngx_loc_conf,
ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module),
NGX_ERROR);
for (i = 0; modules[i]; i++) {
if (modules[i]->create_srv_conf)
ngx_srv_conf[i] = modules[i]->create_srv_conf(pool);
if (modules[i]->create_loc_conf)
ngx_loc_conf[i] = modules[i]->create_loc_conf(pool);
}
#endif
}
void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules)
{
int i;
ngx_http_module_t *module;
int (*ohf)(ngx_http_request_t *r);
int (*obf)(ngx_http_request_t *r, ngx_chain_t *ch);
ohf = NULL;
obf = NULL;
for (i = 0; modules[i]; i++) {
if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
continue;
}
module = (ngx_http_module_t *) modules[i]->ctx;
if (module->output_header_filter) {
module->next_output_header_filter = ohf;
ohf = module->output_header_filter;
}
if (module->output_body_filter) {
module->next_output_body_filter = obf;
obf = module->output_body_filter;
}
}
ngx_http_top_header_filter = ohf;
}
static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool)
{
ngx_http_core_srv_conf_t *scf, **cf;
ngx_test_null(scf,
ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)),
NGX_CONF_ERROR);
ngx_init_array(scf->locations, pool, 5, sizeof(void *), NGX_CONF_ERROR);
ngx_init_array(scf->listen, pool, 5, sizeof(ngx_http_listen_t),
NGX_CONF_ERROR);
ngx_test_null(cf, ngx_push_array(&ngx_http_servers), NGX_CONF_ERROR);
*cf = scf;
return scf;
}
static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf)
{
ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf;
ngx_http_listen_t *l;
if (scf->listen.nelts == 0) {
ngx_test_null(l, ngx_push_array(&scf->listen), NGX_CONF_ERROR);
l->addr = INADDR_ANY;
l->port = 8000;
l->family = AF_INET;
}
return NGX_CONF_OK;
}
static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool)
{
ngx_http_core_loc_conf_t *lcf;
ngx_test_null(lcf,
ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)),
NGX_CONF_ERROR);
lcf->doc_root.len = 4;
lcf->doc_root.data = "html";
lcf->send_timeout = 10;
lcf->discarded_buffer_size = 1500;
lcf->lingering_time = 30;
lcf->lingering_timeout = 5000;
/*
lcf->send_timeout = NGX_CONF_UNSET;
*/
return lcf;
}

View File

@ -0,0 +1,86 @@
#ifndef _NGX_HTTP_CORE_H_INCLUDED_
#define _NGX_HTTP_CORE_H_INCLUDED_
#include <ngx_string.h>
#include <ngx_array.h>
#include <ngx_http.h>
typedef struct {
int addr;
int port;
int family;
int flags; /* 'default' */
ngx_conf_file_t *conf_file;
int line;
} ngx_http_listen_t;
typedef struct {
ngx_array_t locations; /* array of ngx_http_core_loc_conf_t */
ngx_array_t listen; /* 'listen', array of ngx_http_listen_t */
ngx_array_t server_names; /* 'server_name',
array of ngx_http_server_name_t */
ngx_http_conf_ctx_t *ctx;
} ngx_http_core_srv_conf_t;
typedef struct {
ngx_str_t name;
ngx_http_core_srv_conf_t *core_srv_conf;
} ngx_http_server_name_t;
typedef struct {
int port;
ngx_array_t addr;
} ngx_http_in_port_t;
typedef struct {
u_int32_t addr;
ngx_array_t names;
int flags;
ngx_http_core_srv_conf_t *core_srv_conf;
} ngx_http_in_addr_t;
#define NGX_HTTP_DEFAULT_SERVER 1
typedef struct {
ngx_str_t name; /* location name */
void **loc_conf; /* used in translation handler */
ngx_str_t doc_root; /* 'root' */
time_t send_timeout; /* 'send_timeout' */
size_t discarded_buffer_size; /* 'discarded_buffer_size */
time_t lingering_time; /* 'lingering_time */
ngx_msec_t lingering_timeout; /* 'lingering_timeout */
} ngx_http_core_loc_conf_t;
#if 0
typedef struct {
int dummy;
} ngx_http_core_conf_t;
#endif
extern ngx_http_module_t ngx_http_core_module_ctx;
extern ngx_module_t ngx_http_core_module;
extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
extern int ngx_http_max_module;
int ngx_http_core_translate_handler(ngx_http_request_t *r);
#endif /* _NGX_HTTP_CORE_H_INCLUDED_ */

View File

@ -12,7 +12,7 @@
#include <ngx_inet.h>
#include <ngx_http.h>
#include <ngx_http_config.h>
#include <ngx_http_core.h>
#include <ngx_http_core_module.h>
/* STUB */
#include <ngx_http_output_filter.h>
@ -75,16 +75,13 @@ int ngx_http_init_connection(ngx_connection_t *c)
{
ngx_event_t *ev;
struct sockaddr *addr;
ngx_http_server_t *srv;
ngx_http_log_ctx_t *ctx;
ev = c->read;
ev->event_handler = ngx_http_init_request;
srv = (ngx_http_server_t *) c->server;
ngx_test_null(c->pool,
ngx_create_pool(srv->connection_pool_size, ev->log),
ngx_create_pool(ngx_http_connection_pool_size, ev->log),
NGX_ERROR);
ngx_test_null(c->requests, ngx_create_array(c->pool, 10, sizeof(char *)),
@ -97,12 +94,12 @@ int ngx_http_init_connection(ngx_connection_t *c)
ngx_memcpy(addr, c->sockaddr, c->socklen);
c->sockaddr = addr;
ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text.len),
ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text_max_len),
NGX_ERROR);
c->addr_text.len = ngx_inet_ntop(c->family,
(char *)c->sockaddr + c->addr,
c->addr_text.data, c->addr_text.len);
c->addr_text.data, c->addr_text_max_len);
if (c->addr_text.len == 0)
return NGX_ERROR;
@ -118,7 +115,6 @@ int ngx_http_init_connection(ngx_connection_t *c)
return ngx_http_init_request(ev);
} else {
#endif
/* STUB: post_accept_timeout should be in http_conf */
ngx_add_timer(ev, c->post_accept_timeout);
#if (USE_KQUEUE)
return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
@ -144,28 +140,21 @@ int ngx_http_init_connection(ngx_connection_t *c)
static int ngx_http_init_request(ngx_event_t *ev)
{
ngx_connection_t *c;
ngx_http_server_t *srv;
ngx_http_request_t *r;
c = (ngx_connection_t *) ev->data;
srv = (ngx_http_server_t *) c->server;
ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)),
NGX_ERROR);
c->data = r;
r->connection = c;
r->server = srv;
r->file.fd = NGX_INVALID_FILE;
/* STUB */
r->srv_conf = ngx_srv_conf;
r->loc_conf = ngx_loc_conf;
/**/
if (c->buffer == NULL) {
ngx_test_null(c->buffer,
ngx_create_temp_hunk(c->pool, srv->header_buffer_size,
ngx_create_temp_hunk(c->pool,
ngx_http_client_header_buffer_size,
0, 0),
NGX_ERROR);
} else {
@ -174,7 +163,7 @@ static int ngx_http_init_request(ngx_event_t *ev)
r->header_in = c->buffer;
ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log),
ngx_test_null(r->pool, ngx_create_pool(ngx_http_request_pool_size, ev->log),
ngx_http_close_request(r));
ngx_test_null(r->ctx,
@ -218,9 +207,7 @@ static int ngx_http_process_request_header(ngx_event_t *ev)
if (r->header_timeout) {
r->header_timeout = 0;
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, ngx_http_client_header_timeout);
}
return NGX_AGAIN;
}
@ -254,7 +241,7 @@ static int ngx_http_process_request_header(ngx_event_t *ev)
if (r->header_timeout) {
r->header_timeout = 0;
ngx_del_timer(ev);
ngx_add_timer(ev, r->server->header_timeout);
ngx_add_timer(ev, ngx_http_client_header_timeout);
}
if (rc == NGX_OK)
@ -593,23 +580,27 @@ static int ngx_http_read_discarded_body(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_http_core_loc_conf_t *lcf;
ngx_log_debug(ev->log, "http read discarded body");
if (ev->timedout)
return NGX_ERROR;
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
lcf = (ngx_http_core_loc_conf_t *)
ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
if (r->discarded_buffer == NULL)
ngx_test_null(r->discarded_buffer,
ngx_palloc(r->pool, r->server->discarded_buffer_size),
ngx_palloc(r->pool, lcf->discarded_buffer_size),
NGX_ERROR);
size = r->client_content_length;
if (size > r->server->discarded_buffer_size)
size = r->server->discarded_buffer_size;
if (size > lcf->discarded_buffer_size)
size = lcf->discarded_buffer_size;
n = ngx_event_recv(c, r->discarded_buffer, size);
if (n == NGX_ERROR)
@ -624,34 +615,6 @@ static int ngx_http_read_discarded_body(ngx_event_t *ev)
}
#if 0
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;
}
#endif
static int ngx_http_keepalive_handler(ngx_event_t *ev)
{
ssize_t n;
@ -690,11 +653,16 @@ static int ngx_http_keepalive_handler(ngx_event_t *ev)
static int ngx_http_set_lingering_close(ngx_http_request_t *r)
{
r->lingering_time = ngx_time() + r->server->lingering_time;
ngx_http_core_loc_conf_t *lcf;
lcf = (ngx_http_core_loc_conf_t *)
ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
r->lingering_time = ngx_time() + lcf->lingering_time;
r->connection->read->event_handler = ngx_http_lingering_close_handler;
ngx_del_timer(r->connection->read);
ngx_add_timer(r->connection->read, r->server->lingering_timeout);
ngx_add_timer(r->connection->read, lcf->lingering_timeout);
if (r->connection->read->blocked) {
if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
@ -725,9 +693,7 @@ static int ngx_http_lingering_close_handler(ngx_event_t *ev)
ngx_msec_t timer;
ngx_connection_t *c;
ngx_http_request_t *r;
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
ngx_http_core_loc_conf_t *lcf;
ngx_log_debug(ev->log, "http lingering close handler");
@ -735,25 +701,30 @@ static int ngx_http_lingering_close_handler(ngx_event_t *ev)
return ngx_http_close_request(r);
}
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
timer = r->lingering_time - ngx_time();
if (timer <= 0) {
return ngx_http_close_request(r);
}
lcf = (ngx_http_core_loc_conf_t *)
ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
if (r->discarded_buffer == NULL) {
if (r->header_in->end - r->header_in->last.mem
>= r->server->discarded_buffer_size) {
>= lcf->discarded_buffer_size) {
r->discarded_buffer = r->header_in->last.mem;
} else {
ngx_test_null(r->discarded_buffer,
ngx_palloc(c->pool, r->server->discarded_buffer_size),
ngx_palloc(c->pool, lcf->discarded_buffer_size),
ngx_http_close_request(r));
}
}
n = ngx_event_recv(c, r->discarded_buffer,
r->server->discarded_buffer_size);
n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size);
ngx_log_debug(ev->log, "lingering read: %d" _ n);
@ -762,8 +733,8 @@ static int ngx_http_lingering_close_handler(ngx_event_t *ev)
}
timer *= 1000;
if (timer > r->server->lingering_timeout) {
timer = r->server->lingering_timeout;
if (timer > lcf->lingering_timeout) {
timer = lcf->lingering_timeout;
}
ngx_del_timer(ev);

View File

@ -34,6 +34,7 @@ ngx_http_module_t ngx_http_header_filter_module_ctx = {
ngx_module_t ngx_http_header_filter_module = {
0, /* module index */
&ngx_http_header_filter_module_ctx, /* module context */
NULL, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */

View File

@ -14,14 +14,16 @@
static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src);
static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool);
static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool,
void *parent, void *child);
static ngx_command_t ngx_http_output_filter_commands[] = {
{ngx_string("output_buffer"),
NGX_CONF_TAKE1,
NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
NGX_HTTP_LOC_CONF,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_output_filter_conf_t, hunk_size)},
{ngx_string(""), 0, NULL, 0, 0}
@ -34,7 +36,7 @@ static ngx_http_module_t ngx_http_output_filter_module_ctx = {
NULL, /* create server config */
NULL, /* init server config */
ngx_http_output_filter_create_conf, /* create location config */
NULL, /* merge location config */
ngx_http_output_filter_merge_conf, /* merge location config */
NULL, /* translate handler */
@ -47,6 +49,7 @@ static ngx_http_module_t ngx_http_output_filter_module_ctx = {
ngx_module_t ngx_http_output_filter_module = {
0, /* module index */
&ngx_http_output_filter_module_ctx, /* module context */
ngx_http_output_filter_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
@ -249,7 +252,7 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
if (ctx->hunk) {
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
}
#if (!NGX_ONESHOT_EVENT)
#if (NGX_LEVEL_EVENT)
ngx_del_event(r->connection->write, NGX_WRITE_EVENT);
#endif
}
@ -315,3 +318,17 @@ static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool)
return conf;
}
static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool,
void *parent, void *child)
{
ngx_http_output_filter_conf_t *prev =
(ngx_http_output_filter_conf_t *) parent;
ngx_http_output_filter_conf_t *conf =
(ngx_http_output_filter_conf_t *) child;
ngx_conf_merge(conf->hunk_size, prev->hunk_size, 32768);
return NULL;
}

View File

@ -43,33 +43,39 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
case sw_start:
switch (ch) {
case 'G':
if (p + 1 >= r->header_in->last.mem)
if (p + 1 >= r->header_in->last.mem) {
return NGX_AGAIN;
}
if (*p != 'E' || *(p + 1) != 'T')
if (*p != 'E' || *(p + 1) != 'T') {
return NGX_HTTP_PARSE_INVALID_METHOD;
}
r->method = NGX_HTTP_GET;
p += 2;
break;
case 'H':
if (p + 2 >= r->header_in->last.mem)
if (p + 2 >= r->header_in->last.mem) {
return NGX_AGAIN;
}
if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D')
if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D') {
return NGX_HTTP_PARSE_INVALID_METHOD;
}
r->method = NGX_HTTP_HEAD;
p += 3;
break;
case 'P':
if (p + 2 >= r->header_in->last.mem)
if (p + 2 >= r->header_in->last.mem) {
return NGX_AGAIN;
}
if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T')
if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T') {
return NGX_HTTP_PARSE_INVALID_METHOD;
}
r->method = NGX_HTTP_POST;
p += 3;
@ -226,8 +232,9 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
return NGX_AGAIN;
}
if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/')
if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/') {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
p += 3;
state = sw_first_major_digit;
@ -235,8 +242,9 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
/* first digit of major HTTP version */
case sw_first_major_digit:
if (ch < '1' || ch > '9')
if (ch < '1' || ch > '9') {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
r->http_major = ch - '0';
state = sw_major_digit;
@ -249,16 +257,18 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
break;
}
if (ch < '0' || ch > '9')
if (ch < '0' || ch > '9') {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
r->http_major = r->http_major * 10 + ch - '0';
break;
/* first digit of minor HTTP version */
case sw_first_minor_digit:
if (ch < '0' || ch > '9')
if (ch < '0' || ch > '9') {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
r->http_minor = ch - '0';
state = sw_minor_digit;
@ -276,8 +286,9 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
break;
}
if (ch < '0' || ch > '9')
if (ch < '0' || ch > '9') {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
r->http_minor = r->http_minor * 10 + ch - '0';
break;
@ -299,14 +310,19 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
r->header_in->pos.mem = p;
if (state == sw_done) {
if (r->request_end == NULL)
if (r->request_end == NULL) {
r->request_end = p - 1;
}
r->http_version = r->http_major * 1000 + r->http_minor;
r->state = sw_start;
if (r->http_version == 9 && r->method == NGX_HTTP_HEAD)
if (r->http_version == 9 && r->method == NGX_HTTP_HEAD) {
return NGX_HTTP_PARSE_INVALID_HEAD;
else
} else {
return NGX_OK;
}
} else {
r->state = state;
return NGX_AGAIN;
@ -358,14 +374,17 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
r->header_name_start = p - 1;
c = ch | 0x20;
if (c >= 'a' && c <= 'z')
if (c >= 'a' && c <= 'z') {
break;
}
if (ch == '-')
if (ch == '-') {
break;
}
if (ch >= '0' && ch <= '9')
if (ch >= '0' && ch <= '9') {
break;
}
return NGX_HTTP_PARSE_INVALID_HEADER;
@ -375,8 +394,9 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
/* header name */
case sw_name:
c = ch | 0x20;
if (c >= 'a' && c <= 'z')
if (c >= 'a' && c <= 'z') {
break;
}
if (ch == ':') {
r->header_name_end = p - 1;
@ -384,11 +404,13 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
break;
}
if (ch == '-')
if (ch == '-') {
break;
}
if (ch >= '0' && ch <= '9')
if (ch >= '0' && ch <= '9') {
break;
}
return NGX_HTTP_PARSE_INVALID_HEADER;
@ -476,9 +498,11 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
if (state == sw_done) {
r->state = sw_start;
return NGX_OK;
} else if (state == sw_header_done) {
r->state = sw_start;
return NGX_HTTP_PARSE_HEADER_DONE;
} else {
r->state = state;
return NGX_AGAIN;

View File

@ -21,8 +21,9 @@ time_t ngx_http_parse_time(char *value, size_t len)
end = value + len;
for (p = value; p < end; p++) {
if (*p == ',')
if (*p == ',') {
break;
}
if (*p == ' ') {
fmt = isoc;
@ -31,22 +32,26 @@ time_t ngx_http_parse_time(char *value, size_t len)
}
for (p++; p < end; p++)
if (*p != ' ')
if (*p != ' ') {
break;
}
if (end - p < 18)
if (end - p < 18) {
return NGX_ERROR;
}
if (fmt != isoc) {
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
return NGX_ERROR;
}
day = (*p - '0') * 10 + *(p + 1) - '0';
p += 2;
if (*p == ' ') {
if (end - p < 18)
if (end - p < 18) {
return NGX_ERROR;
}
fmt = rfc822;
} else if (*p == '-') {
@ -99,8 +104,9 @@ time_t ngx_http_parse_time(char *value, size_t len)
p += 3;
if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-'))
if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) {
return NGX_ERROR;
}
p++;
@ -108,15 +114,18 @@ time_t ngx_http_parse_time(char *value, size_t len)
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
|| *(p + 2) < '0' || *(p + 2) > '9'
|| *(p + 3) < '0' || *(p + 3) > '9')
{
return NGX_ERROR;
}
year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
+ (*(p + 2) - '0') * 10 + *(p + 3) - '0';
p += 4;
} else if (fmt == rfc850) {
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
return NGX_ERROR;
}
year = (*p - '0') * 10 + *(p + 1) - '0';
year += (year < 70) ? 2000 : 1900;
@ -124,61 +133,74 @@ time_t ngx_http_parse_time(char *value, size_t len)
}
if (fmt == isoc) {
if (*p == ' ')
if (*p == ' ') {
p++;
}
if (*p < '0' || *p > '9')
if (*p < '0' || *p > '9') {
return NGX_ERROR;
}
day = *p++ - '0';
if (*p != ' ') {
if (*p < '0' || *p > '9')
if (*p < '0' || *p > '9') {
return NGX_ERROR;
}
day = day * 10 + *p++ - '0';
}
if (end - p < 14)
if (end - p < 14) {
return NGX_ERROR;
}
}
if (*p++ != ' ') {
return NGX_ERROR;
}
if (*p++ != ' ')
return NGX_ERROR;
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
return NGX_ERROR;
}
hour = (*p - '0') * 10 + *(p + 1) - '0';
p += 2;
if (*p++ != ':')
if (*p++ != ':') {
return NGX_ERROR;
}
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
return NGX_ERROR;
}
min = (*p - '0') * 10 + *(p + 1) - '0';
p += 2;
if (*p++ != ':')
if (*p++ != ':') {
return NGX_ERROR;
}
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9')
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
return NGX_ERROR;
}
sec = (*p - '0') * 10 + *(p + 1) - '0';
if (fmt == isoc) {
p += 2;
if (*p++ != ' ')
if (*p++ != ' ') {
return NGX_ERROR;
}
if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
|| *(p + 2) < '0' || *(p + 2) > '9'
|| *(p + 3) < '0' || *(p + 3) > '9')
{
return NGX_ERROR;
}
year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
+ (*(p + 2) - '0') * 10 + *(p + 3) - '0';
@ -188,19 +210,22 @@ time_t ngx_http_parse_time(char *value, size_t len)
printf("%d.%d.%d %d:%d:%d\n", day, month + 1, year, hour, min, sec);
#endif
if (hour > 23 || min > 59 || sec > 59)
if (hour > 23 || min > 59 || sec > 59) {
return NGX_ERROR;
}
if (day == 29 && month == 1) {
if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0))
if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) {
return NGX_ERROR;
}
} else if (day > mday[month]) {
return NGX_ERROR;
}
if (sizeof(time_t) <= 4 && year >= 2038)
if (sizeof(time_t) <= 4 && year >= 2038) {
return NGX_ERROR;
}
/* shift new year to 1st March, needed for Gauss's formula */
if (--month <= 0) {

View File

@ -13,14 +13,16 @@
static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool);
static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool,
void *parent, void *child);
static ngx_command_t ngx_http_write_filter_commands[] = {
{ngx_string("write_buffer"),
NGX_CONF_TAKE1,
NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
NGX_HTTP_LOC_CONF,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_write_filter_conf_t, buffer_output)},
{ngx_string(""), 0, NULL, 0, 0}
@ -33,7 +35,7 @@ ngx_http_module_t ngx_http_write_filter_module_ctx = {
NULL, /* create server config */
NULL, /* init server config */
ngx_http_write_filter_create_conf, /* create location config */
NULL, /* merge location config */
ngx_http_write_filter_merge_conf, /* merge location config */
NULL, /* translate handler */
@ -45,6 +47,7 @@ ngx_http_module_t ngx_http_write_filter_module_ctx = {
ngx_module_t ngx_http_write_filter_module = {
0, /* module index */
&ngx_http_write_filter_module_ctx, /* module context */
ngx_http_write_filter_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
@ -79,9 +82,12 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
prev = &ch->next;
size += ch->hunk->last.file - ch->hunk->pos.file;
ngx_log_debug(r->connection->log, "old chunk: %x " QX_FMT " " QD_FMT _
#if (NGX_DEBUG_WRITE_FILTER)
ngx_log_debug(r->connection->log, "write filter: old chunk: %x "
QX_FMT " " QD_FMT _
ch->hunk->type _ ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
#endif
if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
flush = size;
@ -102,9 +108,12 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
prev = &ch->next;
size += ch->hunk->last.file - ch->hunk->pos.file;
ngx_log_debug(r->connection->log, "new chunk: %x " QX_FMT " " QD_FMT _
#if (NGX_DEBUG_WRITE_FILTER)
ngx_log_debug(r->connection->log, "write filter: new chunk: %x "
QX_FMT " " QD_FMT _
ch->hunk->type _ ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
#endif
if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
flush = size;
@ -119,7 +128,10 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_http_get_module_loc_conf(r->main ? r->main : r,
ngx_http_write_filter_module_ctx);
ngx_log_debug(r->connection->log, "l:%d f:%d" _ last _ flush);
#if (NGX_DEBUG_WRITE_FILTER)
ngx_log_debug(r->connection->log, "write filter: last:%d flush:%d" _
last _ flush);
#endif
if (!last && flush == 0 && size < conf->buffer_output) {
return NGX_OK;
@ -150,3 +162,18 @@ static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool)
return conf;
}
static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool,
void *parent, void *child)
{
ngx_http_write_filter_conf_t *prev =
(ngx_http_write_filter_conf_t *) parent;
ngx_http_write_filter_conf_t *conf =
(ngx_http_write_filter_conf_t *) child;
ngx_conf_merge(conf->buffer_output, prev->buffer_output, 1460);
return NULL;
}

26
src/os/unix/ngx_pthread.c Normal file
View File

@ -0,0 +1,26 @@
#include <ngx_config.h>
#include <ngx_log.h>
#include <ngx_pthread.h>
int ngx_create_os_thread(ngx_os_tid_t *tid, void *stack,
ngx_thread_start_routine_t func, void *arg,
ngx_log_t log)
{
int err;
pthread_attr_t *attr;
attr = NULL;
err = pthread_create(tid, attr, func, arg);
if (err != 0) {
ngx_log_error(NGX_LOG_ERR, log, err, "pthread_create() failed");
return NGX_ERROR;
}
return NGX_OK;
}

14
src/os/unix/ngx_pthread.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _NGX_OS_THREAD_H_INCLUDED_
#define _NGX_OS_THREAD_H_INCLUDED_
#include <pthread.h>
typedef pthread_t ngx_os_tid_t;
typedef int ngx_tid_t;
typedef void *(*)(void *) ngx_thread_start_routine_t
#endif /* _NGX_OS_THREAD_H_INCLUDED_ */

View File

@ -0,0 +1,26 @@
#include <ngx_config.h>
#include <ngx_log.h>
#include <ngx_os_thread.h>
int ngx_create_os_thread(ngx_os_tid_t *tid, void *stack,
ngx_thread_start_routine_t func, void *arg,
ngx_log_t log)
{
ngx_os_tid_t id;
int dummy; /* needed in Win9X only, in NT can be NULL */
id = CreateThread(NULL, stack_size, func, arg, 0, &dummy);
if (id == NULL) {
ngx_log_error(NGX_LOG_ERR, log, err, "CreateThread() failed");
return NGX_ERROR;
}
*tid = id;
return NGX_OK;
}

View File

@ -0,0 +1,14 @@
#ifndef _NGX_OS_THREAD_H_INCLUDED_
#define _NGX_OS_THREAD_H_INCLUDED_
#include <ngx_config.h>
typedef HANDLE ngx_os_tid_t;
typedef int ngx_tid_t;
typedef LPTHREAD_START_ROUTINE ngx_thread_start_routine_t
#endif /* _NGX_OS_THREAD_H_INCLUDED_ */