nginx-0.0.1-2003-11-18-19:49:00 import

This commit is contained in:
Igor Sysoev 2003-11-18 16:49:00 +00:00
parent 0b2b4ccd2c
commit 222a2adf40
15 changed files with 157 additions and 90 deletions

View File

@ -285,9 +285,9 @@ static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
#if (HAVE_LOWAT_EVENT) #if (HAVE_LOWAT_EVENT)
if ((flags & EV_ADD) && ev->lowat > 0) { if (flags & NGX_LOWAT_EVENT) {
change_list[nchanges].fflags = NOTE_LOWAT; change_list[nchanges].fflags = NOTE_LOWAT;
change_list[nchanges].data = ev->lowat; change_list[nchanges].data = ev->available;
} else { } else {
change_list[nchanges].fflags = 0; change_list[nchanges].fflags = 0;

View File

@ -45,13 +45,20 @@ struct ngx_event_s {
/* /*
* kqueue only: * kqueue only:
* accept: number of sockets that wait to be accepted * accept: number of sockets that wait to be accepted
* read: bytes to read * read: bytes to read when event is ready
* write: available space in buffer * or lowat when event is set with NGX_LOWAT_EVENT flag
* write: available space in buffer when event is ready
* or lowat when event is set with NGX_LOWAT_EVENT flag
* *
* otherwise: * otherwise:
* accept: 1 if accept many, 0 otherwise * accept: 1 if accept many, 0 otherwise
*/ */
#if (HAVE_KQUEUE)
int available; int available;
#else
unsigned available:1;
#endif
unsigned oneshot:1; unsigned oneshot:1;
@ -104,10 +111,6 @@ struct ngx_event_s {
int kq_errno; int kq_errno;
#endif #endif
#if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */
int lowat;
#endif
#if (HAVE_AIO) #if (HAVE_AIO)
@ -224,7 +227,11 @@ extern ngx_event_actions_t ngx_event_actions;
* /dev/poll: we need to flush POLLREMOVE event before closing file * /dev/poll: we need to flush POLLREMOVE event before closing file
*/ */
#define NGX_CLOSE_EVENT 1 #define NGX_CLOSE_EVENT 1
/* this flag has meaning only for kqueue */
#define NGX_LOWAT_EVENT 0
#if (HAVE_KQUEUE) #if (HAVE_KQUEUE)
@ -233,13 +240,17 @@ extern ngx_event_actions_t ngx_event_actions;
#define NGX_WRITE_EVENT EVFILT_WRITE #define NGX_WRITE_EVENT EVFILT_WRITE
/* /*
* NGX_CLOSE_EVENT is the module flag and it would not go into a kernel * NGX_CLOSE_EVENT and NGX_LOWAT_EVENT are the module flags and they would
* so we need to choose the value that would not interfere with any existent * not go into a kernel so we need to choose the value that would not interfere
* and future flags. kqueue has such values - EV_FLAG1, EV_EOF and EV_ERROR. * with any existent and future kqueue flags. kqueue has such values -
* They are reserved and cleared on a kernel entrance. * EV_FLAG1, EV_EOF and EV_ERROR. They are reserved and cleared on a kernel
* entrance.
*/ */
#undef NGX_CLOSE_EVENT #undef NGX_CLOSE_EVENT
#define NGX_CLOSE_EVENT EV_FLAG1 #define NGX_CLOSE_EVENT EV_EOF
#undef NGX_LOWAT_EVENT
#define NGX_LOWAT_EVENT EV_FLAG1
#define NGX_LEVEL_EVENT 0 #define NGX_LEVEL_EVENT 0
#define NGX_ONESHOT_EVENT EV_ONESHOT #define NGX_ONESHOT_EVENT EV_ONESHOT
@ -351,7 +362,7 @@ int ngx_event_post_acceptex(ngx_listening_t *ls, int n);
ngx_inline static int ngx_handle_read_event(ngx_event_t *rev, int close) ngx_inline static int ngx_handle_read_event(ngx_event_t *rev, int flags)
{ {
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
@ -380,10 +391,8 @@ ngx_inline static int ngx_handle_read_event(ngx_event_t *rev, int close)
return NGX_OK; return NGX_OK;
} }
if (rev->active && (rev->ready || close)) { if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
if (ngx_del_event(rev, NGX_READ_EVENT, close ? NGX_CLOSE_EVENT : 0) if (ngx_del_event(rev, NGX_READ_EVENT, flags) == NGX_ERROR) {
== NGX_ERROR)
{
return NGX_ERROR; return NGX_ERROR;
} }
@ -423,21 +432,14 @@ ngx_inline static int ngx_handle_level_read_event(ngx_event_t *rev)
} }
ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, int lowat) ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, int flags)
{ {
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
/* kqueue */ /* kqueue */
#if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */
if (ngx_event_flags & NGX_HAVE_LOWAT_EVENT) {
wev->lowat = lowat;
}
#endif
if (!wev->active && !wev->ready) { if (!wev->active && !wev->ready) {
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT|flags)
== NGX_ERROR) { == NGX_ERROR) {
return NGX_ERROR; return NGX_ERROR;
} }

View File

@ -260,6 +260,8 @@ ngx_log_debug(pc->log, "CONNECT: %s" _ peer->addr_port_text.data);
return NGX_AGAIN; return NGX_AGAIN;
} }
ngx_log_debug(pc->log, "CONNECTED");
wev->ready = 1; wev->ready = 1;
return NGX_OK; return NGX_OK;

View File

@ -19,6 +19,7 @@ static int ngx_event_pipe_drain_chains(ngx_event_pipe_t *p);
int ngx_event_pipe(ngx_event_pipe_t *p, int do_write) int ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
{ {
int flags;
ngx_event_t *rev, *wev; ngx_event_t *rev, *wev;
for ( ;; ) { for ( ;; ) {
@ -45,7 +46,9 @@ int ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
if (p->upstream->fd != -1) { if (p->upstream->fd != -1) {
rev = p->upstream->read; rev = p->upstream->read;
if (ngx_handle_read_event(rev, (rev->eof || rev->error)) == NGX_ERROR) { flags = (rev->eof || rev->error) ? NGX_CLOSE_EVENT : 0;
if (ngx_handle_read_event(rev, flags) == NGX_ERROR) {
return NGX_ABORT; return NGX_ABORT;
} }
@ -54,12 +57,10 @@ int ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
} }
} }
ngx_log_debug(p->log, "DOWN: %d" _ p->downstream->fd);
if (p->downstream->fd != -1) { if (p->downstream->fd != -1) {
wev = p->downstream->write; wev = p->downstream->write;
wev->available = p->send_lowat;
if (ngx_handle_write_event(wev, p->send_lowat) == NGX_ERROR) { if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
return NGX_ABORT; return NGX_ABORT;
} }

View File

@ -283,8 +283,28 @@ void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p)
p->cache->ctx.file.info_valid = 1; p->cache->ctx.file.info_valid = 1;
} }
if (rc == NGX_AGAIN) { if (rc == NGX_AGAIN) {
if ((ngx_event_flags & (NGX_USE_CLEAR_EVENT|NGX_HAVE_KQUEUE_EVENT))
&& !p->request->connection->write->active)
{
/*
* kqueue allows to detect when client closes prematurely
* connection
*/
p->request->connection->write->event_handler =
ngx_http_proxy_check_broken_connection;
if (ngx_add_event(p->request->connection->write, NGX_WRITE_EVENT,
NGX_CLEAR_EVENT) == NGX_ERROR)
{
ngx_http_proxy_finalize_request(p,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
}
return; return;
} }

View File

@ -338,6 +338,45 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r)
} }
void ngx_http_proxy_check_broken_connection(ngx_event_t *wev)
{
ngx_connection_t *c;
ngx_http_request_t *r;
ngx_http_proxy_ctx_t *p;
ngx_log_debug(wev->log, "http proxy check client");
c = wev->data;
r = c->data;
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
#if (HAVE_KQUEUE)
if (wev->kq_eof) {
wev->eof = 1;
if (wev->kq_errno) {
wev->error = 1;
}
if (!p->cachable && p->upstream->peer.connection) {
ngx_log_error(NGX_LOG_INFO, wev->log, wev->kq_errno,
"client closed prematurely connection, "
"so upstream connection is closed too");
ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
return;
}
ngx_log_error(NGX_LOG_INFO, wev->log, wev->kq_errno,
"client closed prematurely connection");
if (p->upstream == NULL || p->upstream->peer.connection == NULL) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
}
}
#endif
}
void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev) void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev)
{ {
ngx_connection_t *c; ngx_connection_t *c;
@ -351,6 +390,12 @@ void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev)
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module); p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
p->action = "waiting upstream in busy lock"; p->action = "waiting upstream in busy lock";
if (p->request->connection->write->eof) {
ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock);
ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
return;
}
if (rev->timedout) { if (rev->timedout) {
rev->timedout = 0; rev->timedout = 0;
p->busy_lock.time++; p->busy_lock.time++;
@ -369,14 +414,15 @@ void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev)
/* /*
* TODO: kevent() notify about error, otherwise we need to * TODO: kevent() notify about error, otherwise we need to
* call ngx_peek(): recv(MGS_PEEK) to get errno. THINK about aio * call ngx_peek(): recv(MSG_PEEK) to get errno. THINK about aio
* if there's no error we need to disable event. * if there's no error we need to disable event.
*/ */
#if 0
#if (HAVE_KQUEUE) #if (HAVE_KQUEUE)
if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) && rev->kq_eof) { if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) && rev->kq_eof) {
p->lcf->busy_lock->waiting--; ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock);
ngx_del_timer(rev); ngx_del_timer(rev);
@ -388,13 +434,12 @@ void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev)
return; return;
} }
/* we have not HTTP code for the case when a client cancels a request */ ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
ngx_http_proxy_finalize_request(p, 0);
return; return;
} }
#endif #endif
#endif
} }

View File

@ -203,6 +203,8 @@ int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p);
int ngx_http_proxy_is_cachable(ngx_http_proxy_ctx_t *p); int ngx_http_proxy_is_cachable(ngx_http_proxy_ctx_t *p);
int ngx_http_proxy_update_cache(ngx_http_proxy_ctx_t *p); int ngx_http_proxy_update_cache(ngx_http_proxy_ctx_t *p);
void ngx_http_proxy_check_broken_connection(ngx_event_t *wev);
void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev); void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev);
void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p); void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p);
void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p); void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p);

View File

@ -19,7 +19,6 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev);
static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev); static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev);
static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *); static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *);
static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p); static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p);
static void ngx_http_proxy_check_broken_connection(ngx_event_t *wev);
static void ngx_http_proxy_process_body(ngx_event_t *ev); static void ngx_http_proxy_process_body(ngx_event_t *ev);
static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type); static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type);
@ -502,8 +501,8 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
if (rc == NGX_AGAIN) { if (rc == NGX_AGAIN) {
ngx_add_timer(c->write, p->lcf->send_timeout); ngx_add_timer(c->write, p->lcf->send_timeout);
if (ngx_handle_write_event(c->write, /* STUB: lowat */ 0) == NGX_ERROR) c->write->available = /* STUB: lowat */ 0;
{ if (ngx_handle_write_event(c->write, NGX_LOWAT_EVENT) == NGX_ERROR) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
return; return;
} }
@ -526,6 +525,8 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
return; return;
} }
ngx_add_timer(c->read, p->lcf->read_timeout);
#if 0 #if 0
if (c->read->ready) { if (c->read->ready) {
@ -566,9 +567,11 @@ static void ngx_http_proxy_send_request_handler(ngx_event_t *wev)
return; return;
} }
if (p->request->connection->write->eof) { if (p->request->connection->write->eof
ngx_http_proxy_close_connection(p); && (!p->cachable || !p->request_sent))
ngx_http_close_connection(p->request->connection); {
ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
return;
} }
ngx_http_proxy_send_request(p); ngx_http_proxy_send_request(p);
@ -868,7 +871,9 @@ static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p)
p->header_in->end - p->header_in->last); p->header_in->end - p->header_in->last);
if (n == NGX_AGAIN) { if (n == NGX_AGAIN) {
#if 0
ngx_add_timer(rev, p->lcf->read_timeout); ngx_add_timer(rev, p->lcf->read_timeout);
#endif
if (ngx_handle_read_event(rev, 0) == NGX_ERROR) { if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
@ -1042,45 +1047,6 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
} }
static void ngx_http_proxy_check_broken_connection(ngx_event_t *wev)
{
ngx_connection_t *c;
ngx_http_request_t *r;
ngx_http_proxy_ctx_t *p;
ngx_log_debug(wev->log, "http proxy check client");
c = wev->data;
r = c->data;
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
#if (HAVE_KQUEUE)
if (wev->kq_eof) {
wev->eof = 1;
if (wev->kq_errno) {
wev->error = 1;
}
if (!p->cachable && p->upstream->peer.connection) {
ngx_log_error(NGX_LOG_INFO, wev->log, wev->kq_errno,
"client closed prematurely connection, "
"so upstream connection is closed too");
ngx_http_proxy_close_connection(p);
} else {
ngx_log_error(NGX_LOG_INFO, wev->log, wev->kq_errno,
"client closed prematurely connection");
}
if (p->upstream->peer.connection == NULL) {
ngx_http_close_connection(c);
}
}
#endif
}
static void ngx_http_proxy_process_body(ngx_event_t *ev) static void ngx_http_proxy_process_body(ngx_event_t *ev)
{ {
ngx_connection_t *c; ngx_connection_t *c;
@ -1215,6 +1181,11 @@ ngx_log_debug(p->request->connection->log, "next upstream: %d" _ ft_type);
ngx_http_proxy_close_connection(p); ngx_http_proxy_close_connection(p);
} }
if (p->request->connection->write->eof) {
ngx_http_proxy_finalize_request(p, status ? status:
NGX_HTTP_CLIENT_CLOSED_REQUEST);
}
if (status) { if (status) {
p->state->status = status; p->state->status = status;

View File

@ -103,6 +103,10 @@ ngx_log_debug(bc->event->log, "BUSYLOCK: %d" _ rc);
void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl, void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc) ngx_http_busy_lock_ctx_t *bc)
{ {
if (bl == NULL) {
return;
}
if (bl->md5) { if (bl->md5) {
bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7)); bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
bl->cachable--; bl->cachable--;

View File

@ -107,6 +107,13 @@ int ngx_http_cache_open_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
ctx->date = h->date; ctx->date = h->date;
ctx->length = h->length; ctx->length = h->length;
if (h->key_len > (size_t) (ctx->buf->last - ctx->buf->pos)) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"cache file \"%s\" is probably invalid",
ctx->file.name.data);
return NGX_DECLINED;
}
if (h->key_len != ctx->key.len if (h->key_len != ctx->key.len
|| ngx_strncmp(h->key, ctx->key.data, h->key_len) != 0) || ngx_strncmp(h->key, ctx->key.data, h->key_len) != 0)
{ {

View File

@ -664,6 +664,10 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
return n; return n;
} }
if (!rev->ready) {
return NGX_AGAIN;
}
n = ngx_recv(r->connection, r->header_in->last, n = ngx_recv(r->connection, r->header_in->last,
r->header_in->end - r->header_in->last); r->header_in->end - r->header_in->last);
@ -853,7 +857,8 @@ static void ngx_http_set_write_handler(ngx_http_request_t *r)
ngx_http_core_module); ngx_http_core_module);
ngx_add_timer(wev, clcf->send_timeout); ngx_add_timer(wev, clcf->send_timeout);
if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) { wev->available = clcf->send_lowat;
if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
ngx_http_close_request(r, 0); ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection); ngx_http_close_connection(r->connection);
} }

View File

@ -49,6 +49,12 @@
#define NGX_HTTP_REQUEST_URI_TOO_LARGE 414 #define NGX_HTTP_REQUEST_URI_TOO_LARGE 414
#define NGX_HTTP_RANGE_NOT_SATISFIABLE 416 #define NGX_HTTP_RANGE_NOT_SATISFIABLE 416
/*
* HTTP does not define a code for the case when a client closed a connection
* while we are processing request so we introduce own code to log this case
*/
#define NGX_HTTP_CLIENT_CLOSED_REQUEST 420
#define NGX_HTTP_INTERNAL_SERVER_ERROR 500 #define NGX_HTTP_INTERNAL_SERVER_ERROR 500
#define NGX_HTTP_NOT_IMPLEMENTED 501 #define NGX_HTTP_NOT_IMPLEMENTED 501
#define NGX_HTTP_BAD_GATEWAY 502 #define NGX_HTTP_BAD_GATEWAY 502

View File

@ -33,11 +33,13 @@ typedef u_int32_t uintptr_t;
#endif #endif
/* TODO: autoconf ??? */
#if __FreeBSD_version < 330002 /* exactly */ #if __FreeBSD_version < 330002 /* exactly */
typedef uint32_t socklen_t; typedef uint32_t socklen_t;
#endif #endif
/* TODO: autoconf */
#if (i386) #if (i386)
#define OFF_FMT "%lld" #define OFF_FMT "%lld"
@ -52,7 +54,7 @@ typedef uint32_t socklen_t;
#endif #endif
#define TIME_FMT "%lu" #define TIME_FMT "%ld"
#define PID_FMT "%d" #define PID_FMT "%d"
#define RLIM_FMT "%lld" #define RLIM_FMT "%lld"
@ -91,8 +93,8 @@ typedef uint32_t socklen_t;
/* STUB */ /* STUB */
#define HAVE_PREAD 1 #define HAVE_PREAD 0
#define HAVE_PWRITE 1 #define HAVE_PWRITE 0
#define HAVE_LOCALTIME_R 1 #define HAVE_LOCALTIME_R 1

View File

@ -34,7 +34,7 @@
#define OFF_FMT "%lld" #define OFF_FMT "%lld"
#define SIZE_FMT "%d" #define SIZE_FMT "%d"
#define SIZEX_FMT "%x" #define SIZEX_FMT "%x"
#define TIME_FMT "%lu" #define TIME_FMT "%ld"
#define PID_FMT "%d" #define PID_FMT "%d"
#define RLIM_FMT "%lu" #define RLIM_FMT "%lu"

View File

@ -33,7 +33,7 @@ typedef uint32_t u_int32_t;
#define OFF_FMT "%lld" #define OFF_FMT "%lld"
#define SIZE_FMT "%d" #define SIZE_FMT "%d"
#define SIZEX_FMT "%x" #define SIZEX_FMT "%x"
#define TIME_FMT "%lu" #define TIME_FMT "%ld"
#define PID_FMT "%ld" #define PID_FMT "%ld"
#define RLIM_FMT "%lu" #define RLIM_FMT "%lu"