Annotation of embedaddon/miniupnpc/src/miniwget.c, revision 1.1.1.1

1.1       misho       1: /* $Id: miniwget.c,v 1.84 2020/11/09 19:41:18 nanard Exp $ */
                      2: /* Project : miniupnp
                      3:  * Website : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
                      4:  * Author : Thomas Bernard
                      5:  * Copyright (c) 2005-2020 Thomas Bernard
                      6:  * This software is subject to the conditions detailed in the
                      7:  * LICENCE file provided in this distribution. */
                      8: 
                      9: #include <stdio.h>
                     10: #include <stdlib.h>
                     11: #include <string.h>
                     12: #include <ctype.h>
                     13: #ifdef _WIN32
                     14: #include <winsock2.h>
                     15: #include <ws2tcpip.h>
                     16: #include <io.h>
                     17: #define MAXHOSTNAMELEN 64
                     18: #include "win32_snprintf.h"
                     19: #define socklen_t int
                     20: #ifndef strncasecmp
                     21: #if defined(_MSC_VER) && (_MSC_VER >= 1400)
                     22: #define strncasecmp _memicmp
                     23: #else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
                     24: #define strncasecmp memicmp
                     25: #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
                     26: #endif /* #ifndef strncasecmp */
                     27: #else /* #ifdef _WIN32 */
                     28: #include <unistd.h>
                     29: #include <sys/param.h>
                     30: #if defined(__amigaos__) && !defined(__amigaos4__)
                     31: #define socklen_t int
                     32: #else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
                     33: #include <sys/select.h>
                     34: #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
                     35: #include <sys/socket.h>
                     36: #include <netinet/in.h>
                     37: #include <arpa/inet.h>
                     38: #include <net/if.h>
                     39: #include <netdb.h>
                     40: #define closesocket close
                     41: #include <strings.h>
                     42: #endif /* #else _WIN32 */
                     43: #ifdef __GNU__
                     44: #define MAXHOSTNAMELEN 64
                     45: #endif /* __GNU__ */
                     46: 
                     47: #ifndef MIN
                     48: #define MIN(x,y) (((x)<(y))?(x):(y))
                     49: #endif /* MIN */
                     50: 
                     51: 
                     52: #include "miniupnpcstrings.h"
                     53: #include "miniwget.h"
                     54: #include "connecthostport.h"
                     55: #include "receivedata.h"
                     56: 
                     57: #ifndef MAXHOSTNAMELEN
                     58: #define MAXHOSTNAMELEN 64
                     59: #endif
                     60: 
                     61: /*
                     62:  * Read a HTTP response from a socket.
                     63:  * Process Content-Length and Transfer-encoding headers.
                     64:  * return a pointer to the content buffer, which length is saved
                     65:  * to the length parameter.
                     66:  */
                     67: void *
                     68: getHTTPResponse(SOCKET s, int * size, int * status_code)
                     69: {
                     70:        char buf[2048];
                     71:        int n;
                     72:        int endofheaders = 0;
                     73:        int chunked = 0;
                     74:        int content_length = -1;
                     75:        unsigned int chunksize = 0;
                     76:        unsigned int bytestocopy = 0;
                     77:        /* buffers : */
                     78:        char * header_buf;
                     79:        unsigned int header_buf_len = 2048;
                     80:        unsigned int header_buf_used = 0;
                     81:        char * content_buf;
                     82:        unsigned int content_buf_len = 2048;
                     83:        unsigned int content_buf_used = 0;
                     84:        char chunksize_buf[32];
                     85:        unsigned int chunksize_buf_index;
                     86: #ifdef DEBUG
                     87:        char * reason_phrase = NULL;
                     88:        int reason_phrase_len = 0;
                     89: #endif
                     90: 
                     91:        if(status_code) *status_code = -1;
                     92:        header_buf = malloc(header_buf_len);
                     93:        if(header_buf == NULL)
                     94:        {
                     95: #ifdef DEBUG
                     96:                fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse");
                     97: #endif /* DEBUG */
                     98:                *size = -1;
                     99:                return NULL;
                    100:        }
                    101:        content_buf = malloc(content_buf_len);
                    102:        if(content_buf == NULL)
                    103:        {
                    104:                free(header_buf);
                    105: #ifdef DEBUG
                    106:                fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse");
                    107: #endif /* DEBUG */
                    108:                *size = -1;
                    109:                return NULL;
                    110:        }
                    111:        chunksize_buf[0] = '\0';
                    112:        chunksize_buf_index = 0;
                    113: 
                    114:        while((n = receivedata(s, buf, sizeof(buf), 5000, NULL)) > 0)
                    115:        {
                    116:                if(endofheaders == 0)
                    117:                {
                    118:                        int i;
                    119:                        int linestart=0;
                    120:                        int colon=0;
                    121:                        int valuestart=0;
                    122:                        if(header_buf_used + n > header_buf_len) {
                    123:                                char * tmp = realloc(header_buf, header_buf_used + n);
                    124:                                if(tmp == NULL) {
                    125:                                        /* memory allocation error */
                    126:                                        free(header_buf);
                    127:                                        free(content_buf);
                    128:                                        *size = -1;
                    129:                                        return NULL;
                    130:                                }
                    131:                                header_buf = tmp;
                    132:                                header_buf_len = header_buf_used + n;
                    133:                        }
                    134:                        memcpy(header_buf + header_buf_used, buf, n);
                    135:                        header_buf_used += n;
                    136:                        /* search for CR LF CR LF (end of headers)
                    137:                         * recognize also LF LF */
                    138:                        i = 0;
                    139:                        while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
                    140:                                if(header_buf[i] == '\r') {
                    141:                                        i++;
                    142:                                        if(header_buf[i] == '\n') {
                    143:                                                i++;
                    144:                                                if(i < (int)header_buf_used && header_buf[i] == '\r') {
                    145:                                                        i++;
                    146:                                                        if(i < (int)header_buf_used && header_buf[i] == '\n') {
                    147:                                                                endofheaders = i+1;
                    148:                                                        }
                    149:                                                }
                    150:                                        }
                    151:                                } else if(header_buf[i] == '\n') {
                    152:                                        i++;
                    153:                                        if(header_buf[i] == '\n') {
                    154:                                                endofheaders = i+1;
                    155:                                        }
                    156:                                }
                    157:                                i++;
                    158:                        }
                    159:                        if(endofheaders == 0)
                    160:                                continue;
                    161:                        /* parse header lines */
                    162:                        for(i = 0; i < endofheaders - 1; i++) {
                    163:                                if(linestart > 0 && colon <= linestart && header_buf[i]==':')
                    164:                                {
                    165:                                        colon = i;
                    166:                                        while(i < (endofheaders-1)
                    167:                                              && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
                    168:                                                i++;
                    169:                                        valuestart = i + 1;
                    170:                                }
                    171:                                /* detecting end of line */
                    172:                                else if(header_buf[i]=='\r' || header_buf[i]=='\n')
                    173:                                {
                    174:                                        if(linestart == 0 && status_code)
                    175:                                        {
                    176:                                                /* Status line
                    177:                                                 * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */
                    178:                                                int sp;
                    179:                                                for(sp = 0; sp < i - 1; sp++)
                    180:                                                        if(header_buf[sp] == ' ')
                    181:                                                        {
                    182:                                                                if(*status_code < 0)
                    183:                                                                {
                    184:                                                                        if (header_buf[sp+1] >= '1' && header_buf[sp+1] <= '9')
                    185:                                                                                *status_code = atoi(header_buf + sp + 1);
                    186:                                                                }
                    187:                                                                else
                    188:                                                                {
                    189: #ifdef DEBUG
                    190:                                                                        reason_phrase = header_buf + sp + 1;
                    191:                                                                        reason_phrase_len = i - sp - 1;
                    192: #endif
                    193:                                                                        break;
                    194:                                                                }
                    195:                                                        }
                    196: #ifdef DEBUG
                    197:                                                printf("HTTP status code = %d, Reason phrase = %.*s\n",
                    198:                                                       *status_code, reason_phrase_len, reason_phrase);
                    199: #endif
                    200:                                        }
                    201:                                        else if(colon > linestart && valuestart > colon)
                    202:                                        {
                    203: #ifdef DEBUG
                    204:                                                printf("header='%.*s', value='%.*s'\n",
                    205:                                                       colon-linestart, header_buf+linestart,
                    206:                                                       i-valuestart, header_buf+valuestart);
                    207: #endif
                    208:                                                if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart))
                    209:                                                {
                    210:                                                        content_length = atoi(header_buf+valuestart);
                    211: #ifdef DEBUG
                    212:                                                        printf("Content-Length: %d\n", content_length);
                    213: #endif
                    214:                                                }
                    215:                                                else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
                    216:                                                   && 0==strncasecmp(header_buf+valuestart, "chunked", 7))
                    217:                                                {
                    218: #ifdef DEBUG
                    219:                                                        printf("chunked transfer-encoding!\n");
                    220: #endif
                    221:                                                        chunked = 1;
                    222:                                                }
                    223:                                        }
                    224:                                        while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n'))
                    225:                                                i++;
                    226:                                        linestart = i;
                    227:                                        colon = linestart;
                    228:                                        valuestart = 0;
                    229:                                }
                    230:                        }
                    231:                        /* copy the remaining of the received data back to buf */
                    232:                        n = header_buf_used - endofheaders;
                    233:                        memcpy(buf, header_buf + endofheaders, n);
                    234:                        /* if(headers) */
                    235:                }
                    236:                /* if we get there, endofheaders != 0.
                    237:                 * In the other case, there was a continue above */
                    238:                /* content */
                    239:                if(chunked)
                    240:                {
                    241:                        int i = 0;
                    242:                        while(i < n)
                    243:                        {
                    244:                                if(chunksize == 0)
                    245:                                {
                    246:                                        /* reading chunk size */
                    247:                                        if(chunksize_buf_index == 0) {
                    248:                                                /* skipping any leading CR LF */
                    249:                                                if(buf[i] == '\r') i++;
                    250:                                                if(i<n && buf[i] == '\n') i++;
                    251:                                        }
                    252:                                        while(i<n && isxdigit(buf[i])
                    253:                                             && chunksize_buf_index < (sizeof(chunksize_buf)-1))
                    254:                                        {
                    255:                                                chunksize_buf[chunksize_buf_index++] = buf[i];
                    256:                                                chunksize_buf[chunksize_buf_index] = '\0';
                    257:                                                i++;
                    258:                                        }
                    259:                                        while(i<n && buf[i] != '\r' && buf[i] != '\n')
                    260:                                                i++; /* discarding chunk-extension */
                    261:                                        if(i<n && buf[i] == '\r') i++;
                    262:                                        if(i<n && buf[i] == '\n') {
                    263:                                                unsigned int j;
                    264:                                                for(j = 0; j < chunksize_buf_index; j++) {
                    265:                                                if(chunksize_buf[j] >= '0'
                    266:                                                   && chunksize_buf[j] <= '9')
                    267:                                                        chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
                    268:                                                else
                    269:                                                        chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
                    270:                                                }
                    271:                                                chunksize_buf[0] = '\0';
                    272:                                                chunksize_buf_index = 0;
                    273:                                                i++;
                    274:                                        } else {
                    275:                                                /* not finished to get chunksize */
                    276:                                                continue;
                    277:                                        }
                    278: #ifdef DEBUG
                    279:                                        printf("chunksize = %u (%x)\n", chunksize, chunksize);
                    280: #endif
                    281:                                        if(chunksize == 0)
                    282:                                        {
                    283: #ifdef DEBUG
                    284:                                                printf("end of HTTP content - %d %d\n", i, n);
                    285:                                                /*printf("'%.*s'\n", n-i, buf+i);*/
                    286: #endif
                    287:                                                goto end_of_stream;
                    288:                                        }
                    289:                                }
                    290:                                /* it is guaranteed that (n >= i) */
                    291:                                bytestocopy = (chunksize < (unsigned int)(n - i))?chunksize:(unsigned int)(n - i);
                    292:                                if((content_buf_used + bytestocopy) > content_buf_len)
                    293:                                {
                    294:                                        char * tmp;
                    295:                                        if((content_length >= 0) && ((unsigned int)content_length >= (content_buf_used + bytestocopy))) {
                    296:                                                content_buf_len = content_length;
                    297:                                        } else {
                    298:                                                content_buf_len = content_buf_used + bytestocopy;
                    299:                                        }
                    300:                                        tmp = realloc(content_buf, content_buf_len);
                    301:                                        if(tmp == NULL) {
                    302:                                                /* memory allocation error */
                    303:                                                free(content_buf);
                    304:                                                free(header_buf);
                    305:                                                *size = -1;
                    306:                                                return NULL;
                    307:                                        }
                    308:                                        content_buf = tmp;
                    309:                                }
                    310:                                memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
                    311:                                content_buf_used += bytestocopy;
                    312:                                i += bytestocopy;
                    313:                                chunksize -= bytestocopy;
                    314:                        }
                    315:                }
                    316:                else
                    317:                {
                    318:                        /* not chunked */
                    319:                        if(content_length > 0
                    320:                           && (content_buf_used + n) > (unsigned int)content_length) {
                    321:                                /* skipping additional bytes */
                    322:                                n = content_length - content_buf_used;
                    323:                        }
                    324:                        if(content_buf_used + n > content_buf_len)
                    325:                        {
                    326:                                char * tmp;
                    327:                                if(content_length >= 0
                    328:                                   && (unsigned int)content_length >= (content_buf_used + n)) {
                    329:                                        content_buf_len = content_length;
                    330:                                } else {
                    331:                                        content_buf_len = content_buf_used + n;
                    332:                                }
                    333:                                tmp = realloc(content_buf, content_buf_len);
                    334:                                if(tmp == NULL) {
                    335:                                        /* memory allocation error */
                    336:                                        free(content_buf);
                    337:                                        free(header_buf);
                    338:                                        *size = -1;
                    339:                                        return NULL;
                    340:                                }
                    341:                                content_buf = tmp;
                    342:                        }
                    343:                        memcpy(content_buf + content_buf_used, buf, n);
                    344:                        content_buf_used += n;
                    345:                }
                    346:                /* use the Content-Length header value if available */
                    347:                if(content_length > 0 && content_buf_used >= (unsigned int)content_length)
                    348:                {
                    349: #ifdef DEBUG
                    350:                        printf("End of HTTP content\n");
                    351: #endif
                    352:                        break;
                    353:                }
                    354:        }
                    355: end_of_stream:
                    356:        free(header_buf);
                    357:        *size = content_buf_used;
                    358:        if(content_buf_used == 0)
                    359:        {
                    360:                free(content_buf);
                    361:                content_buf = NULL;
                    362:        }
                    363:        return content_buf;
                    364: }
                    365: 
                    366: /* miniwget3() :
                    367:  * do all the work.
                    368:  * Return NULL if something failed. */
                    369: static void *
                    370: miniwget3(const char * host,
                    371:           unsigned short port, const char * path,
                    372:           int * size, char * addr_str, int addr_str_len,
                    373:           const char * httpversion, unsigned int scope_id,
                    374:           int * status_code)
                    375: {
                    376:        char buf[2048];
                    377:        SOCKET s;
                    378:        int n;
                    379:        int len;
                    380:        int sent;
                    381:        void * content;
                    382: 
                    383:        *size = 0;
                    384:        s = connecthostport(host, port, scope_id);
                    385:        if(ISINVALID(s))
                    386:                return NULL;
                    387: 
                    388:        /* get address for caller ! */
                    389:        if(addr_str)
                    390:        {
                    391:                struct sockaddr_storage saddr;
                    392:                socklen_t saddrlen;
                    393: 
                    394:                saddrlen = sizeof(saddr);
                    395:                if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
                    396:                {
                    397:                        perror("getsockname");
                    398:                }
                    399:                else
                    400:                {
                    401: #if defined(__amigaos__) && !defined(__amigaos4__)
                    402:        /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
                    403:      * But his function make a string with the port :  nn.nn.nn.nn:port */
                    404: /*             if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
                    405:                             NULL, addr_str, (DWORD *)&addr_str_len))
                    406:                {
                    407:                    printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
                    408:                }*/
                    409:                        /* the following code is only compatible with ip v4 addresses */
                    410:                        strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
                    411: #else
                    412: #if 0
                    413:                        if(saddr.sa_family == AF_INET6) {
                    414:                                inet_ntop(AF_INET6,
                    415:                                          &(((struct sockaddr_in6 *)&saddr)->sin6_addr),
                    416:                                          addr_str, addr_str_len);
                    417:                        } else {
                    418:                                inet_ntop(AF_INET,
                    419:                                          &(((struct sockaddr_in *)&saddr)->sin_addr),
                    420:                                          addr_str, addr_str_len);
                    421:                        }
                    422: #endif
                    423:                        /* getnameinfo return ip v6 address with the scope identifier
                    424:                         * such as : 2a01:e35:8b2b:7330::%4281128194 */
                    425:                        n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
                    426:                                        addr_str, addr_str_len,
                    427:                                        NULL, 0,
                    428:                                        NI_NUMERICHOST | NI_NUMERICSERV);
                    429:                        if(n != 0) {
                    430: #ifdef _WIN32
                    431:                                fprintf(stderr, "getnameinfo() failed : %d\n", n);
                    432: #else
                    433:                                fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
                    434: #endif
                    435:                        }
                    436: #endif
                    437:                }
                    438: #ifdef DEBUG
                    439:                printf("address miniwget : %s\n", addr_str);
                    440: #endif
                    441:        }
                    442: 
                    443:        len = snprintf(buf, sizeof(buf),
                    444:                  "GET %s HTTP/%s\r\n"
                    445:                             "Host: %s:%d\r\n"
                    446:                                 "Connection: Close\r\n"
                    447:                                 "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
                    448: 
                    449:                                 "\r\n",
                    450:                           path, httpversion, host, port);
                    451:        if ((unsigned int)len >= sizeof(buf))
                    452:        {
                    453:                closesocket(s);
                    454:                return NULL;
                    455:        }
                    456:        sent = 0;
                    457:        /* sending the HTTP request */
                    458:        while(sent < len)
                    459:        {
                    460:                n = send(s, buf+sent, len-sent, 0);
                    461:                if(n < 0)
                    462:                {
                    463:                        perror("send");
                    464:                        closesocket(s);
                    465:                        return NULL;
                    466:                }
                    467:                else
                    468:                {
                    469:                        sent += n;
                    470:                }
                    471:        }
                    472:        content = getHTTPResponse(s, size, status_code);
                    473:        closesocket(s);
                    474:        return content;
                    475: }
                    476: 
                    477: /* miniwget2() :
                    478:  * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
                    479: static void *
                    480: miniwget2(const char * host,
                    481:           unsigned short port, const char * path,
                    482:           int * size, char * addr_str, int addr_str_len,
                    483:           unsigned int scope_id, int * status_code)
                    484: {
                    485:        char * respbuffer;
                    486: 
                    487: #if 1
                    488:        respbuffer = miniwget3(host, port, path, size,
                    489:                               addr_str, addr_str_len, "1.1",
                    490:                               scope_id, status_code);
                    491: #else
                    492:        respbuffer = miniwget3(host, port, path, size,
                    493:                               addr_str, addr_str_len, "1.0",
                    494:                               scope_id, status_code);
                    495:        if (*size == 0)
                    496:        {
                    497: #ifdef DEBUG
                    498:                printf("Retrying with HTTP/1.1\n");
                    499: #endif
                    500:                free(respbuffer);
                    501:                respbuffer = miniwget3(host, port, path, size,
                    502:                                       addr_str, addr_str_len, "1.1",
                    503:                                       scope_id, status_code);
                    504:        }
                    505: #endif
                    506:        return respbuffer;
                    507: }
                    508: 
                    509: 
                    510: 
                    511: 
                    512: /* parseURL()
                    513:  * arguments :
                    514:  *   url :             source string not modified
                    515:  *   hostname :        hostname destination string (size of MAXHOSTNAMELEN+1)
                    516:  *   port :            port (destination)
                    517:  *   path :            pointer to the path part of the URL
                    518:  *
                    519:  * Return values :
                    520:  *    0 - Failure
                    521:  *    1 - Success         */
                    522: int
                    523: parseURL(const char * url,
                    524:          char * hostname, unsigned short * port,
                    525:          char * * path, unsigned int * scope_id)
                    526: {
                    527:        char * p1, *p2, *p3;
                    528:        if(!url)
                    529:                return 0;
                    530:        p1 = strstr(url, "://");
                    531:        if(!p1)
                    532:                return 0;
                    533:        p1 += 3;
                    534:        if(  (url[0]!='h') || (url[1]!='t')
                    535:           ||(url[2]!='t') || (url[3]!='p'))
                    536:                return 0;
                    537:        memset(hostname, 0, MAXHOSTNAMELEN + 1);
                    538:        if(*p1 == '[')
                    539:        {
                    540:                /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
                    541:                char * scope;
                    542:                scope = strchr(p1, '%');
                    543:                p2 = strchr(p1, ']');
                    544:                if(p2 && scope && scope < p2 && scope_id) {
                    545:                        /* parse scope */
                    546: #ifdef IF_NAMESIZE
                    547:                        char tmp[IF_NAMESIZE];
                    548:                        int l;
                    549:                        scope++;
                    550:                        /* "%25" is just '%' in URL encoding */
                    551:                        if(scope[0] == '2' && scope[1] == '5')
                    552:                                scope += 2;     /* skip "25" */
                    553:                        l = p2 - scope;
                    554:                        if(l >= IF_NAMESIZE)
                    555:                                l = IF_NAMESIZE - 1;
                    556:                        memcpy(tmp, scope, l);
                    557:                        tmp[l] = '\0';
                    558:                        *scope_id = if_nametoindex(tmp);
                    559:                        if(*scope_id == 0) {
                    560:                                *scope_id = (unsigned int)strtoul(tmp, NULL, 10);
                    561:                        }
                    562: #else
                    563:                        /* under windows, scope is numerical */
                    564:                        char tmp[8];
                    565:                        size_t l;
                    566:                        scope++;
                    567:                        /* "%25" is just '%' in URL encoding */
                    568:                        if(scope[0] == '2' && scope[1] == '5')
                    569:                                scope += 2;     /* skip "25" */
                    570:                        l = p2 - scope;
                    571:                        if(l >= sizeof(tmp))
                    572:                                l = sizeof(tmp) - 1;
                    573:                        memcpy(tmp, scope, l);
                    574:                        tmp[l] = '\0';
                    575:                        *scope_id = (unsigned int)strtoul(tmp, NULL, 10);
                    576: #endif
                    577:                }
                    578:                p3 = strchr(p1, '/');
                    579:                if(p2 && p3)
                    580:                {
                    581:                        p2++;
                    582:                        strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
                    583:                        if(*p2 == ':')
                    584:                        {
                    585:                                *port = 0;
                    586:                                p2++;
                    587:                                while( (*p2 >= '0') && (*p2 <= '9'))
                    588:                                {
                    589:                                        *port *= 10;
                    590:                                        *port += (unsigned short)(*p2 - '0');
                    591:                                        p2++;
                    592:                                }
                    593:                        }
                    594:                        else
                    595:                        {
                    596:                                *port = 80;
                    597:                        }
                    598:                        *path = p3;
                    599:                        return 1;
                    600:                }
                    601:        }
                    602:        p2 = strchr(p1, ':');
                    603:        p3 = strchr(p1, '/');
                    604:        if(!p3)
                    605:                return 0;
                    606:        if(!p2 || (p2>p3))
                    607:        {
                    608:                strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
                    609:                *port = 80;
                    610:        }
                    611:        else
                    612:        {
                    613:                strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
                    614:                *port = 0;
                    615:                p2++;
                    616:                while( (*p2 >= '0') && (*p2 <= '9'))
                    617:                {
                    618:                        *port *= 10;
                    619:                        *port += (unsigned short)(*p2 - '0');
                    620:                        p2++;
                    621:                }
                    622:        }
                    623:        *path = p3;
                    624:        return 1;
                    625: }
                    626: 
                    627: void *
                    628: miniwget(const char * url, int * size,
                    629:          unsigned int scope_id, int * status_code)
                    630: {
                    631:        unsigned short port;
                    632:        char * path;
                    633:        /* protocol://host:port/chemin */
                    634:        char hostname[MAXHOSTNAMELEN+1];
                    635:        *size = 0;
                    636:        if(!parseURL(url, hostname, &port, &path, &scope_id))
                    637:                return NULL;
                    638: #ifdef DEBUG
                    639:        printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
                    640:               hostname, port, path, scope_id);
                    641: #endif
                    642:        return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code);
                    643: }
                    644: 
                    645: void *
                    646: miniwget_getaddr(const char * url, int * size,
                    647:                  char * addr, int addrlen, unsigned int scope_id,
                    648:                  int * status_code)
                    649: {
                    650:        unsigned short port;
                    651:        char * path;
                    652:        /* protocol://host:port/path */
                    653:        char hostname[MAXHOSTNAMELEN+1];
                    654:        *size = 0;
                    655:        if(addr)
                    656:                addr[0] = '\0';
                    657:        if(!parseURL(url, hostname, &port, &path, &scope_id))
                    658:                return NULL;
                    659: #ifdef DEBUG
                    660:        printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
                    661:               hostname, port, path, scope_id);
                    662: #endif
                    663:        return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code);
                    664: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>