diff options
Diffstat (limited to 'http.c')
-rw-r--r-- | http.c | 62 |
1 files changed, 48 insertions, 14 deletions
@@ -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); } /* |