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

Reply via email to