about summary refs log tree commit homepage
path: root/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'http.c')
-rw-r--r--http.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/http.c b/http.c
index f2a66e0..5fa34bc 100644
--- a/http.c
+++ b/http.c
@@ -3,6 +3,7 @@
  * License: GPLv3 or later (see COPYING for details)
  */
 #include "cmogstored.h"
+#include "trace.h"
 #include "http.h"
 
 /*
@@ -59,15 +60,17 @@ http_defer_rbuf(struct mog_http *http, struct mog_rbuf *rbuf, size_t buf_len)
 }
 
 static void
-http_process_client(struct mog_http *http, char *buf, size_t buf_len)
+http_process_client(struct mog_fd *mfd, char *buf, size_t buf_len)
 {
+        struct mog_http *http = &mfd->as.http;
+
         switch (http->_p.http_method) {
         case MOG_HTTP_METHOD_NONE: assert(0 && "BUG: unset HTTP method");
-        case MOG_HTTP_METHOD_GET: mog_http_get_open(http, buf); break;
-        case MOG_HTTP_METHOD_HEAD: mog_http_get_open(http, buf); break;
-        case MOG_HTTP_METHOD_DELETE: mog_http_delete(http, buf); break;
-        case MOG_HTTP_METHOD_MKCOL: mog_http_mkcol(http, buf); break;
-        case MOG_HTTP_METHOD_PUT: mog_http_put(http, buf, buf_len); break;
+        case MOG_HTTP_METHOD_GET: mog_http_get_open(mfd, buf); break;
+        case MOG_HTTP_METHOD_HEAD: mog_http_get_open(mfd, buf); break;
+        case MOG_HTTP_METHOD_DELETE: mog_http_delete(mfd, buf); break;
+        case MOG_HTTP_METHOD_MKCOL: mog_http_mkcol(mfd, buf); break;
+        case MOG_HTTP_METHOD_PUT: mog_http_put(mfd, buf, buf_len); break;
         }
 }
 
@@ -158,6 +161,9 @@ static enum mog_next http_queue_step(struct mog_fd *mfd)
 reread:
         r = read(mfd->fd, buf + off, rbuf->rcapa - off);
         if (r > 0) {
+                if (off == 0)
+                        TRACE(CMOGSTORED_HTTP_REQ_BEGIN(false));
+
                 buf_len = r + off;
 parse:
                 state = mog_http_parse(http, buf, buf_len);
@@ -178,7 +184,7 @@ parse:
                         off = http->_p.offset;
                         goto reread;
                 case MOG_PARSER_DONE:
-                        http_process_client(http, buf, buf_len);
+                        http_process_client(mfd, buf, buf_len);
                         if (http->wbuf == MOG_WR_ERROR)
                                 return MOG_NEXT_CLOSE;
                         if (http->wbuf) {
@@ -190,12 +196,17 @@ parse:
                         } else if (!http->_p.persistent) {
                                 return MOG_NEXT_CLOSE;
                         } else {
+                                /* pipelined request */
+                                if (buf_len)
+                                        TRACE(CMOGSTORED_HTTP_REQ_BEGIN(true));
+
                                 http_defer_rbuf(http, rbuf, buf_len);
                                 mog_http_reset(http);
                         }
                         return MOG_NEXT_ACTIVE;
                 }
         } else if (r == 0) { /* client shut down */
+                TRACE(CMOGSTORED_HTTP_RDCLOSE(buf_len));
                 return MOG_NEXT_CLOSE;
         } else {
                 switch (errno) {
@@ -209,8 +220,11 @@ parse:
                 case EINTR: goto reread;
                 case ECONNRESET:
                 case ENOTCONN:
+                        /* these errors are too common to log, normally */
+                        TRACE(CMOGSTORED_HTTP_RDERR(buf_len, errno));
                         return MOG_NEXT_CLOSE;
                 default:
+                        TRACE(CMOGSTORED_HTTP_RDERR(buf_len, errno));
                         syslog(LOG_NOTICE, "http client died: %m");
                         return MOG_NEXT_CLOSE;
                 }
@@ -264,28 +278,48 @@ void mog_http_quit_step(struct mog_fd *mfd)
         }
 }
 
-/* called immediately after accept(), this initializes the mfd (once) */
-void mog_http_post_accept(int fd, struct mog_svc *svc,
+/* stringify the address for tracers */
+static MOG_NOINLINE void
+trace_http_accepted(struct mog_fd *mfd, struct sockaddr *sa, socklen_t salen)
+{
+#ifdef HAVE_SYSTEMTAP
+        struct mog_ni ni;
+        int rc = mog_nameinfo(sa, salen, &ni);
+        const char *host = rc == 0 ? ni.ni_host : gai_strerror(rc);
+
+        TRACE(CMOGSTORED_HTTP_ACCEPTED(mfd->fd, host, ni.ni_serv));
+#endif /* !HAVE_SYSTEMTAP */
+}
+
+static void http_post_accept_common(struct mog_fd *mfd, struct mog_svc *svc,
                         struct sockaddr *sa, socklen_t salen)
 {
-        struct mog_fd *mfd = mog_fd_init(fd, MOG_FD_TYPE_HTTP);
         struct mog_http *http = &mfd->as.http;
 
+        if (TRACE_ENABLED(CMOGSTORED_HTTP_ACCEPTED))
+                trace_http_accepted(mfd, sa, salen);
+
         mog_http_init(http, svc);
         mog_packaddr_init(&http->mpa, sa, salen);
         mog_idleq_add(svc->queue, mfd, MOG_QEV_RD);
 }
 
 /* called immediately after accept(), this initializes the mfd (once) */
+void mog_http_post_accept(int fd, struct mog_svc *svc,
+                        struct sockaddr *sa, socklen_t salen)
+{
+        struct mog_fd *mfd = mog_fd_init(fd, MOG_FD_TYPE_HTTP);
+
+        http_post_accept_common(mfd, svc, sa, salen);
+}
+
+/* called immediately after accept(), this initializes the mfd (once) */
 void mog_httpget_post_accept(int fd, struct mog_svc *svc,
                         struct sockaddr *sa, socklen_t salen)
 {
         struct mog_fd *mfd = mog_fd_init(fd, MOG_FD_TYPE_HTTPGET);
-        struct mog_http *http = &mfd->as.http;
 
-        mog_http_init(http, svc);
-        mog_packaddr_init(&http->mpa, sa, salen);
-        mog_idleq_add(svc->queue, mfd, MOG_QEV_RD);
+        http_post_accept_common(mfd, svc, sa, salen);
 }
 
 /*