mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-08 11:53:00 -04:00
Preliminary support for Continue expectation in evhttp.
This commit is contained in:
parent
a12839b083
commit
fa9305f8f5
55
http.c
55
http.c
@ -377,6 +377,29 @@ evhttp_write_buffer(struct evhttp_connection *evcon,
|
||||
evcon);
|
||||
}
|
||||
|
||||
static void
|
||||
evhttp_send_continue_done(struct evhttp_connection *evcon, void *arg)
|
||||
{
|
||||
bufferevent_disable(evcon->bufev, EV_WRITE);
|
||||
}
|
||||
|
||||
static void
|
||||
evhttp_send_continue(struct evhttp_connection *evcon,
|
||||
struct evhttp_request *req)
|
||||
{
|
||||
bufferevent_enable(evcon->bufev, EV_WRITE);
|
||||
evbuffer_add_printf(bufferevent_get_output(evcon->bufev),
|
||||
"HTTP/%d.%d 100 Continue\r\n\r\n",
|
||||
req->major, req->minor);
|
||||
evcon->cb = evhttp_send_continue_done;
|
||||
evcon->cb_arg = NULL;
|
||||
bufferevent_setcb(evcon->bufev,
|
||||
evhttp_read_cb,
|
||||
evhttp_write_cb,
|
||||
evhttp_error_cb,
|
||||
evcon);
|
||||
}
|
||||
|
||||
/** Helper: returns true iff evconn is in any connected state. */
|
||||
static int
|
||||
evhttp_connected(struct evhttp_connection *evcon)
|
||||
@ -574,6 +597,9 @@ evhttp_make_header(struct evhttp_connection *evcon, struct evhttp_request *req)
|
||||
* For a request, we add the POST data, for a reply, this
|
||||
* is the regular data.
|
||||
*/
|
||||
/* XXX We might want to support waiting (a limited amount of
|
||||
time) for a continue status line from the server before
|
||||
sending POST/PUT message bodies. */
|
||||
evbuffer_add_buffer(output, req->output_buffer);
|
||||
}
|
||||
}
|
||||
@ -1804,6 +1830,30 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Should we send a 100 Continue status line? */
|
||||
if (req->kind == EVHTTP_REQUEST && REQ_VERSION_ATLEAST(req, 1, 1)) {
|
||||
const char *expect;
|
||||
|
||||
expect = evhttp_find_header(req->input_headers, "Expect");
|
||||
if (expect) {
|
||||
if (!evutil_ascii_strcasecmp(expect, "100-continue")) {
|
||||
/* XXX It would be nice to do some sanity
|
||||
checking here. Does the resource exist?
|
||||
Should the resource accept post requests? If
|
||||
no, we should respond with an error. For
|
||||
now, just optimistically tell the client to
|
||||
send their message body. */
|
||||
if (!evbuffer_get_length(bufferevent_get_input(evcon->bufev)))
|
||||
evhttp_send_continue(evcon, req);
|
||||
} else {
|
||||
evhttp_send_error(req, HTTP_EXPECTATIONFAILED,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
evhttp_read_body(evcon, req);
|
||||
/* note the request may have been freed in evhttp_read_body */
|
||||
}
|
||||
@ -1861,6 +1911,11 @@ evhttp_read_header(struct evhttp_connection *evcon,
|
||||
break;
|
||||
|
||||
case EVHTTP_RESPONSE:
|
||||
/* Start over if we got a 100 Continue response. */
|
||||
if (req->response_code == 100) {
|
||||
evhttp_start_read(evcon);
|
||||
return;
|
||||
}
|
||||
if (!evhttp_response_needs_body(req)) {
|
||||
event_debug(("%s: skipping body for code %d\n",
|
||||
__func__, req->response_code));
|
||||
|
@ -58,6 +58,7 @@ struct event_base;
|
||||
#define HTTP_BADREQUEST 400 /**< invalid http request was made */
|
||||
#define HTTP_NOTFOUND 404 /**< could not find content for uri */
|
||||
#define HTTP_BADMETHOD 405 /**< method not allowed for this uri */
|
||||
#define HTTP_EXPECTATIONFAILED 417 /**< we can't handle this expectation */
|
||||
#define HTTP_INTERNAL 500 /**< internal error */
|
||||
#define HTTP_NOTIMPLEMENTED 501 /**< not implemented */
|
||||
#define HTTP_SERVUNAVAIL 503 /**< the server is not available */
|
||||
|
@ -1503,10 +1503,31 @@ http_post_test(void *arg)
|
||||
|
||||
event_base_dispatch(data->base);
|
||||
|
||||
tt_int_op(test_ok, ==, 1);
|
||||
|
||||
test_ok = 0;
|
||||
|
||||
req = evhttp_request_new(http_postrequest_done, data->base);
|
||||
tt_assert(req);
|
||||
|
||||
/* Now try with 100-continue. */
|
||||
|
||||
/* Add the information that we care about */
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Host", "somehost");
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req), "Expect", "100-continue");
|
||||
evbuffer_add_printf(evhttp_request_get_output_buffer(req), POST_DATA);
|
||||
|
||||
if (evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/postit") == -1) {
|
||||
tt_abort_msg("Couldn't make request");
|
||||
}
|
||||
|
||||
event_base_dispatch(data->base);
|
||||
|
||||
tt_int_op(test_ok, ==, 1);
|
||||
|
||||
evhttp_connection_free(evcon);
|
||||
evhttp_free(http);
|
||||
|
||||
tt_int_op(test_ok, ==, 1);
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user