mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-13 06:16:10 -04:00
from trunk: always generate Date and Content-Length headers for HTTP/1.1
svn:r565
This commit is contained in:
parent
567f681bf1
commit
ef12a5a15a
@ -8,6 +8,7 @@ Changes in current version:
|
|||||||
o Make kqueue restore signal handlers correctly when event_del() is called.
|
o Make kqueue restore signal handlers correctly when event_del() is called.
|
||||||
o provide event_reinit() to reintialize an event_base after fork
|
o provide event_reinit() to reintialize an event_base after fork
|
||||||
o small improvements to evhttp documentation
|
o small improvements to evhttp documentation
|
||||||
|
o always generate Date and Content-Length headers for HTTP/1.1 replies
|
||||||
|
|
||||||
|
|
||||||
Changes in 1.4.0-beta:
|
Changes in 1.4.0-beta:
|
||||||
|
82
http.c
82
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
|
static void
|
||||||
evhttp_make_header_request(struct evhttp_connection *evcon,
|
evhttp_make_header_request(struct evhttp_connection *evcon,
|
||||||
@ -351,9 +351,45 @@ evhttp_is_connection_keepalive(struct evkeyvalq* headers)
|
|||||||
&& strncasecmp(connection, "keep-alive", 10) == 0);
|
&& strncasecmp(connection, "keep-alive", 10) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
evhttp_maybe_add_date_header(struct evkeyvalq *headers)
|
||||||
|
{
|
||||||
|
if (evhttp_find_header(headers, "Date") == NULL) {
|
||||||
|
char date[50];
|
||||||
|
#ifndef WIN32
|
||||||
|
struct tm cur;
|
||||||
|
#endif
|
||||||
|
struct tm *cur_p;
|
||||||
|
time_t t = time(NULL);
|
||||||
|
#ifdef WIN32
|
||||||
|
cur_p = gmtime(&t);
|
||||||
|
#else
|
||||||
|
gmtime_r(&t, &cur);
|
||||||
|
cur_p = &cur;
|
||||||
|
#endif
|
||||||
|
if (strftime(date, sizeof(date),
|
||||||
|
"%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
|
||||||
|
evhttp_add_header(headers, "Date", date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
* Create the headers needed for an HTTP reply
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
evhttp_make_header_response(struct evhttp_connection *evcon,
|
evhttp_make_header_response(struct evhttp_connection *evcon,
|
||||||
struct evhttp_request *req)
|
struct evhttp_request *req)
|
||||||
@ -364,48 +400,24 @@ evhttp_make_header_response(struct evhttp_connection *evcon,
|
|||||||
req->response_code_line);
|
req->response_code_line);
|
||||||
evbuffer_add(evcon->output_buffer, line, strlen(line));
|
evbuffer_add(evcon->output_buffer, line, strlen(line));
|
||||||
|
|
||||||
/* Potentially add headers for unidentified content. */
|
if (req->major == 1 && req->minor == 1) {
|
||||||
if (EVBUFFER_LENGTH(req->output_buffer)) {
|
evhttp_maybe_add_date_header(req->output_headers);
|
||||||
if (evhttp_find_header(req->output_headers,
|
|
||||||
"Date") == NULL) {
|
|
||||||
char date[50];
|
|
||||||
#ifndef WIN32
|
|
||||||
struct tm cur;
|
|
||||||
#endif
|
|
||||||
struct tm *cur_p;
|
|
||||||
time_t t = time(NULL);
|
|
||||||
#ifdef WIN32
|
|
||||||
cur_p = gmtime(&t);
|
|
||||||
#else
|
|
||||||
gmtime_r(&t, &cur);
|
|
||||||
cur_p = &cur;
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (evhttp_find_header(req->output_headers,
|
|
||||||
"Content-Type") == NULL) {
|
|
||||||
evhttp_add_header(req->output_headers,
|
|
||||||
"Content-Type", "text/html; charset=ISO-8859-1");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we need to add the content length if the user did
|
* we need to add the content length if the user did
|
||||||
* not give it, this is required for persistent
|
* not give it, this is required for persistent
|
||||||
* connections to work.
|
* connections to work.
|
||||||
*/
|
*/
|
||||||
|
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,
|
if (evhttp_find_header(req->output_headers,
|
||||||
"Transfer-Encoding") == NULL &&
|
"Content-Type") == NULL) {
|
||||||
evhttp_find_header(req->output_headers,
|
|
||||||
"Content-Length") == NULL) {
|
|
||||||
static char len[12];
|
|
||||||
snprintf(len, sizeof(len), "%ld",
|
|
||||||
(long)EVBUFFER_LENGTH(req->output_buffer));
|
|
||||||
evhttp_add_header(req->output_headers,
|
evhttp_add_header(req->output_headers,
|
||||||
"Content-Length", len);
|
"Content-Type", "text/html; charset=ISO-8859-1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,12 +198,14 @@ http_errorcb(struct bufferevent *bev, short what, void *arg)
|
|||||||
void
|
void
|
||||||
http_basic_cb(struct evhttp_request *req, void *arg)
|
http_basic_cb(struct evhttp_request *req, void *arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct evbuffer *evb = evbuffer_new();
|
struct evbuffer *evb = evbuffer_new();
|
||||||
|
int empty = evhttp_find_header(req->input_headers, "Empty") != NULL;
|
||||||
event_debug(("%s: called\n", __func__));
|
event_debug(("%s: called\n", __func__));
|
||||||
evbuffer_add_printf(evb, "This is funny");
|
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);
|
evbuffer_free(evb);
|
||||||
}
|
}
|
||||||
@ -251,6 +253,7 @@ http_basic_test(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void http_request_done(struct evhttp_request *, void *);
|
void http_request_done(struct evhttp_request *, void *);
|
||||||
|
void http_request_empty_done(struct evhttp_request *, void *);
|
||||||
|
|
||||||
void
|
void
|
||||||
http_connection_test(int persistent)
|
http_connection_test(int persistent)
|
||||||
@ -317,6 +320,27 @@ http_connection_test(int persistent)
|
|||||||
|
|
||||||
event_dispatch();
|
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_connection_free(evcon);
|
||||||
evhttp_free(http);
|
evhttp_free(http);
|
||||||
|
|
||||||
@ -329,7 +353,6 @@ http_request_done(struct evhttp_request *req, void *arg)
|
|||||||
const char *what = "This is funny";
|
const char *what = "This is funny";
|
||||||
|
|
||||||
if (req->response_code != HTTP_OK) {
|
if (req->response_code != HTTP_OK) {
|
||||||
|
|
||||||
fprintf(stderr, "FAILED\n");
|
fprintf(stderr, "FAILED\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@ -353,6 +376,42 @@ http_request_done(struct evhttp_request *req, void *arg)
|
|||||||
event_loopexit(NULL);
|
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
|
* HTTP DISPATCHER test
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user