diff --git a/src/lib/proxy.c b/src/lib/proxy.c index 3876e7a..6d480b8 100644 --- a/src/lib/proxy.c +++ b/src/lib/proxy.c @@ -139,9 +139,10 @@ proxy_ctx_t *proxy_get_by_conf(host_config_t *conf) { void proxy_unlock_ctx(proxy_ctx_t *ctx) { int n = (int) ((ctx - proxies) / MAX_PROXY_CNX_PER_HOST); + int was_in_use = ctx->in_use; ctx->in_use = 0; ctx->client = NULL; - sem_post(&available[n]); + if (was_in_use) sem_post(&available[n]); } int proxy_request_header(http_req *req, sock *sock) { @@ -340,6 +341,7 @@ static int proxy_connect(proxy_ctx_t *proxy, host_config_t *conf, http_res *res, if ((ret = SSL_do_handshake(proxy->proxy.ssl)) != 1) { sock_error(&proxy->proxy, (int) ret); SSL_free(proxy->proxy.ssl); + proxy->proxy.ssl = NULL; res->status = http_get_status(502); ctx->origin = SERVER_REQ; error("Unable to perform handshake"); diff --git a/src/worker/proxy_handler.c b/src/worker/proxy_handler.c index 79f6883..b136e92 100644 --- a/src/worker/proxy_handler.c +++ b/src/worker/proxy_handler.c @@ -28,22 +28,22 @@ void proxy_handler_func(client_ctx_t *ctx) { if (ret == 1) { proxy_unlock_ctx(ctx->proxy); - ctx->proxy = NULL; } else if (ctx->use_proxy == 0) { proxy_close(ctx->proxy); + proxy_unlock_ctx(ctx->proxy); } else if (ctx->use_proxy == 1) { if (proxy_handler_2(ctx) == 1) { // chunked return; } proxy_unlock_ctx(ctx->proxy); - ctx->proxy = NULL; } else if (ctx->use_proxy == 2) { // WebSocket ws_handle_connection(ctx); return; } + ctx->proxy = NULL; request_complete(ctx); handle_request(ctx); } @@ -61,6 +61,9 @@ static int proxy_handler_1(client_ctx_t *ctx) { ctx->use_proxy = proxy_init(&ctx->proxy, &ctx->req, res, status, ctx->conf, &ctx->socket, &ctx->custom_status, ctx->err_msg) == 0; ctx->proxy->client = ctx; + if (ctx->use_proxy == 0) + return 0; + if (res->status->code == 101) { const char *connection = http_get_header_field(&res->hdr, "Connection"); const char *upgrade = http_get_header_field(&res->hdr, "Upgrade"); @@ -110,15 +113,20 @@ static int proxy_handler_1(client_ctx_t *ctx) { static void proxy_chunk_next_cb(chunk_ctx_t *ctx) { proxy_unlock_ctx(ctx->client->proxy); - ctx->client->proxy = NULL; + ctx->client->proxy = NULL; request_complete(ctx->client); handle_request(ctx->client); } static void proxy_chunk_err_cb(chunk_ctx_t *ctx) { ctx->client->c_keep_alive = 0; - proxy_chunk_next_cb(ctx); + proxy_close(ctx->client->proxy); + proxy_unlock_ctx(ctx->client->proxy); + + ctx->client->proxy = NULL; + request_complete(ctx->client); + handle_request(ctx->client); } static int proxy_handler_2(client_ctx_t *ctx) {