Mercurial > hg > nginx-quic
diff src/http/modules/proxy/ngx_http_proxy_upstream.c @ 176:c0552e5ab567
nginx-0.0.1-2003-11-09-23:03:38 import; separate building
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 09 Nov 2003 20:03:38 +0000 |
parents | e92c2c647c57 |
children | 4db54fdbcbe7 |
line wrap: on
line diff
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -11,8 +11,6 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p); static void ngx_http_proxy_init_upstream(void *data); static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p); -static void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p); -static void ngx_http_proxy_upstream_busy_lock_handler(ngx_event_t *rev); static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p); static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p); static void ngx_http_proxy_send_request_handler(ngx_event_t *wev); @@ -266,7 +264,7 @@ ngx_log_debug(r->connection->log, "timer wctx->pool = r->pool; - if (p->lcf->busy_lock) { + if (p->lcf->busy_lock && !p->busy_locked) { ngx_http_proxy_upstream_busy_lock(p); } else { ngx_http_proxy_connect(p); @@ -312,41 +310,31 @@ static void ngx_http_proxy_reinit_upstre } -static 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) { - int ft_type; + int rc, ft_type; - if (p->lcf->busy_lock->conn_n < p->lcf->busy_lock->max_conn) { - p->lcf->busy_lock->conn_n++; + if (p->busy_lock.time == 0) { + p->busy_lock.event = p->request->connection->read; + p->busy_lock.event_handler = ngx_http_proxy_busy_lock_handler; + } - if (p->busy_lock_time) { - p->busy_lock_time = 0; - p->lcf->busy_lock->waiting_n--; - } + rc = ngx_http_busy_lock(p->lcf->busy_lock, &p->busy_lock); + if (rc == NGX_AGAIN) { + return; + } + + if (rc == NGX_OK) { ngx_http_proxy_connect(p); return; } - if (p->busy_lock_time) { - if (p->busy_lock_time < p->lcf->busy_lock->timeout) { - ngx_add_timer(p->request->connection->read, 1000); - return; - } - - p->lcf->busy_lock->waiting_n--; + if (rc == NGX_DONE) { ft_type = NGX_HTTP_PROXY_FT_BUSY_LOCK; } else { - if (p->lcf->busy_lock->waiting_n < p->lcf->busy_lock->max_waiting) { - p->lcf->busy_lock->waiting_n++; - ngx_add_timer(p->request->connection->read, 1000); - p->request->connection->read->event_handler = - ngx_http_proxy_upstream_busy_lock_handler; - /* TODO: ngx_handle_level_read_event() */ - return; - } - + /* rc == NGX_ERROR */ ft_type = NGX_HTTP_PROXY_FT_MAX_WAITING; } @@ -357,61 +345,6 @@ static void ngx_http_proxy_upstream_busy } ngx_http_proxy_finalize_request(p, NGX_HTTP_SERVICE_UNAVAILABLE); - return; -} - - -static void ngx_http_proxy_upstream_busy_lock_handler(ngx_event_t *rev) -{ - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_proxy_ctx_t *p; - - ngx_log_debug(rev->log, "busy lock"); - - c = rev->data; - r = c->data; - p = ngx_http_get_module_ctx(r, ngx_http_proxy_module); - p->action = "waiting upstream in busy lock"; - - if (rev->timedout) { - rev->timedout = 0; - p->busy_lock_time++; - ngx_http_proxy_upstream_busy_lock(p); - return; - } - - ngx_log_debug(rev->log, "client sent while busy lock"); - - /* - * TODO: kevent() notify about error, otherwise we need to - * call ngx_peek(): recv(MGS_PEEK) to get errno. THINK about aio - * if there's no error we need to disable event. - */ - -#if (HAVE_KQUEUE) - - if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) && rev->kq_eof) { - p->lcf->busy_lock->waiting_n--; - - ngx_del_timer(rev); - - ngx_log_error(NGX_LOG_ERR, c->log, rev->kq_errno, - "client() closed connection"); - - if (ngx_del_event(rev, NGX_READ_EVENT, NGX_CLOSE_EVENT) == NGX_ERROR) { - ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - - /* we have not HTTP code for the case when a client cancels a request */ - - ngx_http_proxy_finalize_request(p, 0); - return; - } - -#endif - } @@ -724,6 +657,16 @@ static void ngx_http_proxy_process_upstr } } + if (p->status == NGX_HTTP_NOT_FOUND + && p->upstream->peer.tries > 1 + && p->lcf->next_upstream & NGX_HTTP_PROXY_FT_HTTP_404) + { + ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_HTTP_404); + return; + } + + /* TODO: "proxy_error_page" */ + p->upstream->status_line.len = p->status_end - p->status_start; p->upstream->status_line.data = ngx_palloc(p->request->pool, p->upstream->status_line.len + 1); @@ -740,6 +683,7 @@ static void ngx_http_proxy_process_upstr if (p->upstream->headers_in.headers) { p->upstream->headers_in.headers->nelts = 0; } else { + /* TODO: ngx_init_table */ p->upstream->headers_in.headers = ngx_create_table(p->request->pool, 20); } @@ -956,8 +900,8 @@ static void ngx_http_proxy_send_response header->expires = p->cache->ctx.expires; header->last_modified = p->cache->ctx.last_modified; header->date = p->cache->ctx.date; - /* TODO: r->headers_out.content_length_n == -1 */ header->length = r->headers_out.content_length_n; + p->cache->ctx.length = r->headers_out.content_length_n; header->key_len = p->cache->ctx.key.len; ngx_memcpy(&header->key, p->cache->ctx.key.data, header->key_len); @@ -1105,18 +1049,24 @@ static void ngx_http_proxy_process_body( if (p->upstream->peer.connection) { if (ep->upstream_done && p->cachable) { if (ngx_http_proxy_update_cache(p) == NGX_ERROR) { + ngx_http_busy_unlock_cachable(p->lcf->busy_lock, &p->busy_lock); ngx_http_proxy_finalize_request(p, 0); return; } + ngx_http_busy_unlock_cachable(p->lcf->busy_lock, &p->busy_lock); + } else if (ep->upstream_eof && p->cachable) { /* TODO: check length & update cache */ if (ngx_http_proxy_update_cache(p) == NGX_ERROR) { + ngx_http_busy_unlock_cachable(p->lcf->busy_lock, &p->busy_lock); ngx_http_proxy_finalize_request(p, 0); return; } + + ngx_http_busy_unlock_cachable(p->lcf->busy_lock, &p->busy_lock); } if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) { @@ -1206,7 +1156,7 @@ ngx_log_debug(p->request->connection->lo } } - if (p->lcf->busy_lock) { + if (p->lcf->busy_lock && !p->busy_locked) { ngx_http_proxy_upstream_busy_lock(p); } else { ngx_http_proxy_connect(p);