Prioritize HTTP sockets over outgoing connections
[pazpar2-moved-to-github.git] / src / http.c
index 149fdd0..5f5534d 100644 (file)
@@ -81,6 +81,7 @@ struct http_buf
     struct http_buf *next;
 };
 
+static int log_level_post = 0;
 
 static void proxy_io(IOCHAN i, int event);
 static struct http_channel *http_channel_create(http_server_t http_server,
@@ -606,7 +607,8 @@ struct http_request *http_parse_request(struct http_channel *c,
         r->content_len = start + len - buf;
         r->content_buf = buf;
 
-        if (!yaz_strcmp_del("application/x-www-form-urlencoded",
+        if (content_type &&
+            !yaz_strcmp_del("application/x-www-form-urlencoded",
                             content_type, "; "))
         {
             http_parse_arguments(r, c->nmem, r->content_buf);
@@ -655,6 +657,7 @@ static struct http_buf *http_serialize_response(struct http_channel *c,
         FILE *lf = yaz_log_file();
         yaz_log(YLOG_LOG, "Response:");
         fwrite(wrbuf_buf(c->wrbuf), 1, wrbuf_len(c->wrbuf), lf);
+        fputc('\n', lf);
     }
     return http_buf_bywrbuf(c->http_server, c->wrbuf);
 }
@@ -793,11 +796,15 @@ static int http_proxy(struct http_request *rq)
         p->channel = c;
         p->first_response = 1;
         c->proxy = p;
-        // We will add EVENT_OUTPUT below
         p->iochan = iochan_create(sock, proxy_io, EVENT_INPUT, "http_proxy");
         iochan_setdata(p->iochan, p);
 
-        iochan_add(ser->iochan_man, p->iochan);
+        if (iochan_add(ser->iochan_man, p->iochan, 5))
+        {
+            iochan_destroy(p->iochan);
+            xfree(p);
+            return -1;
+        }
     }
 
     // Do _not_ modify Host: header, just checking it's existence
@@ -840,13 +847,15 @@ void http_send_response(struct http_channel *ch)
     struct http_buf *hb;
 
     yaz_timing_stop(ch->yt);
-    yaz_log(YLOG_LOG, "Response: %6.5f %d %s%s%s ",
-            yaz_timing_get_real(ch->yt),
-            iochan_getfd(ch->iochan),
-            ch->request->path,
-            *ch->request->search ? "?" : "",
-            ch->request->search);
-
+    if (ch->request)
+    {
+        yaz_log(YLOG_LOG, "Response: %6.5f %d %s%s%s ",
+                yaz_timing_get_real(ch->yt),
+                iochan_getfd(ch->iochan),
+                ch->request->path,
+                *ch->request->search ? "?" : "",
+                ch->request->search);
+    }
     assert(rs);
     hb = http_serialize_response(ch, rs);
     if (!hb)
@@ -956,8 +965,8 @@ static void http_io(IOCHAN i, int event)
                         hc->request->path,
                         *hc->request->search ? "?" : "",
                         hc->request->search);
-                if (hc->request->content_buf)
-                    yaz_log(YLOG_LOG, "%s", hc->request->content_buf);
+                if (hc->request->content_buf && log_level_post)
+                    yaz_log(log_level_post, "%s", hc->request->content_buf);
                 if (http_weshouldproxy(hc->request))
                     http_proxy(hc->request);
                 else
@@ -996,7 +1005,6 @@ static void http_io(IOCHAN i, int event)
                                 (long long) iochan_getfd(i), sz);
                         fwrite(wb->buf, 1, wb->offset + wb->len,
                                hc->http_server->record_file);
-                        fputc('\n', hc->http_server->record_file);
                         fflush(hc->http_server->record_file);
                     }
  #endif
@@ -1215,11 +1223,14 @@ static void http_accept(IOCHAN i, int event)
     c = iochan_create(s, http_io, EVENT_INPUT | EVENT_EXCEPT,
                       "http_session_socket");
 
-
     ch = http_channel_create(server->http_server, host, server);
     ch->iochan = c;
     iochan_setdata(c, ch);
-    iochan_add(server->iochan_man, c);
+    if (iochan_add(server->iochan_man, c, 0))
+    {
+        yaz_log(YLOG_WARN, "Refusing incoming HTTP connection");
+        http_channel_destroy(c);
+    }
 }
 
 /* Create a http-channel listener, syntax [host:]port */
@@ -1280,7 +1291,7 @@ int http_init(struct conf_server *server, const char *record_fname)
     if (s == -1)
     {
         yaz_log(YLOG_FATAL|YLOG_ERRNO, "socket");
-        freeaddrinfo(ai);
+        freeaddrinfo(af);
         return 1;
     }
     if (ipv6_only >= 0 && ai->ai_family == AF_INET6 &&
@@ -1288,7 +1299,7 @@ int http_init(struct conf_server *server, const char *record_fname)
     {
         yaz_log(YLOG_FATAL|YLOG_ERRNO, "setsockopt IPV6_V6ONLY %s:%s %d",
                 server->host, server->port, ipv6_only);
-        freeaddrinfo(ai);
+        freeaddrinfo(af);
         CLOSESOCKET(s);
         return 1;
     }
@@ -1296,7 +1307,7 @@ int http_init(struct conf_server *server, const char *record_fname)
     {
         yaz_log(YLOG_FATAL|YLOG_ERRNO, "setsockopt SO_REUSEADDR %s:%s",
                 server->host, server->port);
-        freeaddrinfo(ai);
+        freeaddrinfo(af);
         CLOSESOCKET(s);
         return 1;
     }
@@ -1304,11 +1315,11 @@ int http_init(struct conf_server *server, const char *record_fname)
     {
         yaz_log(YLOG_FATAL|YLOG_ERRNO, "bind %s:%s",
                 server->host, server->port);
-        freeaddrinfo(ai);
+        freeaddrinfo(af);
         CLOSESOCKET(s);
         return 1;
     }
-    freeaddrinfo(ai);
+    freeaddrinfo(af);
     if (listen(s, SOMAXCONN) < 0)
     {
         yaz_log(YLOG_FATAL|YLOG_ERRNO, "listen %s:%s",
@@ -1327,15 +1338,20 @@ int http_init(struct conf_server *server, const char *record_fname)
             return 1;
         }
     }
-    server->http_server = http_server_create();
 
+    c = iochan_create(s, http_accept, EVENT_INPUT|EVENT_EXCEPT, "http_server");
+    if (iochan_add(server->iochan_man, c, 0))
+    {
+        yaz_log(YLOG_WARN, "Can not create HTTP binding socket");
+        iochan_destroy(c);
+        return -1;
+    }
+
+    server->http_server = http_server_create();
     server->http_server->record_file = record_file;
     server->http_server->listener_socket = s;
-
-    c = iochan_create(s, http_accept, EVENT_INPUT | EVENT_EXCEPT, "http_server");
     iochan_setdata(c, server);
 
-    iochan_add(server->iochan_man, c);
     return 0;
 }
 
@@ -1449,8 +1465,10 @@ http_server_t http_server_create(void)
     hs->proxy_addr = 0;
     hs->ref_count = 1;
     hs->http_sessions = 0;
-
     hs->record_file = 0;
+
+    log_level_post = yaz_log_module_level("post");
+
     return hs;
 }