33 |
#include "wptTypes.h" |
#include "wptTypes.h" |
34 |
#include "wptErrors.h" |
#include "wptErrors.h" |
35 |
|
|
|
#define free_if_malloc(buf) if ((buf)) { free ((buf)); (buf) = NULL; } |
|
36 |
|
|
37 |
/* Empty constructur to allow advanced requests. */ |
/* Empty constructur to allow advanced requests. */ |
38 |
wHTTP::wHTTP (void) |
wHTTP::wHTTP (void) |
76 |
fd = statcode = 0; |
fd = statcode = 0; |
77 |
method = HTTP_GET; |
method = HTTP_GET; |
78 |
nleft = -1; |
nleft = -1; |
79 |
|
error = 0; |
80 |
} |
} |
81 |
|
|
82 |
|
|
84 |
int |
int |
85 |
wHTTP::head (const char *_url) |
wHTTP::head (const char *_url) |
86 |
{ |
{ |
87 |
free_if_malloc (host); |
safe_free (host); |
88 |
free_if_malloc (url); |
safe_free (url); |
89 |
|
|
90 |
extractHostInfo (_url, &this->host, &this->url); |
extractHostInfo (_url, &this->host, &this->url); |
91 |
method = HTTP_HEAD; |
method = HTTP_HEAD; |
101 |
int |
int |
102 |
wHTTP::get (const char *_url) |
wHTTP::get (const char *_url) |
103 |
{ |
{ |
104 |
free_if_malloc (host); |
safe_free (host); |
105 |
free_if_alloc (url); |
safe_free (url); |
106 |
|
|
107 |
extractHostInfo (_url, &this->host, &this->url); |
extractHostInfo (_url, &this->host, &this->url); |
108 |
|
|
199 |
|
|
200 |
if (isalpha (*_host)) { |
if (isalpha (*_host)) { |
201 |
hp = gethostbyname (_host); |
hp = gethostbyname (_host); |
202 |
if (!hp) |
if (!hp) { |
203 |
|
this->error = (int)WSAGetLastError (); |
204 |
return WPTERR_WINSOCK_CONNECT; |
return WPTERR_WINSOCK_CONNECT; |
205 |
|
} |
206 |
memcpy (&srv.sin_addr, hp->h_addr, hp->h_length); |
memcpy (&srv.sin_addr, hp->h_addr, hp->h_length); |
207 |
} |
} |
208 |
else { |
else { |
209 |
addr = inet_addr (_host); |
addr = inet_addr (_host); |
210 |
if (addr == INADDR_NONE) |
if (addr == INADDR_NONE) { |
211 |
|
this->error = (int)WSAGetLastError (); |
212 |
return WPTERR_WINSOCK_CONNECT; |
return WPTERR_WINSOCK_CONNECT; |
213 |
|
} |
214 |
memcpy (&srv.sin_addr, &addr, sizeof addr); |
memcpy (&srv.sin_addr, &addr, sizeof addr); |
215 |
} |
} |
216 |
|
|
217 |
fd = socket (AF_INET, SOCK_STREAM, 0); |
fd = socket (AF_INET, SOCK_STREAM, 0); |
218 |
if (fd < 0) |
if (fd < 0) { |
219 |
|
this->error = (int)WSAGetLastError (); |
220 |
return WPTERR_WINSOCK_SOCKET; |
return WPTERR_WINSOCK_SOCKET; |
221 |
|
} |
222 |
|
|
223 |
if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, |
if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, |
224 |
(const char*)&i, sizeof i)) { |
(const char*)&i, sizeof i)) { |
225 |
closesocket (fd); |
closesocket (fd); |
226 |
fd = 0; |
fd = 0; |
227 |
|
this->error = (int)WSAGetLastError (); |
228 |
return WPTERR_WINSOCK_SOCKET; |
return WPTERR_WINSOCK_SOCKET; |
229 |
} |
} |
230 |
|
|
231 |
if (::connect (fd, (struct sockaddr *)&srv, sizeof srv)) { |
if (::connect (fd, (struct sockaddr *)&srv, sizeof srv)) { |
232 |
closesocket (fd); |
closesocket (fd); |
233 |
fd = 0; |
fd = 0; |
234 |
|
this->error = (int)WSAGetLastError (); |
235 |
return WPTERR_WINSOCK_CONNECT; |
return WPTERR_WINSOCK_CONNECT; |
236 |
} |
} |
237 |
|
|
277 |
break; |
break; |
278 |
} |
} |
279 |
n = recv (fd, &c, 1, 0); |
n = recv (fd, &c, 1, 0); |
280 |
if (n == -1) |
if (n == -1) { |
281 |
|
this->error = (int)WSAGetLastError (); |
282 |
break; |
break; |
283 |
|
} |
284 |
if (n == 0 || nbuf == 0 || c == '\n') { |
if (n == 0 || nbuf == 0 || c == '\n') { |
285 |
if (n == 0) { |
if (n == 0) { |
286 |
if (eof) |
if (eof) |
319 |
|
|
320 |
/* XXX: do not use static buffers. */ |
/* XXX: do not use static buffers. */ |
321 |
memset (tmpbuf, 0, sizeof (tmpbuf)); |
memset (tmpbuf, 0, sizeof (tmpbuf)); |
322 |
strncpy (tmpbuf, _url, 512); |
strncpy (tmpbuf, _url, sizeof (tmpbuf)-1); |
323 |
|
|
324 |
p = "http://"; |
p = "http://"; |
325 |
if (strlen (_url) < 10 || strncmp (_url, p, 7)) |
if (strlen (_url) < 10 || strncmp (_url, p, 7)) |
331 |
*_host = strdup (p); |
*_host = strdup (p); |
332 |
p = strchr (_url, '/'); |
p = strchr (_url, '/'); |
333 |
if (!p) { |
if (!p) { |
334 |
free_if_malloc (*_host); |
safe_free (*_host); |
335 |
return WPTERR_GENERAL; |
return WPTERR_GENERAL; |
336 |
} |
} |
337 |
*new_url = strdup (p); |
*new_url = strdup (p); |
346 |
char *p; |
char *p; |
347 |
char *fmt = "%s: %s"; |
char *fmt = "%s: %s"; |
348 |
|
|
349 |
p = (char*) malloc (strlen (name)+strlen (val)+strlen (fmt)+1); |
p = (char*) malloc (strlen (name)+strlen (val)+strlen (fmt)+4); |
350 |
sprintf (p, fmt, name, val); |
sprintf (p, fmt, name, val); |
351 |
addHeader (&req_headers, p); |
addHeader (&req_headers, p); |
352 |
free_if_malloc (p); |
safe_free (p); |
353 |
|
|
354 |
return 0; |
return 0; |
355 |
} |
} |
393 |
} |
} |
394 |
|
|
395 |
if (*_url == '/') |
if (*_url == '/') |
396 |
url++; |
_url++; |
397 |
if (_url == NULL) |
if (_url == NULL) |
398 |
_url = ""; |
_url = ""; |
399 |
|
|
404 |
n = 0; |
n = 0; |
405 |
for (h = req_headers; h; h = h->next) |
for (h = req_headers; h; h = h->next) |
406 |
n += strlen (h->d) + 2 + 1; |
n += strlen (h->d) + 2 + 1; |
|
|
|
407 |
h_head = "%s /%s HTTP/1.%d\r\n"; |
h_head = "%s /%s HTTP/1.%d\r\n"; |
408 |
p = (char*)calloc (1, strlen (id[method]) + strlen (h_head) |
n += strlen (id[method]) + strlen (h_head) |
409 |
+ strlen (url) + n + 2 + 1 + 4); |
+ strlen (_url) + n + 2 + 1 + 4; |
410 |
|
p = (char*)calloc (1, n+1); |
411 |
if (!p) |
if (!p) |
412 |
BUG (0); |
BUG (0); |
413 |
sprintf (p, h_head, id[method], url, ver); |
sprintf (p, h_head, id[method], _url, ver); |
414 |
for (h = req_headers; h; h = h->next) { |
for (h = req_headers; h; h = h->next) { |
415 |
strcat (p, h->d); |
strcat (p, h->d); |
416 |
strcat (p, "\r\n"); |
strcat (p, "\r\n"); |
417 |
} |
} |
418 |
strcat (p, "\r\n"); |
strcat (p, "\r\n"); |
|
printf ("p='%s'\n", p); |
|
419 |
n = send (fd, p, strlen (p), 0); |
n = send (fd, p, strlen (p), 0); |
420 |
free_if_malloc (p); |
safe_free (p); |
421 |
return n > 0? 0 : WPTERR_GENERAL; |
return n > 0? 0 : WPTERR_GENERAL; |
422 |
} |
} |
423 |
|
|
470 |
if (strnicmp (val, "text", 4)) { /* binary */ |
if (strnicmp (val, "text", 4)) { /* binary */ |
471 |
do { |
do { |
472 |
n = recv (fd, buf, nlen > 1024? 1024 : nlen, 0); |
n = recv (fd, buf, nlen > 1024? 1024 : nlen, 0); |
473 |
if (n == -1) |
if (n == -1) { |
474 |
|
this->error = (int)WSAGetLastError (); |
475 |
return SOCKET_ERROR; |
return SOCKET_ERROR; |
476 |
|
} |
477 |
if (n == 0) |
if (n == 0) |
478 |
break; |
break; |
479 |
nlen -= n; |
nlen -= n; |
483 |
} |
} |
484 |
|
|
485 |
do { |
do { |
486 |
rc = readLine (buf, 1024, 1, &n, &eof); |
rc = readLine (buf, sizeof (buf)-1, 1, &n, &eof); |
487 |
if (rc) |
if (rc) |
488 |
return rc; |
return rc; |
489 |
if (n > 0) |
if (n > 0) |
546 |
/* Destroy HTTP object. */ |
/* Destroy HTTP object. */ |
547 |
wHTTP::~wHTTP (void) |
wHTTP::~wHTTP (void) |
548 |
{ |
{ |
|
|
|
549 |
http_head_t h; |
http_head_t h; |
550 |
|
|
551 |
while (resp_headers) { |
while (resp_headers) { |
558 |
free (req_headers); |
free (req_headers); |
559 |
req_headers = h; |
req_headers = h; |
560 |
} |
} |
561 |
free_if_malloc (url); |
safe_free (url); |
562 |
free_if_malloc (host); |
safe_free (host); |
563 |
if (fd != 0) |
if (fd != 0) { |
564 |
closesocket (fd); |
closesocket (fd); |
565 |
|
fd = 0; |
566 |
|
} |
567 |
} |
} |
568 |
|
|
569 |
|
|
570 |
|
/* Read @buflen bytes from the http stream into the buffer @buf. */ |
571 |
int |
int |
572 |
wHTTP::read (void *buf, unsigned int buflen) |
wHTTP::read (void *buf, unsigned int buflen) |
573 |
{ |
{ |
594 |
} |
} |
595 |
|
|
596 |
|
|
597 |
|
/* Write the buffer @buf to the http stream. */ |
598 |
int |
int |
599 |
wHTTP::write (const void *buf, unsigned buflen) |
wHTTP::write (const void *buf, unsigned buflen) |
600 |
{ |
{ |
604 |
return -1; |
return -1; |
605 |
return send (fd, (const char*)buf, (int)buflen, 0); |
return send (fd, (const char*)buf, (int)buflen, 0); |
606 |
} |
} |
607 |
|
|
608 |
|
|
609 |
|
/* Return the Winsock specific error code. */ |
610 |
|
int wHTTP::getErrorCode (void) |
611 |
|
{ |
612 |
|
return error; |
613 |
|
} |