X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=common%2Fhttp.c;fp=common%2Fhttp.c;h=923e6d68f6639f5ae747fdc15be99d392ad3d3e9;hb=f4663439b18d84214325e4d3ba50b79c029b79e9;hp=f09ac3cef54a10fbc02d5b4274d94e616a99c6ab;hpb=061d5c595dcaa3082efc92cfe467cae9cd5e2f52;p=doldaconnect.git 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); +}