From f4663439b18d84214325e4d3ba50b79c029b79e9 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Wed, 20 Jun 2007 02:56:50 +0200 Subject: [PATCH] Incremental work. --- common/http.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/http.h | 9 ++++++ 2 files changed, 106 insertions(+) diff --git a/common/http.c b/common/http.c index f09ac3c..923e6d6 100644 --- a/common/http.c +++ b/common/http.c @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -29,6 +30,9 @@ #include #include +#define STATE_SYN 0 +#define STATE_TXREQ 1 + void freeurl(struct hturlinfo *ui) { free(ui->host); @@ -51,6 +55,8 @@ struct hturlinfo *parseurl(char *url) if((p3 = strrchr(p, ':')) != NULL) { *(p3++) = 0; ui->port = atoi(p3); + } else { + ui->port = 80; } ui->host = sstrdup(p); if(p2 == NULL) { @@ -68,3 +74,94 @@ struct hturlinfo *parseurl(char *url) } return(ui); } + +static struct hturlinfo *dupurl(struct hturlinfo *ui) +{ + struct hturlinfo *new; + + new = memset(smalloc(sizeof(*new)), 0, sizeof(*new)); + new->host = sstrdup(ui->host); + new->port = ui->port; + new->path = sstrdup(ui->path); + new->query = sstrdup(ui->query); + return(new); +} + +static struct addrinfo *resolvtcp(char *name, int port) +{ + struct addrinfo hint, *ret; + char tmp[32]; + + memset(&hint, 0, sizeof(hint)); + hint.ai_socktype = SOCK_STREAM; + hint.ai_flags = AI_NUMERICSERV | AI_CANONNAME; + snprintf(tmp, sizeof(tmp), "%i", port); + if(!getaddrinfo(name, tmp, &hint, &ret)) + return(ret); + return(NULL); +} + +void freehtconn(struct htconn *cn) +{ + if(cn->outbuf != NULL) + free(cn->outbuf); + if(cn->inbuf != NULL) + free(cn->inbuf); + freeurl(cn->url); + freeaddrinfo(cn->ailist); + if(cn->fd != -1) + close(cn->fd); + free(cn); +} + +struct htconn *htconnect(struct hturlinfo *ui) +{ + struct htconn *cn; + + cn = memset(smalloc(sizeof(*cn)), 0, sizeof(*cn)); + cn->fd = -1; + cn->url = dupurl(ui); + cn->ailist = resolvtcp(ui->host, ui->port); + return(cn); +} + +int htpollflags(struct htconn *hc) +{ + int ret; + + ret = POLLIN; + if(hc->outbufdata > 0) + ret |= POLLOUT; + return(ret); +} + +int htprocess(struct htconn *hc) +{ + int ret; + socklen_t optlen; + + if(hc->state == STATE_SYN) { + if(hc->fd != -1) { + optlen = sizeof(ret); + getsockopt(hc->fd, SOL_SOCKET, SO_ERROR, &ret, &optlen); + if(ret) { + hc->fd = -1; + } else { + hc->state = STATE_TXREQ; + } + } + if(hc->fd == -1) { + if(hc->curai == NULL) + hc->curai = hc->ailist; + else + hc->curai = hc->curai->ai_next; + if(hc->curai == NULL) { + /* Bleh! Linux and BSD don't share any good + * errno for this. */ + errno = ENOENT; + return(-1); + } + } + } + return(0); +} diff --git a/include/http.h b/include/http.h index 0456d5a..e6d1020 100644 --- a/include/http.h +++ b/include/http.h @@ -20,6 +20,8 @@ #ifndef _HTTP_H #define _HTTP_H +#include + struct hturlinfo { char *host; int port; @@ -28,7 +30,9 @@ struct hturlinfo { }; struct htconn { + int state; int fd; + struct addrinfo *ailist, *curai; char *outbuf, *inbuf; size_t outbufsize, outbufdata; size_t inbufsize, inbufdata; @@ -40,4 +44,9 @@ struct htcookie { char *name, *val; }; +struct hturlinfo *parseurl(char *url); +void freeurl(struct hturlinfo *ui); +struct htconn *htconnect(struct hturlinfo *ui); +int htpollflags(struct htconn *hc); + #endif -- 2.11.0