From: Stephan Bosch Date: Thu, 20 May 2021 21:54:24 +0000 (+0200) Subject: lib-http: http-client-connection - Move handling of 100 response to http-client-request X-Git-Tag: 2.4.1~70 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9729414544cd0ebc2f48b3e8e6508b886d20510;p=thirdparty%2Fdovecot%2Fcore.git lib-http: http-client-connection - Move handling of 100 response to http-client-request --- diff --git a/src/lib-http/http-client-connection.c b/src/lib-http/http-client-connection.c index 4f860625eb..41d4d01d01 100644 --- a/src/lib-http/http-client-connection.c +++ b/src/lib-http/http-client-connection.c @@ -1009,7 +1009,6 @@ http_client_connection_process_response(struct http_client_connection *conn, struct http_client_request *req, struct http_response *resp) { - struct http_client_peer_shared *pshared = conn->ppool->peer; struct http_client_request *req_ref; bool aborted, early = FALSE; @@ -1040,42 +1039,8 @@ http_client_connection_process_response(struct http_client_connection *conn, /* Got some response; cancel response timeout */ timeout_remove(&conn->to_response); - /* RFC 7231, Section 6.2: - - A client MUST be able to parse one or more 1xx responses received - prior to a final response, even if the client does not expect one. - A user agent MAY ignore unexpected 1xx responses. - */ - if (req->payload_sync && resp->status == 100) { - if (req->payload_sync_continue) { - e_debug(conn->event, - "Got 100-continue response after timeout"); - return 0; - } - - pshared->no_payload_sync = FALSE; - pshared->seen_100_response = TRUE; - req->payload_sync_continue = TRUE; - - e_debug(conn->event, - "Got expected 100-continue response"); - - if (req->state == HTTP_REQUEST_STATE_ABORTED) { - e_debug(conn->event, - "Request aborted before sending payload was complete."); - http_client_connection_close(&conn); - return -1; - } - - if (conn->conn.output != NULL) - o_stream_set_flush_pending(conn->conn.output, TRUE); - return -1; - } else if (resp->status / 100 == 1) { - /* Ignore other 1xx for now */ - e_debug(conn->event, - "Got unexpected %u response; ignoring", - resp->status); - return 0; + if (resp->status / 100 == 1) { + return http_client_request_1xx_response(req, resp); } else if ((!req->payload_sync || req->payload_sync_continue) && !req->payload_finished && req->state == HTTP_REQUEST_STATE_PAYLOAD_OUT) { diff --git a/src/lib-http/http-client-private.h b/src/lib-http/http-client-private.h index db9829445a..d83bea5ce7 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -501,6 +501,8 @@ int http_client_request_send(struct http_client_request *req, bool pipelined); int http_client_request_send_more(struct http_client_request *req, bool pipelined); +int http_client_request_1xx_response(struct http_client_request *req, + struct http_response *resp); bool http_client_request_callback(struct http_client_request *req, struct http_response *response); void http_client_request_connect_callback( diff --git a/src/lib-http/http-client-request.c b/src/lib-http/http-client-request.c index d640978c50..b78134899c 100644 --- a/src/lib-http/http-client-request.c +++ b/src/lib-http/http-client-request.c @@ -1561,6 +1561,52 @@ int http_client_request_send(struct http_client_request *req, bool pipelined) return ret; } +int http_client_request_1xx_response(struct http_client_request *req, + struct http_response *resp) +{ + struct http_client_connection *conn = req->conn; + + /* RFC 7231, Section 6.2: + + A client MUST be able to parse one or more 1xx responses received + prior to a final response, even if the client does not expect one. + A user agent MAY ignore unexpected 1xx responses. + */ + + if (req->payload_sync && resp->status == 100) { + struct http_client_peer_shared *pshared = conn->ppool->peer; + + if (req->payload_sync_continue) { + e_debug(req->event, + "Got 100-continue response after timeout"); + return 0; + } + + pshared->no_payload_sync = FALSE; + pshared->seen_100_response = TRUE; + req->payload_sync_continue = TRUE; + + e_debug(req->event, + "Got expected 100-continue response"); + + if (req->state == HTTP_REQUEST_STATE_ABORTED) { + e_debug(req->event, + "Request aborted before sending payload was complete."); + http_client_connection_close(&conn); + return -1; + } + + if (conn->conn.output != NULL) + o_stream_set_flush_pending(conn->conn.output, TRUE); + return -1; + } + + /* Ignore other 1xx for now */ + e_debug(req->event, + "Got unexpected %u response; ignoring", resp->status); + return 0; +} + bool http_client_request_callback(struct http_client_request *req, struct http_response *response) {