summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c')
-rw-r--r--3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c158
1 files changed, 105 insertions, 53 deletions
diff --git a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c
index 0c31416..a75f55b 100644
--- a/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c
+++ b/3rdParty/LibMiniUPnPc/src/miniupnpc/miniwget.c
@@ -1,15 +1,16 @@
-/* $Id: miniwget.c,v 1.52 2011/06/17 22:59:42 nanard Exp $ */
+/* $Id: miniwget.c,v 1.60 2013/10/07 10:03:16 nanard Exp $ */
/* Project : miniupnp
+ * Website : http://miniupnp.free.fr/
* Author : Thomas Bernard
- * Copyright (c) 2005-2011 Thomas Bernard
+ * Copyright (c) 2005-2013 Thomas Bernard
* This software is subject to the conditions detailed in the
* LICENCE file provided in this distribution. */
-
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
-#ifdef WIN32
+#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
@@ -24,7 +25,7 @@
#define strncasecmp memicmp
#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
#endif /* #ifndef strncasecmp */
-#else /* #ifdef WIN32 */
+#else /* #ifdef _WIN32 */
#include <unistd.h>
#include <sys/param.h>
#if defined(__amigaos__) && !defined(__amigaos4__)
@@ -33,26 +34,28 @@
#include <sys/select.h>
#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
#include <sys/socket.h>
+#include <netinet/in.h>
#include <arpa/inet.h>
+#include <net/if.h>
#include <netdb.h>
#define closesocket close
/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
* during the connect() call */
#define MINIUPNPC_IGNORE_EINTR
-#endif /* #else WIN32 */
+#endif /* #else _WIN32 */
#if defined(__sun) || defined(sun)
#define MIN(x,y) (((x)<(y))?(x):(y))
#endif
-#ifdef __ANDROID__
-#define MIN(x,y) (((x)<(y))?(x):(y))
-#endif
-
#include "miniupnpcstrings.h"
#include "miniwget.h"
#include "connecthostport.h"
#include "receivedata.h"
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
/*
* Read a HTTP response from a socket.
* Process Content-Length and Transfer-encoding headers.
@@ -71,20 +74,20 @@ getHTTPResponse(int s, int * size)
unsigned int bytestocopy = 0;
/* buffers : */
char * header_buf;
- int header_buf_len = 2048;
- int header_buf_used = 0;
+ unsigned int header_buf_len = 2048;
+ unsigned int header_buf_used = 0;
char * content_buf;
- int content_buf_len = 2048;
- int content_buf_used = 0;
+ unsigned int content_buf_len = 2048;
+ unsigned int content_buf_used = 0;
char chunksize_buf[32];
- int chunksize_buf_index;
+ unsigned int chunksize_buf_index;
header_buf = malloc(header_buf_len);
content_buf = malloc(content_buf_len);
chunksize_buf[0] = '\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)
{
@@ -101,14 +104,14 @@ getHTTPResponse(int s, int * size)
/* search for CR LF CR LF (end of headers)
* recognize also LF LF */
i = 0;
- while(i < (header_buf_used-1) && (endofheaders == 0)) {
+ while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
if(header_buf[i] == '\r') {
i++;
if(header_buf[i] == '\n') {
i++;
- if(i < header_buf_used && header_buf[i] == '\r') {
+ if(i < (int)header_buf_used && header_buf[i] == '\r') {
i++;
- if(i < header_buf_used && header_buf[i] == '\n') {
+ if(i < (int)header_buf_used && header_buf[i] == '\n') {
endofheaders = i+1;
}
}
@@ -159,12 +162,12 @@ getHTTPResponse(int s, int * size)
chunked = 1;
}
}
- while(header_buf[i]=='\r' || header_buf[i] == '\n')
+ while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n'))
i++;
linestart = i;
colon = linestart;
valuestart = 0;
- }
+ }
}
/* copy the remaining of the received data back to buf */
n = header_buf_used - endofheaders;
@@ -198,7 +201,7 @@ getHTTPResponse(int s, int * size)
i++; /* discarding chunk-extension */
if(i<n && buf[i] == '\r') i++;
if(i<n && buf[i] == '\n') {
- int j;
+ unsigned int j;
for(j = 0; j < chunksize_buf_index; j++) {
if(chunksize_buf[j] >= '0'
&& chunksize_buf[j] <= '9')
@@ -225,15 +228,15 @@ getHTTPResponse(int s, int * size)
goto end_of_stream;
}
}
- bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i);
- if((int)(content_buf_used + bytestocopy) > content_buf_len)
+ bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i);
+ 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;
} 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);
}
memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
@@ -246,18 +249,18 @@ getHTTPResponse(int s, int * size)
{
/* not chunked */
if(content_length > 0
- && (content_buf_used + n) > content_length) {
+ && (int)(content_buf_used + n) > content_length) {
/* skipping additional bytes */
n = content_length - content_buf_used;
}
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;
} else {
content_buf_len = content_buf_used + n;
}
- content_buf = (char *)realloc((void *)content_buf,
+ content_buf = (char *)realloc((void *)content_buf,
content_buf_len);
}
memcpy(content_buf + content_buf_used, buf, n);
@@ -265,7 +268,7 @@ getHTTPResponse(int s, int * size)
}
}
/* 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
printf("End of HTTP content\n");
@@ -288,10 +291,10 @@ end_of_stream:
* do all the work.
* Return NULL if something failed. */
static void *
-miniwget3(const char * url, const char * host,
+miniwget3(const char * host,
unsigned short port, const char * path,
int * size, char * addr_str, int addr_str_len,
- const char * httpversion)
+ const char * httpversion, unsigned int scope_id)
{
char buf[2048];
int s;
@@ -301,7 +304,7 @@ miniwget3(const char * url, const char * host,
void * content;
*size = 0;
- s = connecthostport(host, port);
+ s = connecthostport(host, port, scope_id);
if(s < 0)
return NULL;
@@ -347,7 +350,7 @@ miniwget3(const char * url, const char * host,
NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV);
if(n != 0) {
-#ifdef WIN32
+#ifdef _WIN32
fprintf(stderr, "getnameinfo() failed : %d\n", n);
#else
fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
@@ -392,24 +395,29 @@ miniwget3(const char * url, const char * host,
/* miniwget2() :
* Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
static void *
-miniwget2(const char * url, const char * host,
+miniwget2(const char * host,
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;
- respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.1");
-/*
- respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");
+#if 1
+ respbuffer = miniwget3(host, port, path, size,
+ 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)
{
#ifdef DEBUG
printf("Retrying with HTTP/1.1\n");
#endif
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;
}
@@ -421,12 +429,15 @@ miniwget2(const char * url, const char * host,
* url : source string not modified
* hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
* port : port (destination)
- * path : pointer to the path part of the URL
+ * path : pointer to the path part of the URL
*
* Return values :
* 0 - Failure
* 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;
if(!url)
@@ -442,7 +453,43 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
if(*p1 == '[')
{
/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
+ char * scope;
+ scope = 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, '/');
if(p2 && p3)
{
@@ -492,35 +539,40 @@ int parseURL(const char * url, char * hostname, unsigned short * port, char * *
return 1;
}
-void * miniwget(const char * url, int * size)
+void *
+miniwget(const char * url, int * size, unsigned int scope_id)
{
unsigned short port;
char * path;
/* protocol://host:port/chemin */
char hostname[MAXHOSTNAMELEN+1];
*size = 0;
- if(!parseURL(url, hostname, &port, &path))
+ if(!parseURL(url, hostname, &port, &path, &scope_id))
return NULL;
#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
- 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;
char * path;
- /* protocol://host:port/chemin */
+ /* protocol://host:port/path */
char hostname[MAXHOSTNAMELEN+1];
*size = 0;
if(addr)
addr[0] = '\0';
- if(!parseURL(url, hostname, &port, &path))
+ if(!parseURL(url, hostname, &port, &path, &scope_id))
return NULL;
#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
- return miniwget2(url, hostname, port, path, size, addr, addrlen);
+ return miniwget2(hostname, port, path, size, addr, addrlen, scope_id);
}