12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
* General Public License for more details. |
* General Public License for more details. |
|
* |
|
|
* You should have received a copy of the GNU General Public License |
|
|
* along with WinPT; if not, write to the Free Software Foundation, |
|
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
15 |
*/ |
*/ |
16 |
#ifdef HAVE_CONFIG_H |
#ifdef HAVE_CONFIG_H |
17 |
#include <config.h> |
#include <config.h> |
29 |
#include "wptTypes.h" |
#include "wptTypes.h" |
30 |
#include "wptErrors.h" |
#include "wptErrors.h" |
31 |
|
|
|
#define free_if_malloc(buf) if ((buf)) { free ((buf)); (buf) = NULL; } |
|
32 |
|
|
33 |
/* Empty constructur to allow advanced requests. */ |
/* Empty constructur to allow advanced requests. */ |
34 |
wHTTP::wHTTP (void) |
wHTTP::wHTTP (void) |
54 |
wHTTP::wHTTP (const char *_url) |
wHTTP::wHTTP (const char *_url) |
55 |
{ |
{ |
56 |
reset (); |
reset (); |
57 |
extractHostInfo (_url, &this->host, &this->url); |
|
58 |
/* XXX: if the connection fails, return the error code to the user. */ |
if (extractHostInfo (_url, &this->host, &this->url)) |
59 |
|
return; |
60 |
|
|
61 |
|
/* FIXME: we should throw an exception in case of an error. */ |
62 |
if (!sendRequest (this->host, this->port, this->url)) |
if (!sendRequest (this->host, this->port, this->url)) |
63 |
parseResponse (&statcode); |
parseResponse (&statcode); |
64 |
} |
} |
83 |
int |
int |
84 |
wHTTP::head (const char *_url) |
wHTTP::head (const char *_url) |
85 |
{ |
{ |
86 |
free_if_malloc (host); |
int err; |
87 |
free_if_malloc (url); |
|
88 |
|
safe_free (host); |
89 |
|
safe_free (url); |
90 |
|
|
91 |
extractHostInfo (_url, &this->host, &this->url); |
err = extractHostInfo (_url, &this->host, &this->url); |
92 |
|
if (err) |
93 |
|
return err; |
94 |
method = HTTP_HEAD; |
method = HTTP_HEAD; |
95 |
|
|
96 |
if (!sendRequest (host, port, url)) |
if (!sendRequest (host, port, url)) |
104 |
int |
int |
105 |
wHTTP::get (const char *_url) |
wHTTP::get (const char *_url) |
106 |
{ |
{ |
107 |
free_if_malloc (host); |
int err; |
|
free_if_alloc (url); |
|
108 |
|
|
109 |
extractHostInfo (_url, &this->host, &this->url); |
safe_free (host); |
110 |
|
safe_free (url); |
111 |
|
|
112 |
|
err = extractHostInfo (_url, &this->host, &this->url); |
113 |
|
if (err) |
114 |
|
return err; |
115 |
|
|
116 |
method = HTTP_GET; |
method = HTTP_GET; |
117 |
if (!sendRequest (this->host, this->port, this->url)) |
if (!sendRequest (this->host, this->port, this->url)) |
284 |
break; |
break; |
285 |
} |
} |
286 |
n = recv (fd, &c, 1, 0); |
n = recv (fd, &c, 1, 0); |
287 |
if (n == -1) |
if (n == -1) { |
288 |
|
this->error = (int)WSAGetLastError (); |
289 |
break; |
break; |
290 |
|
} |
291 |
if (n == 0 || nbuf == 0 || c == '\n') { |
if (n == 0 || nbuf == 0 || c == '\n') { |
292 |
if (n == 0) { |
if (n == 0) { |
293 |
if (eof) |
if (eof) |
317 |
@host and also return the resource part of the url in @new_url. */ |
@host and also return the resource part of the url in @new_url. */ |
318 |
int |
int |
319 |
wHTTP::extractHostInfo (const char *_url, char **_host, char **new_url) |
wHTTP::extractHostInfo (const char *_url, char **_host, char **new_url) |
320 |
{ |
{ |
321 |
|
char tmpbuf[2*MAX_PATH+1]; |
322 |
char *p; |
char *p; |
|
char tmpbuf[512]; |
|
323 |
|
|
324 |
*_host = NULL; |
*_host = NULL; |
325 |
*new_url = NULL; |
*new_url = NULL; |
326 |
|
|
327 |
/* XXX: do not use static buffers. */ |
/* XXX: do not use static buffers. */ |
328 |
memset (tmpbuf, 0, sizeof (tmpbuf)); |
memset (tmpbuf, 0, sizeof (tmpbuf)); |
329 |
strncpy (tmpbuf, _url, 512); |
strncpy (tmpbuf, _url, DIM (tmpbuf)-1); |
330 |
|
|
331 |
p = "http://"; |
p = "http://"; |
332 |
if (strlen (_url) < 10 || strncmp (_url, p, 7)) |
if (strlen (_url) < 10 || strncmp (_url, p, 7)) |
335 |
p = strtok (tmpbuf+7, "/"); |
p = strtok (tmpbuf+7, "/"); |
336 |
if (!p) |
if (!p) |
337 |
return WPTERR_GENERAL; |
return WPTERR_GENERAL; |
338 |
*_host = strdup (p); |
*_host = strdup (p); |
339 |
p = strchr (_url, '/'); |
p = strchr (_url, '/'); |
340 |
if (!p) { |
if (!p) /* document were given so we assume the root '/'. */ |
341 |
free_if_malloc (*_host); |
*new_url = strdup ("/"); |
342 |
return WPTERR_GENERAL; |
else |
343 |
} |
*new_url = strdup (p); |
|
*new_url = strdup (p); |
|
344 |
return 0; |
return 0; |
345 |
} |
} |
346 |
|
|
352 |
char *p; |
char *p; |
353 |
char *fmt = "%s: %s"; |
char *fmt = "%s: %s"; |
354 |
|
|
355 |
p = (char*) malloc (strlen (name)+strlen (val)+strlen (fmt)+1); |
p = (char*) malloc (strlen (name)+strlen (val)+strlen (fmt)+4); |
356 |
sprintf (p, fmt, name, val); |
sprintf (p, fmt, name, val); |
357 |
addHeader (&req_headers, p); |
addHeader (&req_headers, p); |
358 |
free_if_malloc (p); |
safe_free (p); |
359 |
|
|
360 |
return 0; |
return 0; |
361 |
} |
} |
399 |
} |
} |
400 |
|
|
401 |
if (*_url == '/') |
if (*_url == '/') |
402 |
url++; |
_url++; |
403 |
if (_url == NULL) |
if (_url == NULL) |
404 |
_url = ""; |
_url = ""; |
405 |
|
|
410 |
n = 0; |
n = 0; |
411 |
for (h = req_headers; h; h = h->next) |
for (h = req_headers; h; h = h->next) |
412 |
n += strlen (h->d) + 2 + 1; |
n += strlen (h->d) + 2 + 1; |
|
|
|
413 |
h_head = "%s /%s HTTP/1.%d\r\n"; |
h_head = "%s /%s HTTP/1.%d\r\n"; |
414 |
p = (char*)calloc (1, strlen (id[method]) + strlen (h_head) |
n += strlen (id[method]) + strlen (h_head) |
415 |
+ strlen (url) + n + 2 + 1 + 4); |
+ strlen (_url) + n + 2 + 1 + 4; |
416 |
|
p = (char*)calloc (1, n+1); |
417 |
if (!p) |
if (!p) |
418 |
BUG (0); |
BUG (0); |
419 |
sprintf (p, h_head, id[method], url, ver); |
sprintf (p, h_head, id[method], _url, ver); |
420 |
for (h = req_headers; h; h = h->next) { |
for (h = req_headers; h; h = h->next) { |
421 |
strcat (p, h->d); |
strcat (p, h->d); |
422 |
strcat (p, "\r\n"); |
strcat (p, "\r\n"); |
423 |
} |
} |
424 |
strcat (p, "\r\n"); |
strcat (p, "\r\n"); |
|
printf ("p='%s'\n", p); |
|
425 |
n = send (fd, p, strlen (p), 0); |
n = send (fd, p, strlen (p), 0); |
426 |
free_if_malloc (p); |
safe_free (p); |
427 |
return n > 0? 0 : WPTERR_GENERAL; |
return n > 0? 0 : WPTERR_GENERAL; |
428 |
} |
} |
429 |
|
|
440 |
return WPTERR_GENERAL; |
return WPTERR_GENERAL; |
441 |
|
|
442 |
do { |
do { |
443 |
rc = readLine (buf, 299, 1, &nn, NULL); |
rc = readLine (buf, DIM (buf)-1, 1, &nn, NULL); |
444 |
if (rc) |
if (rc) |
445 |
return rc; |
return rc; |
446 |
if (nn == 2) |
if (nn == 2) |
476 |
if (strnicmp (val, "text", 4)) { /* binary */ |
if (strnicmp (val, "text", 4)) { /* binary */ |
477 |
do { |
do { |
478 |
n = recv (fd, buf, nlen > 1024? 1024 : nlen, 0); |
n = recv (fd, buf, nlen > 1024? 1024 : nlen, 0); |
479 |
if (n == -1) |
if (n == -1) { |
480 |
|
this->error = (int)WSAGetLastError (); |
481 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
482 |
|
} |
483 |
if (n == 0) |
if (n == 0) |
484 |
break; |
break; |
485 |
nlen -= n; |
nlen -= n; |
489 |
} |
} |
490 |
|
|
491 |
do { |
do { |
492 |
rc = readLine (buf, 1024, 1, &n, &eof); |
rc = readLine (buf, DIM (buf)-1, 1, &n, &eof); |
493 |
if (rc) |
if (rc) |
494 |
return rc; |
return rc; |
495 |
if (n > 0) |
if (n > 0) |
552 |
/* Destroy HTTP object. */ |
/* Destroy HTTP object. */ |
553 |
wHTTP::~wHTTP (void) |
wHTTP::~wHTTP (void) |
554 |
{ |
{ |
|
|
|
555 |
http_head_t h; |
http_head_t h; |
556 |
|
|
557 |
while (resp_headers) { |
while (resp_headers) { |
564 |
free (req_headers); |
free (req_headers); |
565 |
req_headers = h; |
req_headers = h; |
566 |
} |
} |
567 |
free_if_malloc (url); |
safe_free (url); |
568 |
free_if_malloc (host); |
safe_free (host); |
569 |
if (fd != 0) { |
if (fd != 0) { |
570 |
closesocket (fd); |
closesocket (fd); |
571 |
fd = 0; |
fd = 0; |
612 |
} |
} |
613 |
|
|
614 |
|
|
615 |
/* Return the winsock specific error code. */ |
/* Return the Winsock specific error code. */ |
616 |
int wHTTP::getErrorCode (void) |
int wHTTP::getErrorCode (void) |
617 |
{ |
{ |
618 |
return error; |
return error; |