http.c (60737) | http.c (60954) |
---|---|
1/*- 2 * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * | 1/*- 2 * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/lib/libfetch/http.c 60737 2000-05-20 18:23:51Z ume $ | 28 * $FreeBSD: head/lib/libfetch/http.c 60954 2000-05-26 15:34:42Z des $ |
29 */ 30 31/* 32 * The base64 code in this file is based on code from MIT fetch, which 33 * has the following copyright and license: 34 * 35 *- 36 * Copyright 1997 Massachusetts Institute of Technology --- 42 unchanged lines hidden (view full) --- 79#include "httperr.h" 80 81extern char *__progname; 82 83#define ENDL "\r\n" 84 85#define HTTP_OK 200 86#define HTTP_PARTIAL 206 | 29 */ 30 31/* 32 * The base64 code in this file is based on code from MIT fetch, which 33 * has the following copyright and license: 34 * 35 *- 36 * Copyright 1997 Massachusetts Institute of Technology --- 42 unchanged lines hidden (view full) --- 79#include "httperr.h" 80 81extern char *__progname; 82 83#define ENDL "\r\n" 84 85#define HTTP_OK 200 86#define HTTP_PARTIAL 206 |
87#define HTTP_MOVED 302 |
|
87 88struct cookie 89{ 90 FILE *real_f; 91#define ENC_NONE 0 92#define ENC_CHUNKED 1 93 int encoding; /* 1 = chunked, 0 = none */ 94#define HTTPCTYPELEN 59 --- 312 unchanged lines hidden (view full) --- 407ouch: 408 if (sd >= 0) 409 close(sd); 410 _http_seterr(999); /* XXX do this properly RSN */ 411 return NULL; 412} 413 414/* | 88 89struct cookie 90{ 91 FILE *real_f; 92#define ENC_NONE 0 93#define ENC_CHUNKED 1 94 int encoding; /* 1 = chunked, 0 = none */ 95#define HTTPCTYPELEN 59 --- 312 unchanged lines hidden (view full) --- 408ouch: 409 if (sd >= 0) 410 close(sd); 411 _http_seterr(999); /* XXX do this properly RSN */ 412 return NULL; 413} 414 415/* |
416 * Check a header line 417 */ 418char * 419_http_match(char *str, char *hdr) 420{ 421 while (*str && *hdr && tolower(*str++) == tolower(*hdr++)) 422 /* nothing */; 423 if (*str || *hdr != ':') 424 return NULL; 425 while (*hdr && isspace(*++hdr)) 426 /* nothing */; 427 return hdr; 428} 429 430/* |
|
415 * Send a HEAD or GET request 416 */ 417int 418_http_request(FILE *f, char *op, struct url *URL, char *flags) 419{ 420 int e, verbose; 421 char *ln, *p; 422 size_t len; --- 49 unchanged lines hidden (view full) --- 472 return 999; 473 474 e = atoi(p); 475 DEBUG(fprintf(stderr, "code: [\033[1m%d\033[m]\n", e)); 476 return e; 477} 478 479/* | 431 * Send a HEAD or GET request 432 */ 433int 434_http_request(FILE *f, char *op, struct url *URL, char *flags) 435{ 436 int e, verbose; 437 char *ln, *p; 438 size_t len; --- 49 unchanged lines hidden (view full) --- 488 return 999; 489 490 e = atoi(p); 491 DEBUG(fprintf(stderr, "code: [\033[1m%d\033[m]\n", e)); 492 return e; 493} 494 495/* |
480 * Check a header line 481 */ 482char * 483_http_match(char *str, char *hdr) 484{ 485 while (*str && *hdr && tolower(*str++) == tolower(*hdr++)) 486 /* nothing */; 487 if (*str || *hdr != ':') 488 return NULL; 489 while (*hdr && isspace(*++hdr)) 490 /* nothing */; 491 return hdr; 492} 493 494/* | |
495 * Retrieve a file by HTTP 496 */ 497FILE * 498fetchGetHTTP(struct url *URL, char *flags) 499{ | 496 * Retrieve a file by HTTP 497 */ 498FILE * 499fetchGetHTTP(struct url *URL, char *flags) 500{ |
500 int e, enc = ENC_NONE, i; | 501 int e, enc = ENC_NONE, i, noredirect; |
501 struct cookie *c; 502 char *ln, *p, *q; 503 FILE *f, *cf; 504 size_t len; 505 off_t pos = 0; 506 | 502 struct cookie *c; 503 char *ln, *p, *q; 504 FILE *f, *cf; 505 size_t len; 506 off_t pos = 0; 507 |
508 noredirect = (flags && strchr(flags, 'A')); 509 |
|
507 /* allocate cookie */ 508 if ((c = calloc(1, sizeof *c)) == NULL) 509 return NULL; 510 511 /* connect */ 512 if ((f = _http_connect(URL, flags)) == NULL) { 513 free(c); 514 return NULL; 515 } 516 c->real_f = f; 517 518 e = _http_request(f, "GET", URL, flags); | 510 /* allocate cookie */ 511 if ((c = calloc(1, sizeof *c)) == NULL) 512 return NULL; 513 514 /* connect */ 515 if ((f = _http_connect(URL, flags)) == NULL) { 516 free(c); 517 return NULL; 518 } 519 c->real_f = f; 520 521 e = _http_request(f, "GET", URL, flags); |
519 520 /* add code to handle redirects later */ 521 if (e != (URL->offset ? HTTP_PARTIAL : HTTP_OK)) { | 522 if (e != (URL->offset ? HTTP_PARTIAL : HTTP_OK) 523 && (e != HTTP_MOVED || noredirect)) { |
522 _http_seterr(e); 523 goto fouch; 524 } 525 526 /* browse through header */ 527 while (1) { 528 if ((ln = fgetln(f, &len)) == NULL) 529 goto fouch; 530 if ((ln[0] == '\r') || (ln[0] == '\n')) 531 break; 532 while (isspace(ln[len-1])) 533 --len; 534 ln[len] = '\0'; /* XXX */ 535 DEBUG(fprintf(stderr, "header: [\033[1m%s\033[m]\n", ln)); | 524 _http_seterr(e); 525 goto fouch; 526 } 527 528 /* browse through header */ 529 while (1) { 530 if ((ln = fgetln(f, &len)) == NULL) 531 goto fouch; 532 if ((ln[0] == '\r') || (ln[0] == '\n')) 533 break; 534 while (isspace(ln[len-1])) 535 --len; 536 ln[len] = '\0'; /* XXX */ 537 DEBUG(fprintf(stderr, "header: [\033[1m%s\033[m]\n", ln)); |
536 if ((p = _http_match("Transfer-Encoding", ln)) != NULL) { | 538 if ((p = _http_match("Location", ln)) != NULL) { 539 struct url *url; 540 |
537 for (q = p; *q && !isspace(*q); q++) 538 /* VOID */ ; 539 *q = 0; | 541 for (q = p; *q && !isspace(*q); q++) 542 /* VOID */ ; 543 *q = 0; |
544 if ((url = fetchParseURL(p)) == NULL) 545 goto fouch; 546 url->offset = URL->offset; 547 url->length = URL->length; 548 DEBUG(fprintf(stderr, "location: [\033[1m%s\033[m]\n", p)); 549 cf = fetchGetHTTP(url, flags); 550 fetchFreeURL(url); 551 fclose(f); 552 return cf; 553 } else if ((p = _http_match("Transfer-Encoding", ln)) != NULL) { 554 for (q = p; *q && !isspace(*q); q++) 555 /* VOID */ ; 556 *q = 0; |
|
540 if (strcasecmp(p, "chunked") == 0) 541 enc = ENC_CHUNKED; 542 DEBUG(fprintf(stderr, "transfer encoding: [\033[1m%s\033[m]\n", p)); 543 } else if ((p = _http_match("Content-Type", ln)) != NULL) { 544 for (i = 0; *p && i < HTTPCTYPELEN; p++, i++) 545 c->content_type[i] = *p; 546 do c->content_type[i--] = 0; while (isspace(c->content_type[i])); 547 DEBUG(fprintf(stderr, "content type: [\033[1m%s\033[m]\n", --- 46 unchanged lines hidden (view full) --- 594} 595 596/* 597 * Get an HTTP document's metadata 598 */ 599int 600fetchStatHTTP(struct url *URL, struct url_stat *us, char *flags) 601{ | 557 if (strcasecmp(p, "chunked") == 0) 558 enc = ENC_CHUNKED; 559 DEBUG(fprintf(stderr, "transfer encoding: [\033[1m%s\033[m]\n", p)); 560 } else if ((p = _http_match("Content-Type", ln)) != NULL) { 561 for (i = 0; *p && i < HTTPCTYPELEN; p++, i++) 562 c->content_type[i] = *p; 563 do c->content_type[i--] = 0; while (isspace(c->content_type[i])); 564 DEBUG(fprintf(stderr, "content type: [\033[1m%s\033[m]\n", --- 46 unchanged lines hidden (view full) --- 611} 612 613/* 614 * Get an HTTP document's metadata 615 */ 616int 617fetchStatHTTP(struct url *URL, struct url_stat *us, char *flags) 618{ |
602 int e; | 619 int e, noredirect; |
603 size_t len; | 620 size_t len; |
604 char *ln, *p; | 621 char *ln, *p, *q; |
605 FILE *f; | 622 FILE *f; |
623 624 noredirect = (flags && strchr(flags, 'A')); |
|
606 607 us->size = -1; 608 us->atime = us->mtime = 0; 609 610 /* connect */ 611 if ((f = _http_connect(URL, flags)) == NULL) 612 return -1; 613 | 625 626 us->size = -1; 627 us->atime = us->mtime = 0; 628 629 /* connect */ 630 if ((f = _http_connect(URL, flags)) == NULL) 631 return -1; 632 |
614 if ((e = _http_request(f, "HEAD", URL, flags)) != HTTP_OK) { | 633 e = _http_request(f, "HEAD", URL, flags); 634 if (e != HTTP_OK && (e != HTTP_MOVED || noredirect)) { |
615 _http_seterr(e); 616 goto ouch; 617 } 618 619 while (1) { 620 if ((ln = fgetln(f, &len)) == NULL) 621 goto fouch; 622 if ((ln[0] == '\r') || (ln[0] == '\n')) 623 break; 624 while (isspace(ln[len-1])) 625 --len; 626 ln[len] = '\0'; /* XXX */ 627 DEBUG(fprintf(stderr, "header: [\033[1m%s\033[m]\n", ln)); | 635 _http_seterr(e); 636 goto ouch; 637 } 638 639 while (1) { 640 if ((ln = fgetln(f, &len)) == NULL) 641 goto fouch; 642 if ((ln[0] == '\r') || (ln[0] == '\n')) 643 break; 644 while (isspace(ln[len-1])) 645 --len; 646 ln[len] = '\0'; /* XXX */ 647 DEBUG(fprintf(stderr, "header: [\033[1m%s\033[m]\n", ln)); |
628 if ((p = _http_match("Last-Modified", ln)) != NULL) { | 648 if ((p = _http_match("Location", ln)) != NULL) { 649 struct url *url; 650 651 for (q = p; *q && !isspace(*q); q++) 652 /* VOID */ ; 653 *q = 0; 654 if ((url = fetchParseURL(p)) == NULL) 655 goto ouch; 656 url->offset = URL->offset; 657 url->length = URL->length; 658 DEBUG(fprintf(stderr, "location: [\033[1m%s\033[m]\n", p)); 659 e = fetchStatHTTP(url, us, flags); 660 fetchFreeURL(url); 661 fclose(f); 662 return e; 663 } else if ((p = _http_match("Last-Modified", ln)) != NULL) { |
629 struct tm tm; 630 char locale[64]; 631 632 strncpy(locale, setlocale(LC_TIME, NULL), sizeof locale); 633 setlocale(LC_TIME, "C"); 634 strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); 635 /* XXX should add support for date-2 and date-3 */ 636 setlocale(LC_TIME, locale); --- 31 unchanged lines hidden --- | 664 struct tm tm; 665 char locale[64]; 666 667 strncpy(locale, setlocale(LC_TIME, NULL), sizeof locale); 668 setlocale(LC_TIME, "C"); 669 strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); 670 /* XXX should add support for date-2 and date-3 */ 671 setlocale(LC_TIME, locale); --- 31 unchanged lines hidden --- |