14ca1ab94SDag-Erling Smørgrav /*- 24ca1ab94SDag-Erling Smørgrav * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav 34ca1ab94SDag-Erling Smørgrav * All rights reserved. 44ca1ab94SDag-Erling Smørgrav * 54ca1ab94SDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 64ca1ab94SDag-Erling Smørgrav * modification, are permitted provided that the following conditions 74ca1ab94SDag-Erling Smørgrav * are met: 84ca1ab94SDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 94ca1ab94SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer 104ca1ab94SDag-Erling Smørgrav * in this position and unchanged. 114ca1ab94SDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 124ca1ab94SDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 134ca1ab94SDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 144ca1ab94SDag-Erling Smørgrav * 3. The name of the author may not be used to endorse or promote products 154ca1ab94SDag-Erling Smørgrav * derived from this software without specific prior written permission 164ca1ab94SDag-Erling Smørgrav * 174ca1ab94SDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 184ca1ab94SDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 194ca1ab94SDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 204ca1ab94SDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 214ca1ab94SDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 224ca1ab94SDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234ca1ab94SDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244ca1ab94SDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254ca1ab94SDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 264ca1ab94SDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274ca1ab94SDag-Erling Smørgrav * 284ca1ab94SDag-Erling Smørgrav * $Id$ 294ca1ab94SDag-Erling Smørgrav */ 304ca1ab94SDag-Erling Smørgrav 314ca1ab94SDag-Erling Smørgrav #include <sys/param.h> 324ca1ab94SDag-Erling Smørgrav #include <sys/errno.h> 334ca1ab94SDag-Erling Smørgrav #include <sys/socket.h> 344ca1ab94SDag-Erling Smørgrav #include <sys/types.h> 354ca1ab94SDag-Erling Smørgrav 364ca1ab94SDag-Erling Smørgrav #include <netinet/in.h> 374ca1ab94SDag-Erling Smørgrav 384ca1ab94SDag-Erling Smørgrav #include <err.h> 394ca1ab94SDag-Erling Smørgrav #include <ctype.h> 404ca1ab94SDag-Erling Smørgrav #include <netdb.h> 414ca1ab94SDag-Erling Smørgrav #include <stdio.h> 424ca1ab94SDag-Erling Smørgrav #include <stdlib.h> 434ca1ab94SDag-Erling Smørgrav #include <string.h> 444ca1ab94SDag-Erling Smørgrav #include <unistd.h> 454ca1ab94SDag-Erling Smørgrav 464ca1ab94SDag-Erling Smørgrav #include "fetch.h" 474ca1ab94SDag-Erling Smørgrav #include "httperr.c" 484ca1ab94SDag-Erling Smørgrav 494ca1ab94SDag-Erling Smørgrav #ifndef NDEBUG 504ca1ab94SDag-Erling Smørgrav #define DEBUG(x) do x; while (0) 514ca1ab94SDag-Erling Smørgrav #else 524ca1ab94SDag-Erling Smørgrav #define DEBUG(x) do { } while (0) 534ca1ab94SDag-Erling Smørgrav #endif 544ca1ab94SDag-Erling Smørgrav 554ca1ab94SDag-Erling Smørgrav extern char *__progname; 564ca1ab94SDag-Erling Smørgrav 574ca1ab94SDag-Erling Smørgrav extern int fprint64(FILE *f, const unsigned char *buf); 584ca1ab94SDag-Erling Smørgrav 594ca1ab94SDag-Erling Smørgrav #define ENDL "\r\n" 604ca1ab94SDag-Erling Smørgrav 614ca1ab94SDag-Erling Smørgrav struct cookie 624ca1ab94SDag-Erling Smørgrav { 634ca1ab94SDag-Erling Smørgrav FILE *real_f; 644ca1ab94SDag-Erling Smørgrav #define ENC_NONE 0 654ca1ab94SDag-Erling Smørgrav #define ENC_CHUNKED 1 664ca1ab94SDag-Erling Smørgrav int encoding; /* 1 = chunked, 0 = none */ 674ca1ab94SDag-Erling Smørgrav #define HTTPCTYPELEN 59 684ca1ab94SDag-Erling Smørgrav char content_type[HTTPCTYPELEN+1]; 694ca1ab94SDag-Erling Smørgrav char *buf; 704ca1ab94SDag-Erling Smørgrav int b_cur, eof; 714ca1ab94SDag-Erling Smørgrav unsigned b_len, chunksize; 724ca1ab94SDag-Erling Smørgrav }; 734ca1ab94SDag-Erling Smørgrav 744ca1ab94SDag-Erling Smørgrav static int 754ca1ab94SDag-Erling Smørgrav _http_connect(char *host, int port) 764ca1ab94SDag-Erling Smørgrav { 774ca1ab94SDag-Erling Smørgrav struct sockaddr_in sin; 784ca1ab94SDag-Erling Smørgrav struct hostent *he; 794ca1ab94SDag-Erling Smørgrav int fd; 804ca1ab94SDag-Erling Smørgrav 814ca1ab94SDag-Erling Smørgrav /* look up host name */ 824ca1ab94SDag-Erling Smørgrav if ((he = gethostbyname(host)) == NULL) 834ca1ab94SDag-Erling Smørgrav return -1; 844ca1ab94SDag-Erling Smørgrav 854ca1ab94SDag-Erling Smørgrav /* set up socket address structure */ 864ca1ab94SDag-Erling Smørgrav bzero(&sin, sizeof(sin)); 874ca1ab94SDag-Erling Smørgrav bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length); 884ca1ab94SDag-Erling Smørgrav sin.sin_family = he->h_addrtype; 894ca1ab94SDag-Erling Smørgrav sin.sin_port = htons(port); 904ca1ab94SDag-Erling Smørgrav 914ca1ab94SDag-Erling Smørgrav /* try to connect */ 924ca1ab94SDag-Erling Smørgrav if ((fd = socket(sin.sin_family, SOCK_STREAM, 0)) < 0) 934ca1ab94SDag-Erling Smørgrav return -1; 944ca1ab94SDag-Erling Smørgrav if (connect(fd, (struct sockaddr *)&sin, sizeof sin) < 0) { 954ca1ab94SDag-Erling Smørgrav close(fd); 964ca1ab94SDag-Erling Smørgrav return -1; 974ca1ab94SDag-Erling Smørgrav } 984ca1ab94SDag-Erling Smørgrav 994ca1ab94SDag-Erling Smørgrav return fd; 1004ca1ab94SDag-Erling Smørgrav } 1014ca1ab94SDag-Erling Smørgrav 1024ca1ab94SDag-Erling Smørgrav static char * 1034ca1ab94SDag-Erling Smørgrav _http_fillbuf(struct cookie *c) 1044ca1ab94SDag-Erling Smørgrav { 1054ca1ab94SDag-Erling Smørgrav char *ln; 1064ca1ab94SDag-Erling Smørgrav unsigned int len; 1074ca1ab94SDag-Erling Smørgrav 1084ca1ab94SDag-Erling Smørgrav if (c->eof) 1094ca1ab94SDag-Erling Smørgrav return NULL; 1104ca1ab94SDag-Erling Smørgrav 1114ca1ab94SDag-Erling Smørgrav if (c->encoding == ENC_NONE) { 1124ca1ab94SDag-Erling Smørgrav c->buf = fgetln(c->real_f, &(c->b_len)); 1134ca1ab94SDag-Erling Smørgrav c->b_cur = 0; 1144ca1ab94SDag-Erling Smørgrav } else if (c->encoding == ENC_CHUNKED) { 1154ca1ab94SDag-Erling Smørgrav if (c->chunksize == 0) { 1164ca1ab94SDag-Erling Smørgrav ln = fgetln(c->real_f, &len); 1174ca1ab94SDag-Erling Smørgrav DEBUG(fprintf(stderr, "\033[1m_http_fillbuf(): new chunk: " 1184ca1ab94SDag-Erling Smørgrav "%*.*s\033[m\n", (int)len-2, (int)len-2, ln)); 1194ca1ab94SDag-Erling Smørgrav sscanf(ln, "%x", &(c->chunksize)); 1204ca1ab94SDag-Erling Smørgrav if (!c->chunksize) { 1214ca1ab94SDag-Erling Smørgrav DEBUG(fprintf(stderr, "\033[1m_http_fillbuf(): " 1224ca1ab94SDag-Erling Smørgrav "end of last chunk\033[m\n")); 1234ca1ab94SDag-Erling Smørgrav c->eof = 1; 1244ca1ab94SDag-Erling Smørgrav return NULL; 1254ca1ab94SDag-Erling Smørgrav } 1264ca1ab94SDag-Erling Smørgrav DEBUG(fprintf(stderr, "\033[1m_http_fillbuf(): " 1274ca1ab94SDag-Erling Smørgrav "new chunk: %X\033[m\n", c->chunksize)); 1284ca1ab94SDag-Erling Smørgrav } 1294ca1ab94SDag-Erling Smørgrav c->buf = fgetln(c->real_f, &(c->b_len)); 1304ca1ab94SDag-Erling Smørgrav if (c->b_len > c->chunksize) 1314ca1ab94SDag-Erling Smørgrav c->b_len = c->chunksize; 1324ca1ab94SDag-Erling Smørgrav c->chunksize -= c->b_len; 1334ca1ab94SDag-Erling Smørgrav c->b_cur = 0; 1344ca1ab94SDag-Erling Smørgrav } 1354ca1ab94SDag-Erling Smørgrav else return NULL; /* unknown encoding */ 1364ca1ab94SDag-Erling Smørgrav return c->buf; 1374ca1ab94SDag-Erling Smørgrav } 1384ca1ab94SDag-Erling Smørgrav 1394ca1ab94SDag-Erling Smørgrav static int 1404ca1ab94SDag-Erling Smørgrav _http_readfn(struct cookie *c, char *buf, int len) 1414ca1ab94SDag-Erling Smørgrav { 1424ca1ab94SDag-Erling Smørgrav int l, pos = 0; 1434ca1ab94SDag-Erling Smørgrav while (len) { 1444ca1ab94SDag-Erling Smørgrav /* empty buffer */ 1454ca1ab94SDag-Erling Smørgrav if (!c->buf || (c->b_cur == c->b_len)) 1464ca1ab94SDag-Erling Smørgrav if (!_http_fillbuf(c)) 1474ca1ab94SDag-Erling Smørgrav break; 1484ca1ab94SDag-Erling Smørgrav 1494ca1ab94SDag-Erling Smørgrav l = c->b_len - c->b_cur; 1504ca1ab94SDag-Erling Smørgrav if (len < l) l = len; 1514ca1ab94SDag-Erling Smørgrav memcpy(buf + pos, c->buf + c->b_cur, l); 1524ca1ab94SDag-Erling Smørgrav c->b_cur += l; 1534ca1ab94SDag-Erling Smørgrav pos += l; 1544ca1ab94SDag-Erling Smørgrav len -= l; 1554ca1ab94SDag-Erling Smørgrav } 1564ca1ab94SDag-Erling Smørgrav 1574ca1ab94SDag-Erling Smørgrav if (ferror(c->real_f)) 1584ca1ab94SDag-Erling Smørgrav return -1; 1594ca1ab94SDag-Erling Smørgrav else return pos; 1604ca1ab94SDag-Erling Smørgrav } 1614ca1ab94SDag-Erling Smørgrav 1624ca1ab94SDag-Erling Smørgrav static int 1634ca1ab94SDag-Erling Smørgrav _http_writefn(struct cookie *c, const char *buf, int len) 1644ca1ab94SDag-Erling Smørgrav { 1654ca1ab94SDag-Erling Smørgrav size_t r = fwrite(buf, 1, (size_t)len, c->real_f); 1664ca1ab94SDag-Erling Smørgrav return r ? r : -1; 1674ca1ab94SDag-Erling Smørgrav } 1684ca1ab94SDag-Erling Smørgrav 1694ca1ab94SDag-Erling Smørgrav static int 1704ca1ab94SDag-Erling Smørgrav _http_closefn(struct cookie *c) 1714ca1ab94SDag-Erling Smørgrav { 1724ca1ab94SDag-Erling Smørgrav int r = fclose(c->real_f); 1734ca1ab94SDag-Erling Smørgrav free(c); 1744ca1ab94SDag-Erling Smørgrav return (r == EOF) ? -1 : 0; 1754ca1ab94SDag-Erling Smørgrav } 1764ca1ab94SDag-Erling Smørgrav 1774ca1ab94SDag-Erling Smørgrav char * 1784ca1ab94SDag-Erling Smørgrav fetchContentType(FILE *f) 1794ca1ab94SDag-Erling Smørgrav { 1804ca1ab94SDag-Erling Smørgrav /* 1814ca1ab94SDag-Erling Smørgrav * We have no way of making sure this really *is* one of our cookies, 1824ca1ab94SDag-Erling Smørgrav * so just check for a null pointer and hope for the best. 1834ca1ab94SDag-Erling Smørgrav */ 1844ca1ab94SDag-Erling Smørgrav return f->_cookie ? (((struct cookie *)f->_cookie)->content_type) : NULL; 1854ca1ab94SDag-Erling Smørgrav } 1864ca1ab94SDag-Erling Smørgrav 1874ca1ab94SDag-Erling Smørgrav FILE * 1884ca1ab94SDag-Erling Smørgrav fetchGetHTTP(url_t *URL, char *flags) 1894ca1ab94SDag-Erling Smørgrav { 1904ca1ab94SDag-Erling Smørgrav int fd = -1, err, i, enc = ENC_NONE; 1914ca1ab94SDag-Erling Smørgrav struct cookie *c; 1924ca1ab94SDag-Erling Smørgrav char *ln, *p, *q; 1934ca1ab94SDag-Erling Smørgrav FILE *f, *cf; 1944ca1ab94SDag-Erling Smørgrav size_t len; 1954ca1ab94SDag-Erling Smørgrav 1964ca1ab94SDag-Erling Smørgrav /* allocate cookie */ 1974ca1ab94SDag-Erling Smørgrav if ((c = calloc(1, sizeof(struct cookie))) == NULL) 1984ca1ab94SDag-Erling Smørgrav return NULL; 1994ca1ab94SDag-Erling Smørgrav 2004ca1ab94SDag-Erling Smørgrav /* check port */ 2014ca1ab94SDag-Erling Smørgrav if (!URL->port) 2024ca1ab94SDag-Erling Smørgrav URL->port = 80; /* default HTTP port */ 2034ca1ab94SDag-Erling Smørgrav 2044ca1ab94SDag-Erling Smørgrav /* attempt to connect to proxy server */ 2054ca1ab94SDag-Erling Smørgrav if (getenv("HTTP_PROXY")) { 2064ca1ab94SDag-Erling Smørgrav char *px, host[MAXHOSTNAMELEN]; 2074ca1ab94SDag-Erling Smørgrav int port = 3128; /* XXX I think 3128 is default... check? */ 2084ca1ab94SDag-Erling Smørgrav size_t len; 2094ca1ab94SDag-Erling Smørgrav 2104ca1ab94SDag-Erling Smørgrav /* measure length */ 2114ca1ab94SDag-Erling Smørgrav px = getenv("HTTP_PROXY"); 2124ca1ab94SDag-Erling Smørgrav len = strcspn(px, ":"); 2134ca1ab94SDag-Erling Smørgrav 2144ca1ab94SDag-Erling Smørgrav /* get port (atoi is a little too tolerant perhaps?) */ 2154ca1ab94SDag-Erling Smørgrav if (px[len] == ':') 2164ca1ab94SDag-Erling Smørgrav port = atoi(px+len+1); 2174ca1ab94SDag-Erling Smørgrav 2184ca1ab94SDag-Erling Smørgrav /* get host name */ 2194ca1ab94SDag-Erling Smørgrav if (len >= MAXHOSTNAMELEN) 2204ca1ab94SDag-Erling Smørgrav len = MAXHOSTNAMELEN - 1; 2214ca1ab94SDag-Erling Smørgrav strncpy(host, px, len); 2224ca1ab94SDag-Erling Smørgrav host[len] = 0; 2234ca1ab94SDag-Erling Smørgrav 2244ca1ab94SDag-Erling Smørgrav /* connect */ 2254ca1ab94SDag-Erling Smørgrav fd = _http_connect(host, port); 2264ca1ab94SDag-Erling Smørgrav } 2274ca1ab94SDag-Erling Smørgrav 2284ca1ab94SDag-Erling Smørgrav /* if no proxy is configured or could be contacted, try direct */ 2294ca1ab94SDag-Erling Smørgrav if (fd < 0) { 2304ca1ab94SDag-Erling Smørgrav if ((fd = _http_connect(URL->host, URL->port)) < 0) 2314ca1ab94SDag-Erling Smørgrav goto ouch; 2324ca1ab94SDag-Erling Smørgrav } 2334ca1ab94SDag-Erling Smørgrav 2344ca1ab94SDag-Erling Smørgrav /* reopen as stream */ 2354ca1ab94SDag-Erling Smørgrav if ((f = fdopen(fd, "r+")) == NULL) 2364ca1ab94SDag-Erling Smørgrav goto ouch; 2374ca1ab94SDag-Erling Smørgrav c->real_f = f; 2384ca1ab94SDag-Erling Smørgrav 2394ca1ab94SDag-Erling Smørgrav /* send request (proxies require absolute form, so use that) */ 2404ca1ab94SDag-Erling Smørgrav fprintf(f, "GET http://%s:%d/%s HTTP/1.1" ENDL, 2414ca1ab94SDag-Erling Smørgrav URL->host, URL->port, URL->doc); 2424ca1ab94SDag-Erling Smørgrav 2434ca1ab94SDag-Erling Smørgrav /* start sending headers away */ 2444ca1ab94SDag-Erling Smørgrav if (URL->user[0] || URL->pwd[0]) { 2454ca1ab94SDag-Erling Smørgrav fprintf(f, "Authorization: Basic "); 2464ca1ab94SDag-Erling Smørgrav fprint64(f, (const unsigned char *)URL->user); 2474ca1ab94SDag-Erling Smørgrav fputc(':', f); 2484ca1ab94SDag-Erling Smørgrav fprint64(f, (const unsigned char *)URL->pwd); 2494ca1ab94SDag-Erling Smørgrav fputs(ENDL, f); 2504ca1ab94SDag-Erling Smørgrav } 2514ca1ab94SDag-Erling Smørgrav fprintf(f, "Host: %s:%d" ENDL, URL->host, URL->port); 2524ca1ab94SDag-Erling Smørgrav fprintf(f, "User-Agent: %s " _LIBFETCH_VER ENDL, __progname); 2534ca1ab94SDag-Erling Smørgrav fprintf(f, "Connection: close" ENDL ENDL); 2544ca1ab94SDag-Erling Smørgrav 2554ca1ab94SDag-Erling Smørgrav /* get response */ 2564ca1ab94SDag-Erling Smørgrav if ((ln = fgetln(f, &len)) == NULL) 2574ca1ab94SDag-Erling Smørgrav goto fouch; 2584ca1ab94SDag-Erling Smørgrav DEBUG(fprintf(stderr, "response: [\033[1m%*.*s\033[m]\n", 2594ca1ab94SDag-Erling Smørgrav (int)len-2, (int)len-2, ln)); 2604ca1ab94SDag-Erling Smørgrav 2614ca1ab94SDag-Erling Smørgrav /* we can't use strchr() and friends since ln isn't NUL-terminated */ 2624ca1ab94SDag-Erling Smørgrav p = ln; 2634ca1ab94SDag-Erling Smørgrav while ((p < ln + len) && !isspace(*p)) 2644ca1ab94SDag-Erling Smørgrav p++; 2654ca1ab94SDag-Erling Smørgrav while ((p < ln + len) && !isdigit(*p)) 2664ca1ab94SDag-Erling Smørgrav p++; 2674ca1ab94SDag-Erling Smørgrav if (!isdigit(*p)) 2684ca1ab94SDag-Erling Smørgrav goto fouch; 2694ca1ab94SDag-Erling Smørgrav err = atoi(p); 2704ca1ab94SDag-Erling Smørgrav DEBUG(fprintf(stderr, "code: [\033[1m%d\033[m]\n", err)); 2714ca1ab94SDag-Erling Smørgrav 2724ca1ab94SDag-Erling Smørgrav /* add code to handle redirects later */ 2734ca1ab94SDag-Erling Smørgrav if (err != 200) 2744ca1ab94SDag-Erling Smørgrav goto fouch; 2754ca1ab94SDag-Erling Smørgrav 2764ca1ab94SDag-Erling Smørgrav /* browse through header */ 2774ca1ab94SDag-Erling Smørgrav while (1) { 2784ca1ab94SDag-Erling Smørgrav if ((ln = fgetln(f, &len)) == NULL) 2794ca1ab94SDag-Erling Smørgrav goto fouch; 2804ca1ab94SDag-Erling Smørgrav if ((ln[0] == '\r') || (ln[0] == '\n')) 2814ca1ab94SDag-Erling Smørgrav break; 2824ca1ab94SDag-Erling Smørgrav DEBUG(fprintf(stderr, "header: [\033[1m%*.*s\033[m]\n", 2834ca1ab94SDag-Erling Smørgrav (int)len-2, (int)len-2, ln)); 2844ca1ab94SDag-Erling Smørgrav #define XFERENC "Transfer-Encoding:" 2854ca1ab94SDag-Erling Smørgrav if (strncasecmp(ln, XFERENC, sizeof(XFERENC)-1) == 0) { 2864ca1ab94SDag-Erling Smørgrav p = ln + sizeof(XFERENC) - 1; 2874ca1ab94SDag-Erling Smørgrav while ((p < ln + len) && isspace(*p)) 2884ca1ab94SDag-Erling Smørgrav p++; 2894ca1ab94SDag-Erling Smørgrav for (q = p; (q < ln + len) && !isspace(*q); q++) 2904ca1ab94SDag-Erling Smørgrav /* VOID */ ; 2914ca1ab94SDag-Erling Smørgrav *q = 0; 2924ca1ab94SDag-Erling Smørgrav if (strcasecmp(p, "chunked") == 0) 2934ca1ab94SDag-Erling Smørgrav enc = ENC_CHUNKED; 2944ca1ab94SDag-Erling Smørgrav DEBUG(fprintf(stderr, "xferenc: [\033[1m%s\033[m]\n", p)); 2954ca1ab94SDag-Erling Smørgrav #undef XFERENC 2964ca1ab94SDag-Erling Smørgrav #define CONTTYPE "Content-Type:" 2974ca1ab94SDag-Erling Smørgrav } else if (strncasecmp(ln, CONTTYPE, sizeof(CONTTYPE)-1) == 0) { 2984ca1ab94SDag-Erling Smørgrav p = ln + sizeof(CONTTYPE) - 1; 2994ca1ab94SDag-Erling Smørgrav while ((p < ln + len) && isspace(*p)) 3004ca1ab94SDag-Erling Smørgrav p++; 3014ca1ab94SDag-Erling Smørgrav for (i = 0; p < ln + len; p++) 3024ca1ab94SDag-Erling Smørgrav if (i < HTTPCTYPELEN) 3034ca1ab94SDag-Erling Smørgrav c->content_type[i++] = *p; 3044ca1ab94SDag-Erling Smørgrav do c->content_type[i--] = 0; while (isspace(c->content_type[i])); 3054ca1ab94SDag-Erling Smørgrav DEBUG(fprintf(stderr, "conttype: [\033[1m%s\033[m]\n", 3064ca1ab94SDag-Erling Smørgrav c->content_type)); 3074ca1ab94SDag-Erling Smørgrav #undef CONTTYPE 3084ca1ab94SDag-Erling Smørgrav } 3094ca1ab94SDag-Erling Smørgrav } 3104ca1ab94SDag-Erling Smørgrav 3114ca1ab94SDag-Erling Smørgrav /* only body remains */ 3124ca1ab94SDag-Erling Smørgrav c->encoding = enc; 3134ca1ab94SDag-Erling Smørgrav cf = funopen(c, 3144ca1ab94SDag-Erling Smørgrav (int (*)(void *, char *, int))_http_readfn, 3154ca1ab94SDag-Erling Smørgrav (int (*)(void *, const char *, int))_http_writefn, 3164ca1ab94SDag-Erling Smørgrav (fpos_t (*)(void *, fpos_t, int))NULL, 3174ca1ab94SDag-Erling Smørgrav (int (*)(void *))_http_closefn); 3184ca1ab94SDag-Erling Smørgrav if (cf == NULL) 3194ca1ab94SDag-Erling Smørgrav goto fouch; 3204ca1ab94SDag-Erling Smørgrav return cf; 3214ca1ab94SDag-Erling Smørgrav 3224ca1ab94SDag-Erling Smørgrav ouch: 3234ca1ab94SDag-Erling Smørgrav if (fd >= 0) 3244ca1ab94SDag-Erling Smørgrav close(fd); 3254ca1ab94SDag-Erling Smørgrav free(c); 3264ca1ab94SDag-Erling Smørgrav return NULL; 3274ca1ab94SDag-Erling Smørgrav fouch: 3284ca1ab94SDag-Erling Smørgrav fclose(f); 3294ca1ab94SDag-Erling Smørgrav free(c); 3304ca1ab94SDag-Erling Smørgrav return NULL; 3314ca1ab94SDag-Erling Smørgrav } 3324ca1ab94SDag-Erling Smørgrav 3334ca1ab94SDag-Erling Smørgrav FILE * 3344ca1ab94SDag-Erling Smørgrav fetchPutHTTP(url_t *URL, char *flags) 3354ca1ab94SDag-Erling Smørgrav { 3364ca1ab94SDag-Erling Smørgrav warnx("fetchPutHTTP(): not implemented"); 3374ca1ab94SDag-Erling Smørgrav return NULL; 3384ca1ab94SDag-Erling Smørgrav } 339