Mercurial > dovecot > original-hg > dovecot-2.2
changeset 16740:adb4d013073d
lib-http: Adjusted response and request parsers to accept a request/response object to fill with data, rather than have it return one.
author | Stephan Bosch <stephan@rename-it.nl> |
---|---|
date | Sun, 15 Sep 2013 03:36:18 +0300 |
parents | a6ed95a30cb1 |
children | b172c130df9b |
files | src/lib-http/http-client-connection.c src/lib-http/http-request-parser.c src/lib-http/http-request-parser.h src/lib-http/http-response-parser.c src/lib-http/http-response-parser.h src/lib-http/test-http-response-parser.c src/lib-http/test-http-server.c |
diffstat | 7 files changed, 62 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-http/http-client-connection.c Sun Sep 15 03:35:04 2013 +0300 +++ b/src/lib-http/http-client-connection.c Sun Sep 15 03:36:18 2013 +0300 @@ -488,7 +488,7 @@ { struct http_client_connection *conn = (struct http_client_connection *)_conn; - struct http_response *response; + struct http_response response; struct http_client_request *const *req_idx; struct http_client_request *req = NULL; int finished = 0, ret; @@ -547,7 +547,7 @@ (Continue) status message. Unexpected 1xx status responses MAY be ignored by a user agent. */ - if (req->payload_sync && response->status == 100) { + if (req->payload_sync && response.status == 100) { if (conn->payload_continue) { http_client_connection_debug(conn, "Got 100-continue response after timeout"); @@ -564,16 +564,16 @@ t_strdup_printf("Failed to send request: %s", error)); } return; - } else if (response->status / 100 == 1) { + } else if (response.status / 100 == 1) { /* ignore them for now */ http_client_connection_debug(conn, - "Got unexpected %u response; ignoring", response->status); + "Got unexpected %u response; ignoring", response.status); continue; } http_client_connection_debug(conn, "Got %u response for request %s", - response->status, http_client_request_label(req)); + response.status, http_client_request_label(req)); /* remove request from queue */ array_delete(&conn->request_wait_list, 0, 1); @@ -581,25 +581,25 @@ i_assert(req->refcount > 1 || aborted); http_client_request_unref(&req); - conn->close_indicated = response->connection_close; + conn->close_indicated = response.connection_close; if (req->payload_sync && !conn->payload_continue) conn->output_locked = FALSE; if (!aborted) { - if (response->status == 417 && req->payload_sync) { + if (response.status == 417 && req->payload_sync) { /* drop Expect: continue */ req->payload_sync = FALSE; conn->output_locked = FALSE; conn->peer->no_payload_sync = TRUE; - http_client_request_retry(req, response->status, response->reason); + http_client_request_retry(req, response.status, response.reason); - } else if (response->status / 100 == 3 && response->status != 304 && - response->location != NULL) { + } else if (response.status / 100 == 3 && response.status != 304 && + response.location != NULL) { /* redirect */ - http_client_request_redirect(req, response->status, response->location); + http_client_request_redirect(req, response.status, response.location); } else { /* response for application */ - if (!http_client_connection_return_response(conn, req, response)) + if (!http_client_connection_return_response(conn, req, &response)) return; }
--- a/src/lib-http/http-request-parser.c Sun Sep 15 03:35:04 2013 +0300 +++ b/src/lib-http/http-request-parser.c Sun Sep 15 03:36:18 2013 +0300 @@ -23,7 +23,8 @@ struct http_message_parser parser; enum http_request_parser_state state; - struct http_request request; + const char *request_method; + const char *request_target; unsigned int skipping_line:1; }; @@ -49,7 +50,8 @@ http_request_parser_restart(struct http_request_parser *parser) { http_message_parser_restart(&parser->parser); - memset(&parser->request, 0, sizeof(parser->request)); + parser->request_method = NULL; + parser->request_target = NULL; } static int http_request_parse_method(struct http_request_parser *parser) @@ -63,7 +65,7 @@ if (p == parser->parser.end) return 0; - parser->request.method = + parser->request_method = p_strdup_until(parser->parser.msg_pool, parser->parser.cur, p); parser->parser.cur = p; return 1; @@ -82,7 +84,7 @@ if (p == parser->parser.end) return 0; - parser->request.target = + parser->request_target = p_strdup_until(parser->parser.msg_pool, parser->parser.cur, p); parser->parser.cur = p; return 1; @@ -246,7 +248,7 @@ } int http_request_parse_next(struct http_request_parser *parser, - struct http_request **request_r, + struct http_request *request, const char **error_r) { int ret; @@ -271,13 +273,14 @@ return -1; parser->state = HTTP_REQUEST_PARSE_STATE_INIT; - parser->request.version_major = parser->parser.msg.version_major; - parser->request.version_minor = parser->parser.msg.version_minor; - parser->request.date = parser->parser.msg.date; - parser->request.payload = parser->parser.payload; - parser->request.headers = parser->parser.msg.headers; - parser->request.connection_close = parser->parser.msg.connection_close; - - *request_r = &parser->request; + memset(request, 0, sizeof(*request)); + request->method = parser->request_method; + request->target = parser->request_target; + request->version_major = parser->parser.msg.version_major; + request->version_minor = parser->parser.msg.version_minor; + request->date = parser->parser.msg.date; + request->payload = parser->parser.payload; + request->headers = parser->parser.msg.headers; + request->connection_close = parser->parser.msg.connection_close; return 1; }
--- a/src/lib-http/http-request-parser.h Sun Sep 15 03:35:04 2013 +0300 +++ b/src/lib-http/http-request-parser.h Sun Sep 15 03:36:18 2013 +0300 @@ -23,7 +23,7 @@ void http_request_parser_deinit(struct http_request_parser **_parser); int http_request_parse_next(struct http_request_parser *parser, - struct http_request **request_r, + struct http_request *request, const char **error_r); #endif
--- a/src/lib-http/http-response-parser.c Sun Sep 15 03:35:04 2013 +0300 +++ b/src/lib-http/http-response-parser.c Sun Sep 15 03:36:18 2013 +0300 @@ -24,7 +24,8 @@ struct http_message_parser parser; enum http_response_parser_state state; - struct http_response response; + unsigned int response_status; + const char *response_reason; }; struct http_response_parser *http_response_parser_init(struct istream *input) @@ -48,7 +49,8 @@ http_response_parser_restart(struct http_response_parser *parser) { http_message_parser_restart(&parser->parser); - memset(&parser->response, 0, sizeof(parser->response)); + parser->response_status = 0; + parser->response_reason = NULL; } static int http_response_parse_status(struct http_response_parser *parser) @@ -62,7 +64,7 @@ return 0; if (!i_isdigit(p[0]) || !i_isdigit(p[1]) || !i_isdigit(p[2])) return -1; - parser->response.status = + parser->response_status = (p[0] - '0')*100 + (p[1] - '0')*10 + (p[2] - '0'); parser->parser.cur += 3; return 1; @@ -74,12 +76,13 @@ /* reason-phrase = *( HTAB / SP / VCHAR / obs-text ) */ + // FIXME: limit length while (p < parser->parser.end && http_char_is_text(*p)) p++; if (p == parser->parser.end) return 0; - parser->response.reason = + parser->response_reason = p_strdup_until(parser->parser.msg_pool, parser->parser.cur, p); parser->parser.cur = p; return 1; @@ -223,7 +226,7 @@ } int http_response_parse_next(struct http_response_parser *parser, - bool no_payload, struct http_response **response_r, + bool no_payload, struct http_response *response, const char **error_r) { int ret; @@ -251,11 +254,11 @@ A server MUST NOT send a Content-Length header field in any response with a status code of 1xx (Informational) or 204 (No Content). [...] */ - if ((parser->response.status / 100 == 1 || parser->response.status == 204) && + if ((parser->response_status / 100 == 1 || parser->response_status == 204) && parser->parser.msg.content_length > 0) { *error_r = t_strdup_printf( "Unexpected Content-Length header field for %u response " - "(length=%"PRIuUOFF_T")", parser->response.status, + "(length=%"PRIuUOFF_T")", parser->response_status, parser->parser.msg.content_length); return -1; } @@ -269,8 +272,8 @@ header fields, regardless of the header fields present in the message, and thus cannot contain a message body. */ - if (parser->response.status / 100 == 1 || parser->response.status == 204 - || parser->response.status == 304) { // HEAD is handled in caller + if (parser->response_status / 100 == 1 || parser->response_status == 204 + || parser->response_status == 304) { // HEAD is handled in caller no_payload = TRUE; } @@ -281,14 +284,15 @@ } parser->state = HTTP_RESPONSE_PARSE_STATE_INIT; - parser->response.version_major = parser->parser.msg.version_major; - parser->response.version_minor = parser->parser.msg.version_minor; - parser->response.location = parser->parser.msg.location; - parser->response.date = parser->parser.msg.date; - parser->response.payload = parser->parser.payload; - parser->response.headers = parser->parser.msg.headers; - parser->response.connection_close = parser->parser.msg.connection_close; - - *response_r = &parser->response; + memset(response, 0, sizeof(*response)); + response->status = parser->response_status; + response->reason = parser->response_reason; + response->version_major = parser->parser.msg.version_major; + response->version_minor = parser->parser.msg.version_minor; + response->location = parser->parser.msg.location; + response->date = parser->parser.msg.date; + response->payload = parser->parser.payload; + response->headers = parser->parser.msg.headers; + response->connection_close = parser->parser.msg.connection_close; return 1; }
--- a/src/lib-http/http-response-parser.h Sun Sep 15 03:35:04 2013 +0300 +++ b/src/lib-http/http-response-parser.h Sun Sep 15 03:36:18 2013 +0300 @@ -10,7 +10,7 @@ void http_response_parser_deinit(struct http_response_parser **_parser); int http_response_parse_next(struct http_response_parser *parser, - bool no_payload, struct http_response **response_r, + bool no_payload, struct http_response *response, const char **error_r); #endif
--- a/src/lib-http/test-http-response-parser.c Sun Sep 15 03:35:04 2013 +0300 +++ b/src/lib-http/test-http-response-parser.c Sun Sep 15 03:36:18 2013 +0300 @@ -99,7 +99,7 @@ struct ostream *output; const struct http_response_parse_test *test; struct http_response_parser *parser; - struct http_response *response = NULL; + struct http_response response; const char *response_text, *payload, *error; unsigned int pos, response_text_len; int ret = 0; @@ -119,11 +119,11 @@ } test_istream_set_size(input, response_text_len); while (ret > 0) { - if (response->payload != NULL) { + if (response.payload != NULL) { buffer_set_used_size(payload_buffer, 0); output = o_stream_create_buffer(payload_buffer); test_out("payload receive", - o_stream_send_istream(output, response->payload)); + o_stream_send_istream(output, response.payload)); o_stream_destroy(&output); payload = str_c(payload_buffer); } else { @@ -136,9 +136,8 @@ if (ret == 0) { /* verify last response only */ - i_assert(response != NULL); test_out(t_strdup_printf("response->status = %d",test->status), - response->status == test->status); + response.status == test->status); if (payload == NULL || test->payload == NULL) { test_out(t_strdup_printf("response->payload = %s", str_sanitize(payload, 80)), @@ -185,7 +184,7 @@ static void test_http_response_parse_invalid(void) { struct http_response_parser *parser; - struct http_response *response; + struct http_response response; const char *response_text, *error; struct istream *input; int ret;
--- a/src/lib-http/test-http-server.c Sun Sep 15 03:35:04 2013 +0300 +++ b/src/lib-http/test-http-server.c Sun Sep 15 03:36:18 2013 +0300 @@ -48,13 +48,14 @@ static void client_input(struct connection *conn) { struct client *client = (struct client *)conn; - struct http_request *request; + struct http_request request; const char *error; int ret; - while ((ret = http_request_parse_next(client->parser, &request, &error)) > 0) { - if (client_handle_request(client, request) < 0 || - request->connection_close) { + while ((ret = http_request_parse_next + (client->parser, &request, &error)) > 0) { + if (client_handle_request(client, &request) < 0 || + request.connection_close) { client_destroy(conn); return; }