source: branches/1.5x/third-party/miniupnp/miniwget.c @ 7869

Last change on this file since 7869 was 7869, checked in by charles, 13 years ago

(1.5x) update to Jan 2009 versions of libnatpmp and miniupnpc

File size: 5.1 KB
Line 
1/* $Id: miniwget.c,v 1.21 2008/12/18 17:45:18 nanard Exp $ */
2/* Project : miniupnp
3 * Author : Thomas Bernard
4 * Copyright (c) 2005 Thomas Bernard
5 * This software is subject to the conditions detailed in the
6 * LICENCE file provided in this distribution.
7 * */
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include "miniupnpc.h"
12#ifdef WIN32
13#include <winsock2.h>
14#include <io.h>
15#define MAXHOSTNAMELEN 64
16#define MIN(x,y) (((x)<(y))?(x):(y))
17#define snprintf _snprintf
18#define herror
19#define socklen_t int
20#else
21#include <unistd.h>
22#include <sys/param.h>
23#include <sys/socket.h>
24#include <netdb.h>
25#include <netinet/in.h>
26#include <arpa/inet.h>
27#define closesocket close
28#endif
29/* for MIN() macro : */
30#if defined(__sun) || defined(sun)
31#include <utility.h>
32#endif
33
34#include "miniupnpcstrings.h"
35
36/* miniwget2() :
37 * */
38static void *
39miniwget2(const char * url, const char * host,
40                  unsigned short port, const char * path,
41                  int * size, char * addr_str, int addr_str_len)
42{
43        char buf[2048];
44    int s;
45        struct sockaddr_in dest;
46        struct hostent *hp;
47        *size = 0;
48        hp = gethostbyname(host);
49        if(hp==NULL)
50        {
51                herror(host);
52                return NULL;
53        }
54        /*  memcpy((char *)&dest.sin_addr, hp->h_addr, hp->h_length);  */
55        memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
56        memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
57        s = socket(PF_INET, SOCK_STREAM, 0);
58        if(s < 0)
59        {
60                perror("socket");
61                return NULL;
62        }
63        dest.sin_family = AF_INET;
64        dest.sin_port = htons(port);
65        if(connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in))<0)
66        {
67                perror("connect");
68                closesocket(s);
69                return NULL;
70        }
71
72        /* get address for caller ! */
73        if(addr_str)
74        {
75                struct sockaddr_in saddr;
76                socklen_t len;
77
78                len = sizeof(saddr);
79                getsockname(s, (struct sockaddr *)&saddr, &len);
80#ifndef WIN32
81                inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);
82#else
83        /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
84     * But his function make a string with the port :  nn.nn.nn.nn:port */
85/*              if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
86                            NULL, addr_str, (DWORD *)&addr_str_len))
87                {
88                    printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
89                }*/
90                strncpy(addr_str, inet_ntoa(saddr.sin_addr), addr_str_len);
91#endif
92#ifdef DEBUG
93                printf("address miniwget : %s\n", addr_str);
94#endif
95        }
96
97        snprintf(buf, sizeof(buf),
98                 "GET %s HTTP/1.1\r\n"
99                             "Host: %s:%d\r\n"
100                                 "Connection: Close\r\n"
101                                 "User-Agent: " OS_STRING ", UPnP/1.0, MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
102
103                                 "\r\n",
104                    path, host, port);
105        /*write(s, buf, strlen(buf));*/
106        send(s, buf, strlen(buf), 0);
107        {
108                int n, headers=1;
109                char * respbuffer = NULL;
110                int allreadyread = 0;
111                /*while((n = recv(s, buf, 2048, 0)) > 0)*/
112                while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
113                {
114                        if(headers)
115                        {
116                                int i=0;
117                                while(i<n-3)
118                                {
119                                        if(buf[i]=='\r' && buf[i+1]=='\n'
120                                           && buf[i+2]=='\r' && buf[i+3]=='\n')
121                                        {
122                                                headers = 0;    /* end */
123                                                if(i<n-4)
124                                                {
125                                                        respbuffer = (char *)realloc((void *)respbuffer, 
126                                                                                                                 allreadyread+(n-i-4));
127                                                        memcpy(respbuffer+allreadyread, buf + i + 4, n-i-4);
128                                                        allreadyread += (n-i-4);
129                                                }
130                                                break;
131                                        }
132                                        i++;
133                                }
134                        }
135                        else
136                        {
137                                respbuffer = (char *)realloc((void *)respbuffer, 
138                                                                 allreadyread+n);
139                                memcpy(respbuffer+allreadyread, buf, n);
140                                allreadyread += n;
141                        }
142                }
143                *size = allreadyread;
144#ifdef DEBUG
145                printf("%d bytes read\n", *size);
146#endif
147                closesocket(s);
148                return respbuffer;
149        }
150}
151
152/* parseURL()
153 * arguments :
154 *   url :              source string not modified
155 *   hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
156 *   port :             port (destination)
157 *   path :             pointer to the path part of the URL
158 *
159 * Return values :
160 *    0 - Failure
161 *    1 - Success         */
162int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)
163{
164        char * p1, *p2, *p3;
165        p1 = strstr(url, "://");
166        if(!p1)
167                return 0;
168        p1 += 3;
169        if(  (url[0]!='h') || (url[1]!='t')
170           ||(url[2]!='t') || (url[3]!='p'))
171                return 0;
172        p2 = strchr(p1, ':');
173        p3 = strchr(p1, '/');
174        if(!p3)
175                return 0;
176        memset(hostname, 0, MAXHOSTNAMELEN + 1);
177        if(!p2 || (p2>p3))
178        {
179                strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
180                *port = 80;
181        }
182        else
183        {
184                strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
185                *port = 0;
186                p2++;
187                while( (*p2 >= '0') && (*p2 <= '9'))
188                {
189                        *port *= 10;
190                        *port += (unsigned short)(*p2 - '0');
191                        p2++;
192                }
193        }
194        *path = p3;
195        return 1;
196}
197
198void * miniwget(const char * url, int * size)
199{
200        unsigned short port;
201        char * path;
202        /* protocol://host:port/chemin */
203        char hostname[MAXHOSTNAMELEN+1];
204        *size = 0;
205        if(!parseURL(url, hostname, &port, &path))
206                return NULL;
207        return miniwget2(url, hostname, port, path, size, 0, 0);
208}
209
210void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
211{
212        unsigned short port;
213        char * path;
214        /* protocol://host:port/chemin */
215        char hostname[MAXHOSTNAMELEN+1];
216        *size = 0;
217        if(addr)
218                addr[0] = '\0';
219        if(!parseURL(url, hostname, &port, &path))
220                return NULL;
221        return miniwget2(url, hostname, port, path, size, addr, addrlen);
222}
223
Note: See TracBrowser for help on using the repository browser.