mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-13 22:37:42 -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:
|
||||||
|
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
|
static void
|
||||||
evhttp_make_header_request(struct evhttp_connection *evcon,
|
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);
|
&& strncasecmp(connection, "keep-alive", 10) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Create the headers needed for an HTTP reply
|
|
||||||
*/
|
|
||||||
static void
|
static void
|
||||||
evhttp_make_header_response(struct evhttp_connection *evcon,
|
evhttp_maybe_add_date_header(struct evkeyvalq *headers)
|
||||||
struct evhttp_request *req)
|
|
||||||
{
|
{
|
||||||
static char line[1024];
|
if (evhttp_find_header(headers, "Date") == NULL) {
|
||||||
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) {
|
|
||||||
char date[50];
|
char date[50];
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
struct tm cur;
|
struct tm cur;
|
||||||
@ -382,30 +369,55 @@ evhttp_make_header_response(struct evhttp_connection *evcon,
|
|||||||
#endif
|
#endif
|
||||||
if (strftime(date, sizeof(date),
|
if (strftime(date, sizeof(date),
|
||||||
"%a, %d %b %Y %H:%M:%S GMT", cur_p) != 0) {
|
"%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,
|
static void
|
||||||
"Content-Type") == NULL) {
|
evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
|
||||||
evhttp_add_header(req->output_headers,
|
long content_length)
|
||||||
"Content-Type", "text/html; charset=ISO-8859-1");
|
{
|
||||||
|
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
|
* 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.
|
||||||
*/
|
*/
|
||||||
if (evhttp_find_header(req->output_headers,
|
evhttp_maybe_add_content_length_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",
|
|
||||||
(long)EVBUFFER_LENGTH(req->output_buffer));
|
(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,
|
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