about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-07-19 00:15:31 +0000
committerEric Wong <normalperson@yhbt.net>2013-07-19 01:30:17 +0000
commit313a04bd35534a6cd024149d9f2c9b9487f08165 (patch)
treec7c5b3db10715ba68a9c09025c26f51785cfae42
parent00d234c6f9362c11938f3b67c03bf208c7638eca (diff)
downloadcmogstored-313a04bd35534a6cd024149d9f2c9b9487f08165.tar.gz
Incomplete request headers are uncommon, so if we see them,
something is probably off or strange.  This should make it
easier to maintain probe points to watch for this behavior.
-rw-r--r--http.c33
-rw-r--r--mgmt.c33
-rw-r--r--probes.d2
3 files changed, 48 insertions, 20 deletions
diff --git a/http.c b/http.c
index 6f51cf8..a7f9bad 100644
--- a/http.c
+++ b/http.c
@@ -236,7 +236,7 @@ http_client_died(struct mog_fd *mfd, size_t buf_len, int save_err)
         return MOG_NEXT_CLOSE;
 }
 
-MOG_NOINLINE static char *
+static char *
 http_rbuf_grow(struct mog_fd *mfd, struct mog_rbuf **rbuf, size_t buf_len)
 {
         struct mog_http *http = &mfd->as.http;
@@ -246,6 +246,24 @@ http_rbuf_grow(struct mog_fd *mfd, struct mog_rbuf **rbuf, size_t buf_len)
         return *rbuf ? (*rbuf)->rptr : NULL;
 }
 
+MOG_NOINLINE static bool
+http_parse_continue(struct mog_fd *mfd, struct mog_rbuf **rbuf,
+                char **buf, size_t buf_len, uint32_t *off)
+{
+        struct mog_http *http = &mfd->as.http;
+
+        assert(http->wbuf == NULL &&
+               "tried to write (and failed) with partial req");
+        if (http->_p.buf_off >= (*rbuf)->rcapa) {
+                *buf = http_rbuf_grow(mfd, rbuf, buf_len);
+                if (!*buf)
+                        return false;
+        }
+
+        *off = http->_p.buf_off;
+        return true;
+}
+
 static enum mog_next __http_queue_step(struct mog_fd *mfd)
 {
         struct mog_http *http = &mfd->as.http;
@@ -295,15 +313,10 @@ parse:
                 case MOG_PARSER_ERROR:
                         goto err507or400;
                 case MOG_PARSER_CONTINUE:
-                        assert(http->wbuf == NULL &&
-                               "tried to write (and failed) with partial req");
-                        if (http->_p.buf_off >= rbuf->rcapa) {
-                                buf = http_rbuf_grow(mfd, &rbuf, buf_len);
-                                if (!buf)
-                                        goto err400;
-                        }
-                        off = http->_p.buf_off;
-                        goto reread;
+                        if (http_parse_continue(mfd, &rbuf, &buf, buf_len,
+                                                &off))
+                                goto reread;
+                        goto err400;
                 case MOG_PARSER_DONE:
                         return http_run(mfd, rbuf, buf, buf_len);
                 }
diff --git a/mgmt.c b/mgmt.c
index b80718c..6dd1b77 100644
--- a/mgmt.c
+++ b/mgmt.c
@@ -214,7 +214,7 @@ static enum mog_next mgmt_run(struct mog_fd *mfd, struct mog_rbuf *rbuf,
         return mgmt->wbuf ? MOG_NEXT_WAIT_WR : MOG_NEXT_ACTIVE;
 }
 
-MOG_NOINLINE static char *
+static char *
 mgmt_rbuf_grow(struct mog_fd *mfd, struct mog_rbuf **rbuf, size_t buf_len)
 {
         struct mog_mgmt *mgmt = &mfd->as.mgmt;
@@ -223,6 +223,24 @@ mgmt_rbuf_grow(struct mog_fd *mfd, struct mog_rbuf **rbuf, size_t buf_len)
         return *rbuf ? (*rbuf)->rptr : NULL;
 }
 
+MOG_NOINLINE static bool
+mgmt_parse_continue(struct mog_fd *mfd, struct mog_rbuf **rbuf,
+                char **buf, size_t buf_len, off_t *off)
+{
+        struct mog_mgmt *mgmt = &mfd->as.mgmt;
+
+        assert(mgmt->wbuf == NULL &&
+               "tried to write (and failed) with partial req");
+        if (mgmt->buf_off >= (*rbuf)->rcapa) {
+                *buf = mgmt_rbuf_grow(mfd, rbuf, buf_len);
+                if (!*buf)
+                        return false;
+        }
+
+        *off = mgmt->buf_off;
+        return true;
+}
+
 /*
  * this is the main event callback and called whenever mgmt
  * is pulled out of a queue (either idle or active)
@@ -271,15 +289,10 @@ parse:
                         syslog(LOG_ERR, "mgmt parser error");
                         return MOG_NEXT_CLOSE;
                 case MOG_PARSER_CONTINUE:
-                        assert(mgmt->wbuf == NULL &&
-                               "tried to write (and failed) with partial req");
-                        if (mgmt->buf_off >= rbuf->rcapa) {
-                                buf = mgmt_rbuf_grow(mfd, &rbuf, buf_len);
-                                if (!buf)
-                                        goto too_large;
-                        }
-                        off = mgmt->buf_off;
-                        goto reread;
+                        if (mgmt_parse_continue(mfd, &rbuf, &buf, buf_len,
+                                                &off))
+                                goto reread;
+                        goto too_large;
                 case MOG_PARSER_DONE:
                         return mgmt_run(mfd, rbuf, buf, buf_len);
                 }
diff --git a/probes.d b/probes.d
index c5f55ba..d6197d6 100644
--- a/probes.d
+++ b/probes.d
@@ -29,5 +29,7 @@ provider cmogstored {
         probe write_buffered();
 
         /* DWARF: mgmt_rbuf_grow */
+        /* DWARF: mgmt_parse_continue */
         /* DWARF: http_rbuf_grow */
+        /* DWARF: http_parse_continue */
 };