mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
always generate Date and Content-Length headers for HTTP/1.1
svn:r564
This commit is contained in:
parent
f175befac9
commit
74b3db50ae
@ -16,6 +16,7 @@ Changes in current version:
|
||||
o The configure script now takes an --enable-gcc-warnigns option that turns on many optional gcc warnings. (Nick has been building with these for a while, but they might be useful to other developers.)
|
||||
o move EV_PERSIST handling out of the event backends
|
||||
o small improvements to evhttp documentation
|
||||
o always generate Date and Content-Length headers for HTTP/1.1 replies
|
||||
|
||||
|
||||
Changes in 1.4.0:
|
||||
|
68
http.c
68
http.c
@ -302,7 +302,7 @@ evhttp_write_buffer(struct evhttp_connection *evcon,
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the headers need for an HTTP reply
|
||||
* Create the headers need for an HTTP request
|
||||
*/
|
||||
static void
|
||||
evhttp_make_header_request(struct evhttp_connection *evcon,
|
||||
@ -351,23 +351,10 @@ evhttp_is_connection_keepalive(struct evkeyvalq* headers)
|
||||
&& strncasecmp(connection, "keep-alive", 10) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the headers needed for an HTTP reply
|
||||
*/
|
||||
static void
|
||||
evhttp_make_header_response(struct evhttp_connection *evcon,
|
||||
struct evhttp_request *req)
|
||||
evhttp_maybe_add_date_header(struct evkeyvalq *headers)
|
||||
{
|
||||
static char line[1024];
|
||||
snprintf(line, sizeof(line), "HTTP/%d.%d %d %s\r\n",
|
||||
req->major, req->minor, req->response_code,
|
||||
req->response_code_line);
|
||||
evbuffer_add(evcon->output_buffer, line, strlen(line));
|
||||
|
||||
/* Potentially add headers for unidentified content. */
|
||||
if (EVBUFFER_LENGTH(req->output_buffer)) {
|
||||
if (evhttp_find_header(req->output_headers,
|
||||
"Date") == NULL) {
|
||||
if (evhttp_find_header(headers, "Date") == NULL) {
|
||||
char date[50];
|
||||
#ifndef WIN32
|
||||
struct tm cur;
|
||||
@ -382,30 +369,55 @@ evhttp_make_header_response(struct evhttp_connection *evcon,
|
||||
#endif
|
||||
if (strftime(date, sizeof(date),
|
||||
"%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
|
||||
evhttp_add_header(req->output_headers, "Date", date);
|
||||
evhttp_add_header(headers, "Date", date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (evhttp_find_header(req->output_headers,
|
||||
"Content-Type") == NULL) {
|
||||
evhttp_add_header(req->output_headers,
|
||||
"Content-Type", "text/html; charset=ISO-8859-1");
|
||||
static void
|
||||
evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
|
||||
long content_length)
|
||||
{
|
||||
if (evhttp_find_header(headers, "Transfer-Encoding") == NULL &&
|
||||
evhttp_find_header(headers, "Content-Length") == NULL) {
|
||||
static char len[12]; /* XXX: not thread-safe */
|
||||
snprintf(len, sizeof(len), "%ld", content_length);
|
||||
evhttp_add_header(headers, "Content-Length", len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the headers needed for an HTTP reply
|
||||
*/
|
||||
|
||||
static void
|
||||
evhttp_make_header_response(struct evhttp_connection *evcon,
|
||||
struct evhttp_request *req)
|
||||
{
|
||||
static char line[1024];
|
||||
snprintf(line, sizeof(line), "HTTP/%d.%d %d %s\r\n",
|
||||
req->major, req->minor, req->response_code,
|
||||
req->response_code_line);
|
||||
evbuffer_add(evcon->output_buffer, line, strlen(line));
|
||||
|
||||
if (req->major == 1 && req->minor == 1) {
|
||||
evhttp_maybe_add_date_header(req->output_headers);
|
||||
|
||||
/*
|
||||
* we need to add the content length if the user did
|
||||
* not give it, this is required for persistent
|
||||
* connections to work.
|
||||
*/
|
||||
if (evhttp_find_header(req->output_headers,
|
||||
"Transfer-Encoding") == NULL &&
|
||||
evhttp_find_header(req->output_headers,
|
||||
"Content-Length") == NULL) {
|
||||
static char len[12];
|
||||
snprintf(len, sizeof(len), "%ld",
|
||||
evhttp_maybe_add_content_length_header(req->output_headers,
|
||||
(long)EVBUFFER_LENGTH(req->output_buffer));
|
||||
}
|
||||
|
||||
/* Potentially add headers for unidentified content. */
|
||||
if (EVBUFFER_LENGTH(req->output_buffer)) {
|
||||
if (evhttp_find_header(req->output_headers,
|
||||
"Content-Type") == NULL) {
|
||||
evhttp_add_header(req->output_headers,
|
||||
"Content-Length", len);
|
||||
"Content-Type", "text/html; charset=ISO-8859-1");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,12 +200,14 @@ http_errorcb(struct bufferevent *bev, short what, void *arg)
|
||||
void
|
||||
http_basic_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
|
||||
struct evbuffer *evb = evbuffer_new();
|
||||
int empty = evhttp_find_header(req->input_headers, "Empty") != NULL;
|
||||
event_debug(("%s: called\n", __func__));
|
||||
evbuffer_add_printf(evb, "This is funny");
|
||||
|
||||
evhttp_send_reply(req, HTTP_OK, "Everything is fine", evb);
|
||||
/* allow sending of an empty reply */
|
||||
evhttp_send_reply(req, HTTP_OK, "Everything is fine",
|
||||
!empty ? evb : NULL);
|
||||
|
||||
evbuffer_free(evb);
|
||||
}
|
||||
@ -253,6 +255,7 @@ http_basic_test(void)
|
||||
}
|
||||
|
||||
void http_request_done(struct evhttp_request *, void *);
|
||||
void http_request_empty_done(struct evhttp_request *, void *);
|
||||
|
||||
static void
|
||||
http_connection_test(int persistent)
|
||||
@ -319,6 +322,27 @@ http_connection_test(int persistent)
|
||||
|
||||
event_dispatch();
|
||||
|
||||
/* make another request: request empty reply */
|
||||
test_ok = 0;
|
||||
|
||||
req = evhttp_request_new(http_request_empty_done, NULL);
|
||||
|
||||
/* Add the information that we care about */
|
||||
evhttp_add_header(req->output_headers, "Empty", "itis");
|
||||
|
||||
/* We give ownership of the request to the connection */
|
||||
if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
event_dispatch();
|
||||
|
||||
if (test_ok != 1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
evhttp_connection_free(evcon);
|
||||
evhttp_free(http);
|
||||
|
||||
@ -331,7 +355,6 @@ http_request_done(struct evhttp_request *req, void *arg)
|
||||
const char *what = "This is funny";
|
||||
|
||||
if (req->response_code != HTTP_OK) {
|
||||
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -355,6 +378,42 @@ http_request_done(struct evhttp_request *req, void *arg)
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
|
||||
/* test date header and content length */
|
||||
|
||||
void
|
||||
http_request_empty_done(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
if (req->response_code != HTTP_OK) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (evhttp_find_header(req->input_headers, "Date") == NULL) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (evhttp_find_header(req->input_headers, "Content-Length") == NULL) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strcmp(evhttp_find_header(req->input_headers, "Content-Length"),
|
||||
"0")) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (EVBUFFER_LENGTH(req->input_buffer) != 0) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
test_ok = 1;
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* HTTP DISPATCHER test
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user