1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-20 18:55:32 +00:00

update to miniupnpc-1.4.20101209

This commit is contained in:
Mitchell Livingston 2010-12-10 04:07:30 +00:00
parent f4ee84069e
commit 78f2bff2a2
5 changed files with 274 additions and 57 deletions

View file

@ -1,6 +1,20 @@
$Id: Changelog.txt,v 1.117 2010/06/09 10:59:08 nanard Exp $ $Id: Changelog.txt,v 1.122 2010/12/09 16:11:31 nanard Exp $
miniUPnP client Changelog. miniUPnP client Changelog.
2010/12/09:
new code for miniwget that handle Chunked transfer encoding
using getHTTPResponse() in SOAP call code
2010/11/25:
changes to minissdpc.c to compile under Win32.
see http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=729
2010/09/17:
Various improvement to Makefile from Michał Górny
2010/08/05:
Adding the script "external-ip.sh" from Reuben Hawkins
2010/06/09: 2010/06/09:
update to python module to match modification made on 2010/04/05 update to python module to match modification made on 2010/04/05
update to Java test code to match modification made on 2010/04/05 update to Java test code to match modification made on 2010/04/05

View file

@ -1,4 +1,4 @@
/* $Id: minissdpc.c,v 1.13 2009/12/04 16:57:29 nanard Exp $ */ /* $Id: minissdpc.c,v 1.14 2010/11/25 09:57:25 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Author : Thomas BERNARD * Author : Thomas BERNARD
* copyright (c) 2005-2009 Thomas Bernard * copyright (c) 2005-2009 Thomas Bernard
@ -15,6 +15,8 @@
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <io.h> #include <io.h>
#include <winsock.h>
#include <stdint.h>
#endif #endif
#if defined(__amigaos__) || defined(__amigaos4__) #if defined(__amigaos__) || defined(__amigaos4__)
#include <sys/socket.h> #include <sys/socket.h>

View file

@ -1,4 +1,4 @@
/* $Id: miniupnpc.c,v 1.81 2010/04/17 22:07:59 nanard Exp $ */ /* $Id: miniupnpc.c,v 1.83 2010/12/09 16:11:32 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Author : Thomas BERNARD * Author : Thomas BERNARD
* copyright (c) 2005-2010 Thomas Bernard * copyright (c) 2005-2010 Thomas Bernard
@ -99,6 +99,7 @@ LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * d
#endif #endif
} }
#if 0
/* getcontentlenfromline() : parse the Content-Length HTTP header line. /* getcontentlenfromline() : parse the Content-Length HTTP header line.
* Content-length: nnn */ * Content-length: nnn */
static int getcontentlenfromline(const char * p, int n) static int getcontentlenfromline(const char * p, int n)
@ -167,6 +168,7 @@ getContentLengthAndHeaderLength(char * p, int n,
} }
} }
} }
#endif
/* simpleUPnPcommand2 : /* simpleUPnPcommand2 :
* not so simple ! * not so simple !
@ -183,9 +185,9 @@ static int simpleUPnPcommand2(int s, const char * url, const char * service,
char soapact[128]; char soapact[128];
char soapbody[2048]; char soapbody[2048];
char * buf; char * buf;
int buffree; /*int buffree;*/
int n; int n;
int contentlen, headerlen; /* for the response */ /*int contentlen, headerlen;*/ /* for the response */
snprintf(soapact, sizeof(soapact), "%s#%s", service, action); snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
if(args==NULL) if(args==NULL)
@ -272,6 +274,7 @@ static int simpleUPnPcommand2(int s, const char * url, const char * service,
return -1; return -1;
} }
#if 0
contentlen = -1; contentlen = -1;
headerlen = -1; headerlen = -1;
buf = buffer; buf = buffer;
@ -291,7 +294,22 @@ static int simpleUPnPcommand2(int s, const char * url, const char * service,
if(contentlen > 0 && headerlen > 0 && *bufsize >= contentlen+headerlen) if(contentlen > 0 && headerlen > 0 && *bufsize >= contentlen+headerlen)
break; break;
} }
#endif
buf = getHTTPResponse(s, &n);
if(n > 0 && buf)
{
if(*bufsize > n)
{
memcpy(buffer, buf, n);
*bufsize = n;
}
else
{
memcpy(buffer, buf, *bufsize);
}
free(buf);
buf = 0;
}
closesocket(s); closesocket(s);
return 0; return 0;
} }
@ -306,8 +324,10 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
char * buffer, int * bufsize) char * buffer, int * bufsize)
{ {
int result; int result;
int origbufsize = *bufsize; /*int origbufsize = *bufsize;*/
result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1");
/*
result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.0"); result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.0");
if (result < 0 || *bufsize == 0) if (result < 0 || *bufsize == 0)
{ {
@ -317,6 +337,7 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
*bufsize = origbufsize; *bufsize = origbufsize;
result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1"); result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1");
} }
*/
return result; return result;
} }

View file

@ -1,4 +1,4 @@
/* $Id: miniwget.c,v 1.37 2010/04/12 20:39:42 nanard Exp $ */ /* $Id: miniwget.c,v 1.38 2010/12/09 15:54:25 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005-2010 Thomas Bernard * Copyright (c) 2005-2010 Thomas Bernard
@ -8,6 +8,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include "miniupnpc.h" #include "miniupnpc.h"
#ifdef WIN32 #ifdef WIN32
#include <winsock2.h> #include <winsock2.h>
@ -41,6 +42,227 @@
#include "miniwget.h" #include "miniwget.h"
#include "connecthostport.h" #include "connecthostport.h"
/*
* Read a HTTP response from a socket.
* Process Content-Length and Transfer-encoding headers.
*/
void *
getHTTPResponse(int s, int * size)
{
char buf[2048];
int n;
int headers = 1;
int chunked = 0;
int content_length = -1;
unsigned int chunksize = 0;
/* buffers : */
char * header_buf;
int header_buf_len = 2048;
int header_buf_used = 0;
char * content_buf;
int content_buf_len = 2048;
int content_buf_used = 0;
header_buf = malloc(header_buf_len);
content_buf = malloc(content_buf_len);
while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
{
if(headers)
{
int i;
int linestart=0;
int colon=0;
int valuestart=0;
if(header_buf_used + n > header_buf_len) {
header_buf = realloc(header_buf, header_buf_used + n);
header_buf_len = header_buf_used + n;
}
memcpy(header_buf + header_buf_used, buf, n);
header_buf_used += n;
for(i = 0; i < (header_buf_used-3); i++) {
if(colon <= linestart && header_buf[i]==':')
{
colon = i;
while(i < (n-3)
&& (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
i++;
valuestart = i + 1;
}
/* detecting end of line */
else if(header_buf[i]=='\r' && header_buf[i+1]=='\n')
{
if(colon > linestart && valuestart > colon)
{
#ifdef DEBUG
printf("header='%.*s', value='%.*s'\n",
colon-linestart, header_buf+linestart,
i-valuestart, header_buf+valuestart);
#endif
if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart))
{
content_length = atoi(header_buf+valuestart);
#ifdef DEBUG
printf("Content-Length: %d\n", content_length);
#endif
}
else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
&& 0==strncasecmp(buf+valuestart, "chunked", 7))
{
#ifdef DEBUG
printf("chunked transfer-encoding!\n");
#endif
chunked = 1;
}
}
linestart = i+2;
colon = linestart;
valuestart = 0;
}
/* searching for the end of the HTTP headers */
if(header_buf[i]=='\r' && header_buf[i+1]=='\n'
&& header_buf[i+2]=='\r' && header_buf[i+3]=='\n')
{
headers = 0; /* end */
i += 4;
if(i < header_buf_used)
{
if(chunked)
{
while(i<header_buf_used && isxdigit(header_buf[i]))
{
if(header_buf[i] >= '0' && header_buf[i] <= '9')
chunksize = (chunksize << 4) + (header_buf[i] - '0');
else
chunksize = (chunksize << 4) + ((header_buf[i] | 32) - 'a' + 10);
i++;
}
/* discarding chunk-extension */
while(i < header_buf_used && header_buf[i] != '\r') i++;
if(i < header_buf_used && header_buf[i] == '\r') i++;
if(i < header_buf_used && header_buf[i] == '\n') i++;
#ifdef DEBUG
printf("chunksize = %u (%x)\n", chunksize, chunksize);
#endif
if(chunksize == 0)
{
#ifdef DEBUG
printf("end of stream !\n");
#endif
goto end_of_stream;
}
if(header_buf_used - i <= chunksize)
{
if(content_buf_len < header_buf_used - i)
{
content_buf = realloc(content_buf, header_buf_used - i);
content_buf_len = header_buf_used - i;
}
memcpy(content_buf, header_buf + i, header_buf_used - i);
content_buf_used = header_buf_used - i;
chunksize -= (header_buf_used - i);
i = header_buf_used;
}
else
{
printf("arg ! chunksize < (header_buf_used - i)\n");
}
}
else
{
if(content_buf_len < header_buf_used - i)
{
content_buf = realloc(content_buf, header_buf_used - i);
content_buf_len = header_buf_used - i;
}
memcpy(content_buf, header_buf + i, header_buf_used - i);
content_buf_used = header_buf_used - i;
}
}
}
}
}
else
{
/* content */
if(chunked)
{
int i = 0;
unsigned bytestocopy;
while(i < n)
{
if(chunksize == 0)
{
/* reading chunk size */
if(i<n && buf[i] == '\r') i++;
if(i<n && buf[i] == '\n') i++;
while(i<n && isxdigit(buf[i]))
{
if(buf[i] >= '0' && buf[i] <= '9')
chunksize = (chunksize << 4) + (buf[i] - '0');
else
chunksize = (chunksize << 4) + ((buf[i] | 32) - 'a' + 10);
i++;
}
while(i<n && buf[i] != '\r') i++; /* discarding chunk-extension */
if(i<n && buf[i] == '\r') i++;
if(i<n && buf[i] == '\n') i++;
#ifdef DEBUG
printf("chunksize = %u (%x)\n", chunksize, chunksize);
#endif
if(chunksize == 0)
{
#ifdef DEBUG
printf("end of stream - %d %d\n", i, n);
/*printf("'%.*s'\n", n-i, buf+i);*/
#endif
goto end_of_stream;
}
}
bytestocopy = (chunksize < n - i)?chunksize:(n - i);
if(content_buf_used + bytestocopy > content_buf_len)
{
content_buf = (char *)realloc((void *)content_buf,
content_buf_used + bytestocopy);
content_buf_len = content_buf_used + bytestocopy;
}
memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
content_buf_used += bytestocopy;
i += bytestocopy;
chunksize -= bytestocopy;
}
}
else
{
if(content_buf_used + n > content_buf_len)
{
content_buf = (char *)realloc((void *)content_buf,
content_buf_used + n);
content_buf_len = content_buf_used + n;
}
memcpy(content_buf + content_buf_used, buf, n);
content_buf_used += n;
}
}
if(content_length > 0 && content_buf_used >= content_length)
{
#ifdef DEBUG
printf("termine!\n");
#endif
break;
}
}
end_of_stream:
free(header_buf); header_buf = NULL;
*size = content_buf_used;
if(content_buf_used == 0)
{
free(content_buf);
content_buf = NULL;
}
return content_buf;
}
/* miniwget3() : /* miniwget3() :
* do all the work. * do all the work.
* Return NULL if something failed. */ * Return NULL if something failed. */
@ -126,54 +348,7 @@ miniwget3(const char * url, const char * host,
sent += n; sent += n;
} }
} }
{ return getHTTPResponse(s, size);
/* TODO : in order to support HTTP/1.1, chunked transfer encoding
* must be supported. That means parsing of headers must be
* added. */
int headers=1;
char * respbuffer = NULL;
int allreadyread = 0;
/*while((n = recv(s, buf, 2048, 0)) > 0)*/
while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
{
if(headers)
{
int i=0;
while(i<n-3)
{
/* searching for the end of the HTTP headers */
if(buf[i]=='\r' && buf[i+1]=='\n'
&& buf[i+2]=='\r' && buf[i+3]=='\n')
{
headers = 0; /* end */
if(i<n-4)
{
/* Copy the content into respbuffet */
respbuffer = (char *)realloc((void *)respbuffer,
allreadyread+(n-i-4));
memcpy(respbuffer+allreadyread, buf + i + 4, n-i-4);
allreadyread += (n-i-4);
}
break;
}
i++;
}
}
else
{
respbuffer = (char *)realloc((void *)respbuffer,
allreadyread+n);
memcpy(respbuffer+allreadyread, buf, n);
allreadyread += n;
}
}
*size = allreadyread;
#ifdef DEBUG
printf("%d bytes read\n", *size);
#endif
closesocket(s);
return respbuffer;
}
} }
/* miniwget2() : /* miniwget2() :
@ -185,6 +360,8 @@ miniwget2(const char * url, const char * host,
{ {
char * respbuffer; 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"); respbuffer = miniwget3(url, host, port, path, size, addr_str, addr_str_len, "1.0");
if (*size == 0) if (*size == 0)
{ {
@ -194,6 +371,7 @@ miniwget2(const char * url, const char * host,
free(respbuffer); free(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.1");
} }
*/
return respbuffer; return respbuffer;
} }

View file

@ -1,4 +1,4 @@
/* $Id: miniwget.h,v 1.5 2007/01/29 20:27:23 nanard Exp $ */ /* $Id: miniwget.h,v 1.6 2010/12/09 16:11:33 nanard Exp $ */
/* Project : miniupnp /* Project : miniupnp
* Author : Thomas Bernard * Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard * Copyright (c) 2005 Thomas Bernard
@ -14,6 +14,8 @@
extern "C" { extern "C" {
#endif #endif
LIBSPEC void * getHTTPResponse(int s, int * size);
LIBSPEC void * miniwget(const char *, int *); LIBSPEC void * miniwget(const char *, int *);
LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int); LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int);