mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -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);
|
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. */
|
/** Helper: returns true iff evconn is in any connected state. */
|
||||||
static int
|
static int
|
||||||
evhttp_connected(struct evhttp_connection *evcon)
|
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
|
* For a request, we add the POST data, for a reply, this
|
||||||
* is the regular data.
|
* 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);
|
evbuffer_add_buffer(output, req->output_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1804,6 +1830,30 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req)
|
|||||||
return;
|
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);
|
evhttp_read_body(evcon, req);
|
||||||
/* note the request may have been freed in evhttp_read_body */
|
/* note the request may have been freed in evhttp_read_body */
|
||||||
}
|
}
|
||||||
@ -1861,6 +1911,11 @@ evhttp_read_header(struct evhttp_connection *evcon,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EVHTTP_RESPONSE:
|
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)) {
|
if (!evhttp_response_needs_body(req)) {
|
||||||
event_debug(("%s: skipping body for code %d\n",
|
event_debug(("%s: skipping body for code %d\n",
|
||||||
__func__, req->response_code));
|
__func__, req->response_code));
|
||||||
|
@ -58,6 +58,7 @@ struct event_base;
|
|||||||
#define HTTP_BADREQUEST 400 /**< invalid http request was made */
|
#define HTTP_BADREQUEST 400 /**< invalid http request was made */
|
||||||
#define HTTP_NOTFOUND 404 /**< could not find content for uri */
|
#define HTTP_NOTFOUND 404 /**< could not find content for uri */
|
||||||
#define HTTP_BADMETHOD 405 /**< method not allowed for this 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_INTERNAL 500 /**< internal error */
|
||||||
#define HTTP_NOTIMPLEMENTED 501 /**< not implemented */
|
#define HTTP_NOTIMPLEMENTED 501 /**< not implemented */
|
||||||
#define HTTP_SERVUNAVAIL 503 /**< the server is not available */
|
#define HTTP_SERVUNAVAIL 503 /**< the server is not available */
|
||||||
|
@ -1503,10 +1503,31 @@ http_post_test(void *arg)
|
|||||||
|
|
||||||
event_base_dispatch(data->base);
|
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_connection_free(evcon);
|
||||||
evhttp_free(http);
|
evhttp_free(http);
|
||||||
|
|
||||||
tt_int_op(test_ok, ==, 1);
|
|
||||||
end:
|
end:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user