X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fhtparser.c;h=6382bf2b0435b21a26e5b8952ee479d50e23ac47;hb=83723896cdbe2fb064748e45611e9b9c829c1d72;hp=c78f064c33f7775e1e7882586a510dc76876830b;hpb=a0327573bb6032e02e988a0d0aed709b4be7a422;p=ashd.git diff --git a/src/htparser.c b/src/htparser.c index c78f064..6382bf2 100644 --- a/src/htparser.c +++ b/src/htparser.c @@ -20,60 +20,22 @@ #include #include #include -#include #include #include #include #include -#include #ifdef HAVE_CONFIG_H #include #endif #include #include +#include #include #include #include -#define EV_READ 1 -#define EV_WRITE 2 - -struct blocker { - struct blocker *n, *p; - int fd; - int ev; - time_t to; - struct muth *th; -}; - -static struct blocker *blockers; -int plex; - -static int block(int fd, int ev, time_t to) -{ - struct blocker *bl; - int rv; - - omalloc(bl); - bl->fd = fd; - bl->ev = ev; - if(to > 0) - bl->to = time(NULL) + to; - bl->th = current; - bl->n = blockers; - if(blockers) - blockers->p = bl; - blockers = bl; - rv = yield(); - if(bl->n) - bl->n->p = bl->p; - if(bl->p) - bl->p->n = bl->n; - if(bl == blockers) - blockers = bl->n; - return(rv); -} +static int plex; static int listensock4(int port) { @@ -296,7 +258,7 @@ static off_t passdata(int src, int dst, struct charbuf *buf, off_t max) sent = 0; eof = 0; - while(!eof || (buf->d > 0)) { + while((!eof || (buf->d > 0)) && ((max < 0) || (sent < max))) { if(!eof && (buf->d < buf->s) && ((max < 0) || (sent + buf->d < max))) { while(1) { ret = recv(src, buf->b + buf->d, buf->s - buf->d, MSG_DONTWAIT); @@ -339,17 +301,17 @@ static void serve(struct muth *muth, va_list args) vavar(struct sockaddr_storage, name); int cfd; char old; - char *hd; + char *hd, *p; struct charbuf inbuf, outbuf; struct hthead *req, *resp; off_t dlen, sent; - size_t headoff; + ssize_t headoff; char nmbuf[256]; bufinit(inbuf); bufinit(outbuf); cfd = -1; - req = NULL; + req = resp = NULL; while(1) { /* * First, find and decode the header: @@ -369,6 +331,13 @@ static void serve(struct muth *muth, va_list args) goto out; inbuf.b[headoff] = old; bufeat(inbuf, headoff); + /* We strip off the leading slash and any param string from + * the rest string, so that multiplexers can parse + * coherently. */ + if(req->rest[0] == '/') + replrest(req, req->rest + 1); + if((p = strchr(req->rest, '?')) != NULL) + *p = 0; /* * Add metainformation and then send the request to the root @@ -381,7 +350,8 @@ static void serve(struct muth *muth, va_list args) headappheader(req, "X-Ash-Address", inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&name)->sin6_addr, nmbuf, sizeof(nmbuf))); headappheader(req, "X-Ash-Port", sprintf3("%i", ntohs(((struct sockaddr_in6 *)&name)->sin6_port))); } - cfd = sendreq(plex, req); + if((cfd = sendreq(plex, req)) < 0) + goto out; /* * If there is message data, pass it: @@ -391,12 +361,15 @@ static void serve(struct muth *muth, va_list args) if(dlen > 0) passdata(fd, cfd, &inbuf, dlen); } + /* Make sure to send EOF */ + shutdown(cfd, SHUT_WR); /* * Find and decode the response header: */ outbuf.d = 0; - headoff = readhead(cfd, &outbuf); + if((headoff = readhead(cfd, &outbuf)) < 0) + goto out; hd = memcpy(smalloc(headoff + 1), outbuf.b, headoff); hd[headoff] = 0; if((resp = parserawresp(hd)) == NULL) @@ -470,63 +443,6 @@ out: close(ss); } -static void ioloop(void) -{ - int ret; - fd_set rfds, wfds, efds; - struct blocker *bl, *nbl; - struct timeval toval; - time_t now, timeout; - int maxfd; - int ev; - - while(blockers != NULL) { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&efds); - maxfd = 0; - now = time(NULL); - timeout = 0; - for(bl = blockers; bl; bl = bl->n) { - if(bl->ev & EV_READ) - FD_SET(bl->fd, &rfds); - if(bl->ev & EV_WRITE) - FD_SET(bl->fd, &wfds); - FD_SET(bl->fd, &efds); - if(bl->fd > maxfd) - maxfd = bl->fd; - if((bl->to != 0) && ((timeout == 0) || (timeout > bl->to))) - timeout = bl->to; - } - toval.tv_sec = timeout - now; - toval.tv_usec = 0; - ret = select(maxfd + 1, &rfds, &wfds, &efds, timeout?(&toval):NULL); - if(ret < 0) { - if(errno != EINTR) { - flog(LOG_CRIT, "ioloop: select errored out: %s", strerror(errno)); - /* To avoid CPU hogging in case it's bad, which it - * probably is. */ - sleep(1); - } - } - now = time(NULL); - for(bl = blockers; bl; bl = nbl) { - nbl = bl->n; - ev = 0; - if(FD_ISSET(bl->fd, &rfds)) - ev |= EV_READ; - if(FD_ISSET(bl->fd, &wfds)) - ev |= EV_WRITE; - if(FD_ISSET(bl->fd, &efds)) - ev = -1; - if(ev != 0) - resume(bl->th, ev); - else if((bl->to != 0) && (bl->to <= now)) - resume(bl->th, 0); - } - } -} - int main(int argc, char **argv) { int fd;