When initiating HTTP requests in a multi-threaded process, under any
significant load you will start finding horrible memory corruption
problems, sometimes resulting in bad requests and sometimes resulting in
core dumps. Also, under any significant load, you'll probably find that
you are dropping a large number of connections due to the listen queue
overflowing while your code is performing some other task. This is a
patch that I think largely deals with these. Also, http_hostportfile()
is not thread-safe, so I've attached a thread-safe version that can be
used in its place (unfortunately I can't think of any clean way to make
the current interface thread-safe without introducing a memory leak).
/* TH: remember to free() opaque after you're done with this */
int
http_hostportfile_r(const char *url, char **phost, u_short *pport, char
**pfile,void **opaque)
{
struct http_hostportfile_threadsafe_opaque {
char shost[1024];
char sfile[1024];
} *opaquedata;
opaquedata = malloc(sizeof(*opaquedata));
*opaque = opaquedata;
char *p, *p2;
int len;
u_short port;
len = strlen(HTTP_PREFIX);
if (strncasecmp(url, HTTP_PREFIX, len))
return (-1);
url += len;
/* We might overrun */
if (strlcpy(opaquedata-shost, url, sizeof(opaquedata-shost))
= sizeof(opaquedata-shost))
return (-1);
p = strchr(opaquedata-shost, '/');
if (p != NULL) {
*p = '\0';
p2 = p + 1;
} else
p2 = NULL;
if (pfile != NULL) {
/* Generate request file */
if (p2 == NULL)
p2 = ;
snprintf(opaquedata-sfile, sizeof(opaquedata-sfile),
/%s, p2);
}
p = strchr(opaquedata-shost, ':');
if (p != NULL) {
*p = '\0';
port = atoi(p + 1);
if (port == 0)
return (-1);
} else
port = HTTP_DEFAULTPORT;
if (phost != NULL)
*phost = opaquedata-shost;
if (pport != NULL)
*pport = port;
if (pfile != NULL)
*pfile = opaquedata-sfile;
return (0);
}
Index: http.c
===
--- http.c (revision 1)
+++ http.c (working copy)
@@ -308,7 +308,7 @@
evhttp_make_header_request(struct evhttp_connection *evcon,
struct evhttp_request *req)
{
- static char line[1024];
+ char line[1024];
const char *method;
evhttp_remove_header(req-output_headers, Accept-Encoding);
@@ -378,9 +378,9 @@
evhttp_maybe_add_content_length_header(struct evkeyvalq *headers,
long content_length)
{
+ char len[12]; /* XXX: not thread-safe */
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);
}
@@ -394,7 +394,7 @@
evhttp_make_header_response(struct evhttp_connection *evcon,
struct evhttp_request *req)
{
- static char line[1024];
+ 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);
@@ -433,7 +433,7 @@
void
evhttp_make_header(struct evhttp_connection *evcon, struct
evhttp_request *req)
{
- static char line[1024];
+ char line[1024];
struct evkeyval *header;
/*
@@ -1999,7 +1999,7 @@
if ((fd = bind_socket(address, port)) == -1)
return (-1);
- if (listen(fd, 10) == -1) {
+ if (listen(fd, 8192) == -1) {
event_warn(%s: listen, __func__);
EVUTIL_CLOSESOCKET(fd);
return (-1);
___
Libevent-users mailing list
Libevent-users@monkey.org
http://monkeymail.org/mailman/listinfo/libevent-users