Ignore:
Timestamp:
Jul 26, 2011, 1:36:30 AM (10 years ago)
Author:
livings124
Message:

#4387 Update miniupnpc to 1.6

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/third-party/miniupnp/miniwget.c

    r11577 r12593  
    1 /* $Id: miniwget.c,v 1.41 2010/12/12 23:52:02 nanard Exp $ */
     1/* $Id: miniwget.c,v 1.52 2011/06/17 22:59:42 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas Bernard
    4  * Copyright (c) 2005-2010 Thomas Bernard
     4 * Copyright (c) 2005-2011 Thomas Bernard
    55 * This software is subject to the conditions detailed in the
    66 * LICENCE file provided in this distribution. */
     
    1010#include <string.h>
    1111#include <ctype.h>
    12 #include "miniupnpc.h"
    1312#ifdef WIN32
    1413#include <winsock2.h>
     
    1918#define snprintf _snprintf
    2019#define socklen_t int
     20#ifndef strncasecmp
    2121#if defined(_MSC_VER) && (_MSC_VER >= 1400)
    2222#define strncasecmp _memicmp
     
    2424#define strncasecmp memicmp
    2525#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
     26#endif /* #ifndef strncasecmp */
    2627#else /* #ifdef WIN32 */
    2728#include <unistd.h>
     
    4748#include "miniwget.h"
    4849#include "connecthostport.h"
     50#include "receivedata.h"
    4951
    5052/*
    5153 * Read a HTTP response from a socket.
    5254 * Process Content-Length and Transfer-encoding headers.
     55 * return a pointer to the content buffer, which length is saved
     56 * to the length parameter.
    5357 */
    5458void *
     
    5761        char buf[2048];
    5862        int n;
    59         int headers = 1;
     63        int endofheaders = 0;
    6064        int chunked = 0;
    6165        int content_length = -1;
     
    6973        int content_buf_len = 2048;
    7074        int content_buf_used = 0;
     75        char chunksize_buf[32];
     76        int chunksize_buf_index;
    7177
    7278        header_buf = malloc(header_buf_len);
    7379        content_buf = malloc(content_buf_len);
    74 
    75         while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
    76         {
    77                 if(headers)
     80        chunksize_buf[0] = '\0';
     81        chunksize_buf_index = 0;
     82
     83        while((n = receivedata(s, buf, 2048, 5000)) > 0)
     84        {
     85                if(endofheaders == 0)
    7886                {
    7987                        int i;
     
    8795                        memcpy(header_buf + header_buf_used, buf, n);
    8896                        header_buf_used += n;
    89                         for(i = 0; i < (header_buf_used-3); i++) {
     97                        /* search for CR LF CR LF (end of headers)
     98                         * recognize also LF LF */
     99                        i = 0;
     100                        while(i < (header_buf_used-1) && (endofheaders == 0)) {
     101                                if(header_buf[i] == '\r') {
     102                                        i++;
     103                                        if(header_buf[i] == '\n') {
     104                                                i++;
     105                                                if(i < header_buf_used && header_buf[i] == '\r') {
     106                                                        i++;
     107                                                        if(i < header_buf_used && header_buf[i] == '\n') {
     108                                                                endofheaders = i+1;
     109                                                        }
     110                                                }
     111                                        }
     112                                } else if(header_buf[i] == '\n') {
     113                                        i++;
     114                                        if(header_buf[i] == '\n') {
     115                                                endofheaders = i+1;
     116                                        }
     117                                }
     118                                i++;
     119                        }
     120                        if(endofheaders == 0)
     121                                continue;
     122                        /* parse header lines */
     123                        for(i = 0; i < endofheaders - 1; i++) {
    90124                                if(colon <= linestart && header_buf[i]==':')
    91125                                {
    92126                                        colon = i;
    93                                         while(i < (n-3)
     127                                        while(i < (endofheaders-1)
    94128                                              && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
    95129                                                i++;
     
    97131                                }
    98132                                /* detecting end of line */
    99                                 else if(header_buf[i]=='\r' && header_buf[i+1]=='\n')
     133                                else if(header_buf[i]=='\r' || header_buf[i]=='\n')
    100134                                {
    101135                                        if(colon > linestart && valuestart > colon)
     
    114148                                                }
    115149                                                else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
    116                                                    && 0==strncasecmp(buf+valuestart, "chunked", 7))
     150                                                   && 0==strncasecmp(header_buf+valuestart, "chunked", 7))
    117151                                                {
    118152#ifdef DEBUG
     
    122156                                                }
    123157                                        }
    124                                         linestart = i+2;
     158                                        while(header_buf[i]=='\r' || header_buf[i] == '\n')
     159                                                i++;
     160                                        linestart = i;
    125161                                        colon = linestart;
    126162                                        valuestart = 0;
    127163                                }
    128                                 /* searching for the end of the HTTP headers */
    129                                 if(header_buf[i]=='\r' && header_buf[i+1]=='\n'
    130                                    && header_buf[i+2]=='\r' && header_buf[i+3]=='\n')
    131                                 {
    132                                         headers = 0;    /* end */
    133                                         i += 4;
    134                                         if(i < header_buf_used)
    135                                         {
    136                                                 if(chunked)
    137                                                 {
    138                                                         while(i<header_buf_used)
    139                                                         {
    140                                                                 while(i<header_buf_used && isxdigit(header_buf[i]))
    141                                                                 {
    142                                                                         if(header_buf[i] >= '0' && header_buf[i] <= '9')
    143                                                                                 chunksize = (chunksize << 4) + (header_buf[i] - '0');
    144                                                                         else
    145                                                                                 chunksize = (chunksize << 4) + ((header_buf[i] | 32) - 'a' + 10);
    146                                                                         i++;
    147                                                                 }
    148                                                                 /* discarding chunk-extension */
    149                                                                 while(i < header_buf_used && header_buf[i] != '\r') i++;
    150                                                                 if(i < header_buf_used && header_buf[i] == '\r') i++;
    151                                                                 if(i < header_buf_used && header_buf[i] == '\n') i++;
    152 #ifdef DEBUG
    153                                                                 printf("chunksize = %u (%x)\n", chunksize, chunksize);
    154 #endif
    155                                                                 if(chunksize == 0)
    156                                                                 {
    157 #ifdef DEBUG
    158                                                                         printf("end of HTTP content !\n");
    159 #endif
    160                                                                         goto end_of_stream;     
    161                                                                 }
    162                                                                 bytestocopy = ((int)chunksize < header_buf_used - i)?chunksize:(header_buf_used - i);
    163 #ifdef DEBUG
    164                                                                 printf("chunksize=%u bytestocopy=%u (i=%d header_buf_used=%d)\n",
    165                                                                        chunksize, bytestocopy, i, header_buf_used);
    166 #endif
    167                                                                 if(content_buf_len < (int)(content_buf_used + bytestocopy))
    168                                                                 {
    169                                                                         content_buf = realloc(content_buf, content_buf_used + bytestocopy);
    170                                                                         content_buf_len = content_buf_used + bytestocopy;
    171                                                                 }
    172                                                                 memcpy(content_buf + content_buf_used, header_buf + i, bytestocopy);
    173                                                                 content_buf_used += bytestocopy;
    174                                                                 chunksize -= bytestocopy;
    175                                                                 i += bytestocopy;
    176                                                         }
    177                                                 }
    178                                                 else
    179                                                 {
    180                                                         if(content_buf_len < header_buf_used - i)
    181                                                         {
    182                                                                 content_buf = realloc(content_buf, header_buf_used - i);
    183                                                                 content_buf_len = header_buf_used - i;
    184                                                         }
    185                                                         memcpy(content_buf, header_buf + i, header_buf_used - i);
    186                                                         content_buf_used = header_buf_used - i;
    187                                                         i = header_buf_used;
    188                                                 }
    189                                         }
    190                                 }
    191                         }
    192                 }
    193                 else
     164                        }
     165                        /* copy the remaining of the received data back to buf */
     166                        n = header_buf_used - endofheaders;
     167                        memcpy(buf, header_buf + endofheaders, n);
     168                        /* if(headers) */
     169                }
     170                if(endofheaders)
    194171                {
    195172                        /* content */
     
    202179                                        {
    203180                                                /* reading chunk size */
     181                                                if(chunksize_buf_index == 0) {
     182                                                        /* skipping any leading CR LF */
     183                                                        if(i<n && buf[i] == '\r') i++;
     184                                                        if(i<n && buf[i] == '\n') i++;
     185                                                }
     186                                                while(i<n && isxdigit(buf[i])
     187                                                     && chunksize_buf_index < (sizeof(chunksize_buf)-1))
     188                                                {
     189                                                        chunksize_buf[chunksize_buf_index++] = buf[i];
     190                                                        chunksize_buf[chunksize_buf_index] = '\0';
     191                                                        i++;
     192                                                }
     193                                                while(i<n && buf[i] != '\r' && buf[i] != '\n')
     194                                                        i++; /* discarding chunk-extension */
    204195                                                if(i<n && buf[i] == '\r') i++;
    205                                                 if(i<n && buf[i] == '\n') i++;
    206                                                 while(i<n && isxdigit(buf[i]))
    207                                                 {
    208                                                         if(buf[i] >= '0' && buf[i] <= '9')
    209                                                                 chunksize = (chunksize << 4) + (buf[i] - '0');
     196                                                if(i<n && buf[i] == '\n') {
     197                                                        int j;
     198                                                        for(j = 0; j < chunksize_buf_index; j++) {
     199                                                        if(chunksize_buf[j] >= '0'
     200                                                           && chunksize_buf[j] <= '9')
     201                                                                chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
    210202                                                        else
    211                                                                 chunksize = (chunksize << 4) + ((buf[i] | 32) - 'a' + 10);
     203                                                                chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
     204                                                        }
     205                                                        chunksize_buf[0] = '\0';
     206                                                        chunksize_buf_index = 0;
    212207                                                        i++;
    213                                                 }
    214                                                 while(i<n && buf[i] != '\r') i++; /* discarding chunk-extension */
    215                                                 if(i<n && buf[i] == '\r') i++;
    216                                                 if(i<n && buf[i] == '\n') i++;
     208                                                } else {
     209                                                        /* not finished to get chunksize */
     210                                                        continue;
     211                                                }
    217212#ifdef DEBUG
    218213                                                printf("chunksize = %u (%x)\n", chunksize, chunksize);
     
    230225                                        if((int)(content_buf_used + bytestocopy) > content_buf_len)
    231226                                        {
     227                                                if(content_length >= content_buf_used + (int)bytestocopy) {
     228                                                        content_buf_len = content_length;
     229                                                } else {
     230                                                        content_buf_len = content_buf_used + (int)bytestocopy;
     231                                                }
    232232                                                content_buf = (char *)realloc((void *)content_buf,
    233                                                                               content_buf_used + bytestocopy);
    234                                                 content_buf_len = content_buf_used + bytestocopy;
     233                                                                              content_buf_len);
    235234                                        }
    236235                                        memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
     
    242241                        else
    243242                        {
     243                                /* not chunked */
     244                                if(content_length > 0
     245                                   && (content_buf_used + n) > content_length) {
     246                                        /* skipping additional bytes */
     247                                        n = content_length - content_buf_used;
     248                                }
    244249                                if(content_buf_used + n > content_buf_len)
    245250                                {
     251                                        if(content_length >= content_buf_used + n) {
     252                                                content_buf_len = content_length;
     253                                        } else {
     254                                                content_buf_len = content_buf_used + n;
     255                                        }
    246256                                        content_buf = (char *)realloc((void *)content_buf,
    247                                                                       content_buf_used + n);
    248                                         content_buf_len = content_buf_used + n;
     257                                                                      content_buf_len);
    249258                                }
    250259                                memcpy(content_buf + content_buf_used, buf, n);
     
    252261                        }
    253262                }
     263                /* use the Content-Length header value if available */
    254264                if(content_length > 0 && content_buf_used >= content_length)
    255265                {
     
    276286static void *
    277287miniwget3(const char * url, const char * host,
    278                   unsigned short port, const char * path,
    279                   int * size, char * addr_str, int addr_str_len, const char * httpversion)
     288          unsigned short port, const char * path,
     289          int * size, char * addr_str, int addr_str_len,
     290          const char * httpversion)
    280291{
    281292        char buf[2048];
     
    284295        int len;
    285296        int sent;
     297        void * content;
    286298
    287299        *size = 0;
     
    293305        if(addr_str)
    294306        {
    295                 struct sockaddr saddr;
     307                struct sockaddr_storage saddr;
    296308                socklen_t saddrlen;
    297309
    298310                saddrlen = sizeof(saddr);
    299                 if(getsockname(s, &saddr, &saddrlen) < 0)
     311                if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
    300312                {
    301313                        perror("getsockname");
     
    311323                    printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
    312324                }*/
     325                        /* the following code is only compatible with ip v4 addresses */
    313326                        strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
    314327#else
    315                         /*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/
    316                         n = getnameinfo(&saddr, saddrlen,
     328#if 0
     329                        if(saddr.sa_family == AF_INET6) {
     330                                inet_ntop(AF_INET6,
     331                                          &(((struct sockaddr_in6 *)&saddr)->sin6_addr),
     332                                          addr_str, addr_str_len);
     333                        } else {
     334                                inet_ntop(AF_INET,
     335                                          &(((struct sockaddr_in *)&saddr)->sin_addr),
     336                                          addr_str, addr_str_len);
     337                        }
     338#endif
     339                        /* getnameinfo return ip v6 address with the scope identifier
     340                         * such as : 2a01:e35:8b2b:7330::%4281128194 */
     341                        n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
    317342                                        addr_str, addr_str_len,
    318343                                        NULL, 0,
     
    356381                }
    357382        }
    358         return getHTTPResponse(s, size);
     383        content = getHTTPResponse(s, size);
     384        closesocket(s);
     385        return content;
    359386}
    360387
     
    399426{
    400427        char * p1, *p2, *p3;
     428        if(!url)
     429                return 0;
    401430        p1 = strstr(url, "://");
    402431        if(!p1)
     
    406435           ||(url[2]!='t') || (url[3]!='p'))
    407436                return 0;
     437        memset(hostname, 0, MAXHOSTNAMELEN + 1);
     438        if(*p1 == '[')
     439        {
     440                /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
     441                p2 = strchr(p1, ']');
     442                p3 = strchr(p1, '/');
     443                if(p2 && p3)
     444                {
     445                        p2++;
     446                        strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
     447                        if(*p2 == ':')
     448                        {
     449                                *port = 0;
     450                                p2++;
     451                                while( (*p2 >= '0') && (*p2 <= '9'))
     452                                {
     453                                        *port *= 10;
     454                                        *port += (unsigned short)(*p2 - '0');
     455                                        p2++;
     456                                }
     457                        }
     458                        else
     459                        {
     460                                *port = 80;
     461                        }
     462                        *path = p3;
     463                        return 1;
     464                }
     465        }
    408466        p2 = strchr(p1, ':');
    409467        p3 = strchr(p1, '/');
    410468        if(!p3)
    411469                return 0;
    412         memset(hostname, 0, MAXHOSTNAMELEN + 1);
    413470        if(!p2 || (p2>p3))
    414471        {
     
    441498        if(!parseURL(url, hostname, &port, &path))
    442499                return NULL;
     500#ifdef DEBUG
     501        printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
     502#endif
    443503        return miniwget2(url, hostname, port, path, size, 0, 0);
    444504}
     
    455515        if(!parseURL(url, hostname, &port, &path))
    456516                return NULL;
     517#ifdef DEBUG
     518        printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
     519#endif
    457520        return miniwget2(url, hostname, port, path, size, addr, addrlen);
    458521}
Note: See TracChangeset for help on using the changeset viewer.