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 ((flags & EV_ADD) && ev->lowat > 0) {
if (flags & NGX_LOWAT_EVENT) {
change_list[nchanges].fflags = NOTE_LOWAT;
change_list[nchanges].data = ev->lowat;
change_list[nchanges].data = ev->available;
} else {
change_list[nchanges].fflags = 0;

View File

@ -45,13 +45,20 @@ struct ngx_event_s {
/*
* kqueue only:
* accept: number of sockets that wait to be accepted
* read: bytes to read
* write: available space in buffer
* read: bytes to read when event is ready
* 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:
* accept: 1 if accept many, 0 otherwise
*/
#if (HAVE_KQUEUE)
int available;
#else
unsigned available:1;
#endif
unsigned oneshot:1;
@ -104,10 +111,6 @@ struct ngx_event_s {
int kq_errno;
#endif
#if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */
int lowat;
#endif
#if (HAVE_AIO)
@ -227,19 +230,27 @@ extern ngx_event_actions_t ngx_event_actions;
#define NGX_CLOSE_EVENT 1
/* this flag has meaning only for kqueue */
#define NGX_LOWAT_EVENT 0
#if (HAVE_KQUEUE)
#define NGX_READ_EVENT EVFILT_READ
#define NGX_WRITE_EVENT EVFILT_WRITE
/*
* NGX_CLOSE_EVENT is the module flag and it would not go into a kernel
* so we need to choose the value that would not interfere with any existent
* and future flags. kqueue has such values - EV_FLAG1, EV_EOF and EV_ERROR.
* They are reserved and cleared on a kernel entrance.
* NGX_CLOSE_EVENT and NGX_LOWAT_EVENT are the module flags and they would
* not go into a kernel so we need to choose the value that would not interfere
* with any existent and future kqueue flags. kqueue has such values -
* EV_FLAG1, EV_EOF and EV_ERROR. They are reserved and cleared on a kernel
* entrance.
*/
#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_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) {
@ -380,10 +391,8 @@ ngx_inline static int ngx_handle_read_event(ngx_event_t *rev, int close)
return NGX_OK;
}
if (rev->active && (rev->ready || close)) {
if (ngx_del_event(rev, NGX_READ_EVENT, close ? NGX_CLOSE_EVENT : 0)
== NGX_ERROR)
{
if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
if (ngx_del_event(rev, NGX_READ_EVENT, flags) == 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) {
/* 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 (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT)
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT|flags)
== 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;
}
ngx_log_debug(pc->log, "CONNECTED");
wev->ready = 1;
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 flags;
ngx_event_t *rev, *wev;
for ( ;; ) {
@ -45,7 +46,9 @@ int ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
if (p->upstream->fd != -1) {
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;
}
@ -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) {
wev = p->downstream->write;
if (ngx_handle_write_event(wev, p->send_lowat) == NGX_ERROR) {
wev->available = p->send_lowat;
if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
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;
}
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;
}

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)
{
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->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) {
rev->timedout = 0;
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
* 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 0
#if (HAVE_KQUEUE)
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);
@ -388,13 +434,12 @@ void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev)
return;
}
/* we have not HTTP code for the case when a client cancels a request */
ngx_http_proxy_finalize_request(p, 0);
ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
return;
}
#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_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_cache_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 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_check_broken_connection(ngx_event_t *wev);
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);
@ -502,8 +501,8 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
if (rc == NGX_AGAIN) {
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);
return;
}
@ -526,6 +525,8 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
return;
}
ngx_add_timer(c->read, p->lcf->read_timeout);
#if 0
if (c->read->ready) {
@ -566,9 +567,11 @@ static void ngx_http_proxy_send_request_handler(ngx_event_t *wev)
return;
}
if (p->request->connection->write->eof) {
ngx_http_proxy_close_connection(p);
ngx_http_close_connection(p->request->connection);
if (p->request->connection->write->eof
&& (!p->cachable || !p->request_sent))
{
ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
return;
}
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);
if (n == NGX_AGAIN) {
#if 0
ngx_add_timer(rev, p->lcf->read_timeout);
#endif
if (ngx_handle_read_event(rev, 0) == NGX_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)
{
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);
}
if (p->request->connection->write->eof) {
ngx_http_proxy_finalize_request(p, status ? status:
NGX_HTTP_CLIENT_CLOSED_REQUEST);
}
if (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,
ngx_http_busy_lock_ctx_t *bc)
{
if (bl == NULL) {
return;
}
if (bl->md5) {
bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
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->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
|| 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;
}
if (!rev->ready) {
return NGX_AGAIN;
}
n = ngx_recv(r->connection, 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_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_connection(r->connection);
}

View File

@ -49,6 +49,12 @@
#define NGX_HTTP_REQUEST_URI_TOO_LARGE 414
#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_NOT_IMPLEMENTED 501
#define NGX_HTTP_BAD_GATEWAY 502

View File

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

View File

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

View File

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