dovecot-2.2: lib-http: Adjusted response and request parsers to ...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Sep 15 03:38:25 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/adb4d013073d
changeset: 16740:adb4d013073d
user: Stephan Bosch <stephan at rename-it.nl>
date: Sun Sep 15 03:36:18 2013 +0300
description:
lib-http: Adjusted response and request parsers to accept a request/response object to fill with data, rather than have it return one.
diffstat:
src/lib-http/http-client-connection.c | 24 +++++++++---------
src/lib-http/http-request-parser.c | 29 ++++++++++++----------
src/lib-http/http-request-parser.h | 2 +-
src/lib-http/http-response-parser.c | 40 +++++++++++++++++--------------
src/lib-http/http-response-parser.h | 2 +-
src/lib-http/test-http-response-parser.c | 11 ++++----
src/lib-http/test-http-server.c | 9 ++++---
7 files changed, 62 insertions(+), 55 deletions(-)
diffs (truncated from 345 to 300 lines):
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-client-connection.c
--- 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;
}
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-request-parser.c
--- 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;
}
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-request-parser.h
--- 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
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-response-parser.c
--- 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;
}
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/http-response-parser.h
--- 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
diff -r a6ed95a30cb1 -r adb4d013073d src/lib-http/test-http-response-parser.c
--- 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));
More information about the dovecot-cvs
mailing list