Diff for /embedaddon/miniupnpc/miniwget.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 23:16:22 version 1.1.1.2, 2013/07/22 00:36:10
Line 1 Line 1
 /* $Id$ */  /* $Id$ */
 /* Project : miniupnp  /* Project : miniupnp
    * Website : http://miniupnp.free.fr/
  * Author : Thomas Bernard   * Author : Thomas Bernard
 * Copyright (c) 2005-2011 Thomas Bernard * Copyright (c) 2005-2012 Thomas Bernard
  * This software is subject to the conditions detailed in the   * This software is subject to the conditions detailed in the
  * LICENCE file provided in this distribution. */   * LICENCE file provided in this distribution. */
 
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <ctype.h>  #include <ctype.h>
#ifdef WIN32#ifdef _WIN32
 #include <winsock2.h>  #include <winsock2.h>
 #include <ws2tcpip.h>  #include <ws2tcpip.h>
 #include <io.h>  #include <io.h>
Line 24 Line 25
 #define strncasecmp memicmp  #define strncasecmp memicmp
 #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */  #endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
 #endif /* #ifndef strncasecmp */  #endif /* #ifndef strncasecmp */
#else /* #ifdef WIN32 */#else /* #ifdef _WIN32 */
 #include <unistd.h>  #include <unistd.h>
 #include <sys/param.h>  #include <sys/param.h>
 #if defined(__amigaos__) && !defined(__amigaos4__)  #if defined(__amigaos__) && !defined(__amigaos4__)
Line 33 Line 34
 #include <sys/select.h>  #include <sys/select.h>
 #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */  #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
 #include <sys/socket.h>  #include <sys/socket.h>
   #include <netinet/in.h>
 #include <arpa/inet.h>  #include <arpa/inet.h>
   #include <net/if.h>
 #include <netdb.h>  #include <netdb.h>
 #define closesocket close  #define closesocket close
 /* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions  /* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
  * during the connect() call */   * during the connect() call */
 #define MINIUPNPC_IGNORE_EINTR  #define MINIUPNPC_IGNORE_EINTR
#endif /* #else WIN32 */#endif /* #else _WIN32 */
 #if defined(__sun) || defined(sun)  #if defined(__sun) || defined(sun)
 #define MIN(x,y) (((x)<(y))?(x):(y))  #define MIN(x,y) (((x)<(y))?(x):(y))
 #endif  #endif
Line 67  getHTTPResponse(int s, int * size) Line 70  getHTTPResponse(int s, int * size)
         unsigned int bytestocopy = 0;          unsigned int bytestocopy = 0;
         /* buffers : */          /* buffers : */
         char * header_buf;          char * header_buf;
        int header_buf_len = 2048;        unsigned int header_buf_len = 2048;
        int header_buf_used = 0;        unsigned int header_buf_used = 0;
         char * content_buf;          char * content_buf;
        int content_buf_len = 2048;        unsigned int content_buf_len = 2048;
        int content_buf_used = 0;        unsigned int content_buf_used = 0;
         char chunksize_buf[32];          char chunksize_buf[32];
        int chunksize_buf_index;        unsigned int chunksize_buf_index;
   
         header_buf = malloc(header_buf_len);          header_buf = malloc(header_buf_len);
         content_buf = malloc(content_buf_len);          content_buf = malloc(content_buf_len);
         chunksize_buf[0] = '\0';          chunksize_buf[0] = '\0';
         chunksize_buf_index = 0;          chunksize_buf_index = 0;
   
        while((n = receivedata(s, buf, 2048, 5000)) > 0)        while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0)
         {          {
                 if(endofheaders == 0)                  if(endofheaders == 0)
                 {                  {
Line 97  getHTTPResponse(int s, int * size) Line 100  getHTTPResponse(int s, int * size)
                         /* search for CR LF CR LF (end of headers)                          /* search for CR LF CR LF (end of headers)
                          * recognize also LF LF */                           * recognize also LF LF */
                         i = 0;                          i = 0;
                        while(i < (header_buf_used-1) && (endofheaders == 0)) {                        while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
                                 if(header_buf[i] == '\r') {                                  if(header_buf[i] == '\r') {
                                         i++;                                          i++;
                                         if(header_buf[i] == '\n') {                                          if(header_buf[i] == '\n') {
                                                 i++;                                                  i++;
                                                if(i < header_buf_used && header_buf[i] == '\r') {                                                if(i < (int)header_buf_used && header_buf[i] == '\r') {
                                                         i++;                                                          i++;
                                                        if(i < header_buf_used && header_buf[i] == '\n') {                                                        if(i < (int)header_buf_used && header_buf[i] == '\n') {
                                                                 endofheaders = i+1;                                                                  endofheaders = i+1;
                                                         }                                                          }
                                                 }                                                  }
Line 160  getHTTPResponse(int s, int * size) Line 163  getHTTPResponse(int s, int * size)
                                         linestart = i;                                          linestart = i;
                                         colon = linestart;                                          colon = linestart;
                                         valuestart = 0;                                          valuestart = 0;
                                }                                 }
                         }                          }
                         /* copy the remaining of the received data back to buf */                          /* copy the remaining of the received data back to buf */
                         n = header_buf_used - endofheaders;                          n = header_buf_used - endofheaders;
Line 194  getHTTPResponse(int s, int * size) Line 197  getHTTPResponse(int s, int * size)
                                                         i++; /* discarding chunk-extension */                                                          i++; /* discarding chunk-extension */
                                                 if(i<n && buf[i] == '\r') i++;                                                  if(i<n && buf[i] == '\r') i++;
                                                 if(i<n && buf[i] == '\n') {                                                  if(i<n && buf[i] == '\n') {
                                                        int j;                                                        unsigned int j;
                                                         for(j = 0; j < chunksize_buf_index; j++) {                                                          for(j = 0; j < chunksize_buf_index; j++) {
                                                         if(chunksize_buf[j] >= '0'                                                          if(chunksize_buf[j] >= '0'
                                                            && chunksize_buf[j] <= '9')                                                             && chunksize_buf[j] <= '9')
Line 221  getHTTPResponse(int s, int * size) Line 224  getHTTPResponse(int s, int * size)
                                                         goto end_of_stream;                                                          goto end_of_stream;
                                                 }                                                  }
                                         }                                          }
                                        bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i);                                        bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i);
                                        if((int)(content_buf_used + bytestocopy) > content_buf_len)                                        if((content_buf_used + bytestocopy) > content_buf_len)
                                         {                                          {
                                                if(content_length >= content_buf_used + (int)bytestocopy) {                                                if(content_length >= (int)(content_buf_used + bytestocopy)) {
                                                         content_buf_len = content_length;                                                          content_buf_len = content_length;
                                                 } else {                                                  } else {
                                                        content_buf_len = content_buf_used + (int)bytestocopy;                                                        content_buf_len = content_buf_used + bytestocopy;
                                                 }                                                  }
                                                content_buf = (char *)realloc((void *)content_buf,                                                 content_buf = (char *)realloc((void *)content_buf,
                                                                               content_buf_len);                                                                                content_buf_len);
                                         }                                          }
                                         memcpy(content_buf + content_buf_used, buf + i, bytestocopy);                                          memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
Line 242  getHTTPResponse(int s, int * size) Line 245  getHTTPResponse(int s, int * size)
                         {                          {
                                 /* not chunked */                                  /* not chunked */
                                 if(content_length > 0                                  if(content_length > 0
                                   && (content_buf_used + n) > content_length) {                                   && (int)(content_buf_used + n) > content_length) {
                                         /* skipping additional bytes */                                          /* skipping additional bytes */
                                         n = content_length - content_buf_used;                                          n = content_length - content_buf_used;
                                 }                                  }
                                 if(content_buf_used + n > content_buf_len)                                  if(content_buf_used + n > content_buf_len)
                                 {                                  {
                                        if(content_length >= content_buf_used + n) {                                        if(content_length >= (int)(content_buf_used + n)) {
                                                 content_buf_len = content_length;                                                  content_buf_len = content_length;
                                         } else {                                          } else {
                                                 content_buf_len = content_buf_used + n;                                                  content_buf_len = content_buf_used + n;
                                         }                                          }
                                        content_buf = (char *)realloc((void *)content_buf,                                         content_buf = (char *)realloc((void *)content_buf,
                                                                       content_buf_len);                                                                        content_buf_len);
                                 }                                  }
                                 memcpy(content_buf + content_buf_used, buf, n);                                  memcpy(content_buf + content_buf_used, buf, n);
Line 261  getHTTPResponse(int s, int * size) Line 264  getHTTPResponse(int s, int * size)
                         }                          }
                 }                  }
                 /* use the Content-Length header value if available */                  /* use the Content-Length header value if available */
                if(content_length > 0 && content_buf_used >= content_length)                if(content_length > 0 && (int)content_buf_used >= content_length)
                 {                  {
 #ifdef DEBUG  #ifdef DEBUG
                         printf("End of HTTP content\n");                          printf("End of HTTP content\n");
Line 284  end_of_stream: Line 287  end_of_stream:
  * do all the work.   * do all the work.
  * Return NULL if something failed. */   * Return NULL if something failed. */
 static void *  static void *
miniwget3(const char * url, const char * host,miniwget3(const char * host,
           unsigned short port, const char * path,            unsigned short port, const char * path,
           int * size, char * addr_str, int addr_str_len,            int * size, char * addr_str, int addr_str_len,
          const char * httpversion)          const char * httpversion, unsigned int scope_id)
 {  {
         char buf[2048];          char buf[2048];
     int s;      int s;
Line 297  miniwget3(const char * url, const char * host, Line 300  miniwget3(const char * url, const char * host,
         void * content;          void * content;
   
         *size = 0;          *size = 0;
        s = connecthostport(host, port);        s = connecthostport(host, port, scope_id);
         if(s < 0)          if(s < 0)
                 return NULL;                  return NULL;
   
Line 343  miniwget3(const char * url, const char * host, Line 346  miniwget3(const char * url, const char * host,
                                         NULL, 0,                                          NULL, 0,
                                         NI_NUMERICHOST | NI_NUMERICSERV);                                          NI_NUMERICHOST | NI_NUMERICSERV);
                         if(n != 0) {                          if(n != 0) {
#ifdef WIN32#ifdef _WIN32
                                 fprintf(stderr, "getnameinfo() failed : %d\n", n);                                  fprintf(stderr, "getnameinfo() failed : %d\n", n);
 #else  #else
                                 fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));                                  fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
Line 388  miniwget3(const char * url, const char * host, Line 391  miniwget3(const char * url, const char * host,
 /* miniwget2() :  /* miniwget2() :
  * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */   * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
 static void *  static void *
miniwget2(const char * url, const char * host,miniwget2(const char * host,
                   unsigned short port, const char * path,                    unsigned short port, const char * path,
                  int * size, char * addr_str, int addr_str_len)                  int * size, char * addr_str, int addr_str_len,
           unsigned int scope_id)
 {  {
         char * respbuffer;          char * respbuffer;
   
        respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");#if 1
/*        respbuffer = miniwget3(host, port, path, size,
        respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");                               addr_str, addr_str_len, "1.1", scope_id);
 #else
         respbuffer = miniwget3(host, port, path, size,
                                addr_str, addr_str_len, "1.0", scope_id);
         if (*size == 0)          if (*size == 0)
         {          {
 #ifdef DEBUG  #ifdef DEBUG
                 printf("Retrying with HTTP/1.1\n");                  printf("Retrying with HTTP/1.1\n");
 #endif  #endif
                 free(respbuffer);                  free(respbuffer);
                respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");                respbuffer = miniwget3(host, port, path, size,
                                        addr_str, addr_str_len, "1.1", scope_id);
         }          }
*/#endif
         return respbuffer;          return respbuffer;
 }  }
   
Line 417  miniwget2(const char * url, const char * host, Line 425  miniwget2(const char * url, const char * host,
  *   url :              source string not modified   *   url :              source string not modified
  *   hostname : hostname destination string (size of MAXHOSTNAMELEN+1)   *   hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
  *   port :             port (destination)   *   port :             port (destination)
 *   path :             pointer to the path part of the URL  *   path :             pointer to the path part of the URL
  *   *
  * Return values :   * Return values :
  *    0 - Failure   *    0 - Failure
  *    1 - Success         */   *    1 - Success         */
int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)int
 parseURL(const char * url,
          char * hostname, unsigned short * port,
          char * * path, unsigned int * scope_id)
 {  {
         char * p1, *p2, *p3;          char * p1, *p2, *p3;
         if(!url)          if(!url)
Line 438  int parseURL(const char * url, char * hostname, unsign Line 449  int parseURL(const char * url, char * hostname, unsign
         if(*p1 == '[')          if(*p1 == '[')
         {          {
                 /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */                  /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
                   char * scope;
                   scope = strchr(p1, '%');
                 p2 = strchr(p1, ']');                  p2 = strchr(p1, ']');
                   if(p2 && scope && scope < p2 && scope_id) {
                           /* parse scope */
   #ifdef IF_NAMESIZE
                           char tmp[IF_NAMESIZE];
                           int l;
                           scope++;
                           /* "%25" is just '%' in URL encoding */
                           if(scope[0] == '2' && scope[1] == '5')
                                   scope += 2;     /* skip "25" */
                           l = p2 - scope;
                           if(l >= IF_NAMESIZE)
                                   l = IF_NAMESIZE - 1;
                           memcpy(tmp, scope, l);
                           tmp[l] = '\0';
                           *scope_id = if_nametoindex(tmp);
                           if(*scope_id == 0) {
                                   *scope_id = (unsigned int)strtoul(tmp, NULL, 10);
                           }
   #else
                           /* under windows, scope is numerical */
                           char tmp[8];
                           int l;
                           scope++;
                           /* "%25" is just '%' in URL encoding */
                           if(scope[0] == '2' && scope[1] == '5')
                                   scope += 2;     /* skip "25" */
                           l = p2 - scope;
                           if(l >= sizeof(tmp))
                                   l = sizeof(tmp) - 1;
                           memcpy(tmp, scope, l);
                           tmp[l] = '\0';
                           *scope_id = (unsigned int)strtoul(tmp, NULL, 10);
   #endif
                   }
                 p3 = strchr(p1, '/');                  p3 = strchr(p1, '/');
                 if(p2 && p3)                  if(p2 && p3)
                 {                  {
Line 488  int parseURL(const char * url, char * hostname, unsign Line 535  int parseURL(const char * url, char * hostname, unsign
         return 1;          return 1;
 }  }
   
void * miniwget(const char * url, int * size)void *
 miniwget(const char * url, int * size, unsigned int scope_id)
 {  {
         unsigned short port;          unsigned short port;
         char * path;          char * path;
         /* protocol://host:port/chemin */          /* protocol://host:port/chemin */
         char hostname[MAXHOSTNAMELEN+1];          char hostname[MAXHOSTNAMELEN+1];
         *size = 0;          *size = 0;
        if(!parseURL(url, hostname, &port, &path))        if(!parseURL(url, hostname, &port, &path, &scope_id))
                 return NULL;                  return NULL;
 #ifdef DEBUG  #ifdef DEBUG
        printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);        printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
                hostname, port, path, scope_id);
 #endif  #endif
        return miniwget2(url, hostname, port, path, size, 0, 0);        return miniwget2(hostname, port, path, size, 0, 0, scope_id);
 }  }
   
void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)void *
 miniwget_getaddr(const char * url, int * size,
                  char * addr, int addrlen, unsigned int scope_id)
 {  {
         unsigned short port;          unsigned short port;
         char * path;          char * path;
        /* protocol://host:port/chemin */        /* protocol://host:port/path */
         char hostname[MAXHOSTNAMELEN+1];          char hostname[MAXHOSTNAMELEN+1];
         *size = 0;          *size = 0;
         if(addr)          if(addr)
                 addr[0] = '\0';                  addr[0] = '\0';
        if(!parseURL(url, hostname, &port, &path))        if(!parseURL(url, hostname, &port, &path, &scope_id))
                 return NULL;                  return NULL;
 #ifdef DEBUG  #ifdef DEBUG
        printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);        printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
                hostname, port, path, scope_id);
 #endif  #endif
        return miniwget2(url, hostname, port, path, size, addr, addrlen);        return miniwget2(hostname, port, path, size, addr, addrlen, scope_id);
 }  }
   

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


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