1/* 2 HTTP request/response handling 3 Copyright (C) 1999-2010, Joe Orton <joe@manyfish.co.uk> 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with this library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 18 MA 02111-1307, USA 19 20*/ 21 22/* This is the HTTP client request/response implementation. 23 * The goal of this code is to be modular and simple. 24 */ 25 26#include "config.h" 27 28#include <sys/types.h> 29 30#include <errno.h> 31#include <fcntl.h> 32#ifdef HAVE_STRING_H 33#include <string.h> 34#endif 35#ifdef HAVE_STRINGS_H 36#include <strings.h> 37#endif 38#ifdef HAVE_STDLIB_H 39#include <stdlib.h> 40#endif 41#ifdef HAVE_UNISTD_H 42#include <unistd.h> 43#endif 44 45#include "ne_internal.h" 46 47#include "ne_alloc.h" 48#include "ne_request.h" 49#include "ne_string.h" /* for ne_buffer */ 50#include "ne_utils.h" 51#include "ne_socket.h" 52#include "ne_uri.h" 53 54#include "ne_private.h" 55#include "webdav_base.h" //add by alan 56 57#define SOCK_ERR(req, op, msg) do { ssize_t sret = (op); \ 58if (sret < 0) return aborted(req, msg, sret); } while (0) 59 60#define EOL "\r\n" 61 62struct body_reader { 63 ne_block_reader handler; 64 ne_accept_response accept_response; 65 unsigned int use; 66 void *userdata; 67 struct body_reader *next; 68}; 69 70struct field { 71 char *name, *value; 72 size_t vlen; 73 struct field *next; 74}; 75 76/* Maximum number of header fields per response: */ 77#define MAX_HEADER_FIELDS (100) 78/* Size of hash table; 43 is the smallest prime for which the common 79 * header names hash uniquely using the *33 hash function. */ 80#define HH_HASHSIZE (43) 81/* Hash iteration step: *33 known to be a good hash for ASCII, see RSE. */ 82#define HH_ITERATE(hash, ch) (((hash)*33 + (unsigned char)(ch)) % HH_HASHSIZE) 83 84/* pre-calculated hash values for given header names: */ 85#define HH_HV_CONNECTION (0x14) 86#define HH_HV_PROXY_CONNECTION (0x1A) 87#define HH_HV_CONTENT_LENGTH (0x13) 88#define HH_HV_TRANSFER_ENCODING (0x07) 89 90struct ne_request_s { 91 char *method, *uri; /* method and Request-URI */ 92 93 ne_buffer *headers; /* request headers */ 94 95 /* Request body. */ 96 ne_provide_body body_cb; 97 void *body_ud; 98 99 /* Request body source: file or buffer (if not callback). */ 100 union { 101 struct { 102 int fd; 103 ne_off_t offset, length; 104 ne_off_t remain; /* remaining bytes to send. */ 105 } file; 106 struct { 107 /* length bytes @ buffer = whole body. 108 * remain bytes @ pnt = remaining bytes to send */ 109 const char *buffer, *pnt; 110 size_t length, remain; 111 } buf; 112 } body; 113 114 ne_off_t body_length; /* length of request body */ 115 116 /* temporary store for response lines. */ 117 char respbuf[NE_BUFSIZ]; 118 119 /**** Response ***/ 120 121 /* The transfer encoding types */ 122 struct ne_response { 123 enum { 124 R_TILLEOF = 0, /* read till eof */ 125 R_NO_BODY, /* implicitly no body (HEAD, 204, 304) */ 126 R_CHUNKED, /* using chunked transfer-encoding */ 127 R_CLENGTH /* using given content-length */ 128 } mode; 129 union { 130 /* clen: used if mode == R_CLENGTH; total and bytes 131 * remaining to be read of response body. */ 132 struct { 133 ne_off_t total, remain; 134 } clen; 135 /* chunk: used if mode == R_CHUNKED; total and bytes 136 * remaining to be read of current chunk */ 137 struct { 138 size_t total, remain; 139 } chunk; 140 } body; 141 ne_off_t progress; /* number of bytes read of response */ 142 } resp; 143 144 struct hook *private; 145 146 /* response header fields */ 147 struct field *response_headers[HH_HASHSIZE]; 148 149 unsigned int current_index; /* response_headers cursor for iterator */ 150 151 /* List of callbacks which are passed response body blocks */ 152 struct body_reader *body_readers; 153 154 /*** Miscellaneous ***/ 155 unsigned int method_is_head; 156 unsigned int can_persist; 157 158 int flags[NE_REQFLAG_LAST]; 159 160 ne_session *session; 161 ne_status status; 162}; 163 164static int open_connection(ne_session *sess); 165 166/* Returns hash value for header 'name', converting it to lower-case 167 * in-place. */ 168static inline unsigned int hash_and_lower(char *name) 169{ 170 char *pnt; 171 unsigned int hash = 0; 172 173 for (pnt = name; *pnt != '\0'; pnt++) { 174 *pnt = ne_tolower(*pnt); 175 hash = HH_ITERATE(hash,*pnt); 176 } 177 178 return hash; 179} 180 181/* Abort a request due to an non-recoverable HTTP protocol error, 182 * whilst doing 'doing'. 'code', if non-zero, is the socket error 183 * code, NE_SOCK_*, or if zero, is ignored. */ 184static int aborted(ne_request *req, const char *doing, ssize_t code) 185{ 186 ne_session *sess = req->session; 187 int ret = NE_ERROR; 188 189 NE_DEBUG(NE_DBG_HTTP, "Aborted request (%" NE_FMT_SSIZE_T "): %s\n", 190 code, doing); 191 192 switch(code) { 193 case NE_SOCK_CLOSED: 194 if (sess->nexthop->proxy != PROXY_NONE) { 195 ne_set_error(sess, _("%s: connection was closed by proxy server"), 196 doing); 197 } else { 198 ne_set_error(sess, _("%s: connection was closed by server"), 199 doing); 200 } 201 break; 202 case NE_SOCK_TIMEOUT: 203 ne_set_error(sess, _("%s: connection timed out"), doing); 204 ret = NE_TIMEOUT; 205 break; 206 case NE_SOCK_ERROR: 207 case NE_SOCK_RESET: 208 case NE_SOCK_TRUNC: 209 ne_set_error(sess, "%s: %s", doing, ne_sock_error(sess->socket)); 210 break; 211 case 0: 212 ne_set_error(sess, "%s", doing); 213 break; 214 } 215 216 ne_close_connection(sess); 217 return ret; 218} 219 220static void notify_status(ne_session *sess, ne_session_status status) 221{ 222 if (sess->notify_cb) { 223 sess->notify_cb(sess->notify_ud, status, &sess->status); 224 } 225} 226 227static void *get_private(const struct hook *hk, const char *id) 228{ 229 for (; hk != NULL; hk = hk->next) 230 if (strcmp(hk->id, id) == 0) 231 return hk->userdata; 232 return NULL; 233} 234 235void *ne_get_request_private(ne_request *req, const char *id) 236{ 237 return get_private(req->private, id); 238} 239 240void *ne_get_session_private(ne_session *sess, const char *id) 241{ 242 return get_private(sess->private, id); 243} 244 245void ne_set_request_private(ne_request *req, const char *id, void *userdata) 246{ 247 struct hook *hk = ne_malloc(sizeof (struct hook)), *pos; 248 249 if (req->private != NULL) { 250 for (pos = req->private; pos->next != NULL; pos = pos->next) 251 /* nullop */; 252 pos->next = hk; 253 } else { 254 req->private = hk; 255 } 256 257 hk->id = id; 258 hk->fn = NULL; 259 hk->userdata = userdata; 260 hk->next = NULL; 261} 262 263static ssize_t body_string_send(void *userdata, char *buffer, size_t count) 264{ 265 ne_request *req = userdata; 266 267 if (count == 0) { 268 req->body.buf.remain = req->body.buf.length; 269 req->body.buf.pnt = req->body.buf.buffer; 270 } else { 271 /* if body_left == 0 we fall through and return 0. */ 272 if (req->body.buf.remain < count) 273 count = req->body.buf.remain; 274 275 memcpy(buffer, req->body.buf.pnt, count); 276 req->body.buf.pnt += count; 277 req->body.buf.remain -= count; 278 } 279 280 return count; 281} 282 283static ssize_t body_fd_send(void *userdata, char *buffer, size_t count) 284{ 285 ne_request *req = userdata; 286 287 288 if (count) { 289 ssize_t ret; 290 291 if (req->body.file.remain == 0) 292 return 0; 293 294 /* Casts here are necessary for LFS platforms for safe and 295 * warning-free assignment/comparison between 32-bit size_t 296 * and 64-bit off64_t: */ 297 if ((ne_off_t)count > req->body.file.remain) 298 count = (size_t)req->body.file.remain; 299 300 ret = read(req->body.file.fd, buffer, count); 301 if (ret > 0) { 302 req->body.file.remain -= ret; 303 return ret; 304 } 305 else if (ret == 0) { 306 ne_set_error(req->session, 307 _("Premature EOF in request body file")); 308 } 309 else if (ret < 0) { 310 char err[200]; 311 int errnum = errno; 312 313 ne_set_error(req->session, 314 _("Failed reading request body file: %s"), 315 ne_strerror(errnum, err, sizeof err)); 316 } 317 318 return -1; 319 } else { 320 ne_off_t newoff; 321 322 /* rewind for next send. */ 323 newoff = ne_lseek(req->body.file.fd, req->body.file.offset, SEEK_SET); 324 if (newoff == req->body.file.offset) { 325 req->body.file.remain = req->body.file.length; 326 return 0; 327 } else { 328 char err[200], offstr[20]; 329 330 if (newoff == -1) { 331 /* errno was set */ 332 ne_strerror(errno, err, sizeof err); 333 } else { 334 strcpy(err, _("offset invalid")); 335 } 336 ne_snprintf(offstr, sizeof offstr, "%" FMT_NE_OFF_T, 337 req->body.file.offset); 338 ne_set_error(req->session, 339 _("Could not seek to offset %s" 340 " of request body file: %s"), 341 offstr, err); 342 return -1; 343 } 344 } 345} 346 347/* For accurate persistent connection handling, for any write() or 348 * read() operation for a new request on an already-open connection, 349 * an EOF or RST error MUST be treated as a persistent connection 350 * timeout, and the request retried on a new connection. Once a 351 * read() operation has succeeded, any subsequent error MUST be 352 * treated as fatal. A 'retry' flag is used; retry=1 represents the 353 * first case, retry=0 the latter. */ 354 355/* RETRY_RET() crafts a function return value given the 'retry' flag, 356 * the socket error 'code', and the return value 'acode' from the 357 * aborted() function. */ 358#define RETRY_RET(retry, code, acode) \ 359((((code) == NE_SOCK_CLOSED || (code) == NE_SOCK_RESET || \ 360 (code) == NE_SOCK_TRUNC) && retry) ? NE_RETRY : (acode)) 361 362/* Sends the request body; returns 0 on success or an NE_* error code. 363 * If retry is non-zero; will return NE_RETRY on persistent connection 364 * timeout. On error, the session error string is set and the 365 * connection is closed. */ 366static int send_request_body(ne_request *req, int retry) 367{ 368 ne_session *const sess = req->session; 369 char buffer[NE_BUFSIZ]; 370 ssize_t bytes; 371 372 NE_DEBUG(NE_DBG_HTTP, "Sending request body:\n"); 373 374 req->session->status.sr.progress = 0; 375 req->session->status.sr.total = req->body_length; 376 notify_status(sess, ne_status_sending); 377 378 /* tell the source to start again from the beginning. */ 379 if (req->body_cb(req->body_ud, NULL, 0) != 0) { 380 ne_close_connection(sess); 381 return NE_ERROR; 382 } 383 384 while ((bytes = req->body_cb(req->body_ud, buffer, sizeof buffer)) > 0) { 385 //next 3 rows add by alan 386 if(exit_loop == 1){ 387 return NE_WEBDAV_QUIT; 388 } 389 int ret = ne_sock_fullwrite(sess->socket, buffer, bytes); 390 if (ret < 0) { 391 int aret = aborted(req, _("Could not send request body"), ret); 392 return RETRY_RET(retry, ret, aret); 393 } 394 395 NE_DEBUG(NE_DBG_HTTPBODY, 396 "Body block (%" NE_FMT_SSIZE_T " bytes):\n[%.*s]\n", 397 bytes, (int)bytes, buffer); 398 399 /* invoke progress callback */ 400 req->session->status.sr.progress += bytes; 401 notify_status(sess, ne_status_sending); 402 } 403 404 if (bytes == 0) { 405 return NE_OK; 406 } else { 407 NE_DEBUG(NE_DBG_HTTP, "Request body provider failed with " 408 "%" NE_FMT_SSIZE_T "\n", bytes); 409 ne_close_connection(sess); 410 return NE_ERROR; 411 } 412} 413 414/* Lob the User-Agent, connection and host headers in to the request 415 * headers */ 416static void add_fixed_headers(ne_request *req) 417{ 418 ne_session *const sess = req->session; 419 420 if (sess->user_agent) { 421 ne_buffer_zappend(req->headers, sess->user_agent); 422 } 423 424 /* If persistent connections are disabled, just send Connection: 425 * close; otherwise, send Connection: Keep-Alive to pre-1.1 origin 426 * servers to try harder to get a persistent connection, except if 427 * using a proxy as per 2068��19.7.1. Always add TE: trailers. */ 428 if (!sess->flags[NE_SESSFLAG_PERSIST]) { 429 ne_buffer_czappend(req->headers, "Connection: TE, close" EOL); 430 } 431 else if (!sess->is_http11 && !sess->any_proxy_http) { 432 ne_buffer_czappend(req->headers, 433 "Keep-Alive: " EOL 434 "Connection: TE, Keep-Alive" EOL); 435 } 436 else if (!req->session->is_http11 && !sess->any_proxy_http) { 437 ne_buffer_czappend(req->headers, 438 "Keep-Alive: " EOL 439 "Proxy-Connection: Keep-Alive" EOL 440 "Connection: TE" EOL); 441 } 442 else { 443 ne_buffer_czappend(req->headers, "Connection: TE" EOL); 444 } 445 446 ne_buffer_concat(req->headers, "TE: trailers" EOL "Host: ", 447 req->session->server.hostport, EOL, NULL); 448} 449 450int ne_accept_always(void *userdata, ne_request *req, const ne_status *st) 451{ 452 return 1; 453} 454 455int ne_accept_2xx(void *userdata, ne_request *req, const ne_status *st) 456{ 457 return (st->klass == 2); 458} 459 460ne_request *ne_request_create(ne_session *sess, 461 const char *method, const char *path) 462{ 463 ne_request *req = ne_calloc(sizeof *req); 464 465 req->session = sess; 466 req->headers = ne_buffer_create(); 467 468 /* Presume the method is idempotent by default. */ 469 req->flags[NE_REQFLAG_IDEMPOTENT] = 1; 470 /* Expect-100 default follows the corresponding session flag. */ 471 req->flags[NE_REQFLAG_EXPECT100] = sess->flags[NE_SESSFLAG_EXPECT100]; 472 473 /* Add in the fixed headers */ 474 add_fixed_headers(req); 475 476 /* Set the standard stuff */ 477 req->method = ne_strdup(method); 478 req->method_is_head = (strcmp(method, "HEAD") == 0); 479 480 /* Only use an absoluteURI here when we might be using an HTTP 481 * proxy, and SSL is in use: some servers can't parse them. */ 482 if (sess->any_proxy_http && !req->session->use_ssl && path[0] == '/') 483 req->uri = ne_concat(req->session->scheme, "://", 484 req->session->server.hostport, path, NULL); 485 else 486 req->uri = ne_strdup(path); 487 488 { 489 struct hook *hk; 490 491 for (hk = sess->create_req_hooks; hk != NULL; hk = hk->next) { 492 ne_create_request_fn fn = (ne_create_request_fn)hk->fn; 493 fn(req, hk->userdata, req->method, req->uri); 494 } 495 } 496 497 return req; 498} 499 500/* Set the request body length to 'length' */ 501static void set_body_length(ne_request *req, ne_off_t length) 502{ 503 req->body_length = length; 504 ne_print_request_header(req, "Content-Length", "%" FMT_NE_OFF_T, length); 505} 506 507void ne_set_request_body_buffer(ne_request *req, const char *buffer, 508 size_t size) 509{ 510 req->body.buf.buffer = buffer; 511 req->body.buf.length = size; 512 req->body_cb = body_string_send; 513 req->body_ud = req; 514 set_body_length(req, size); 515} 516 517void ne_set_request_body_provider(ne_request *req, ne_off_t bodysize, 518 ne_provide_body provider, void *ud) 519{ 520 req->body_cb = provider; 521 req->body_ud = ud; 522 set_body_length(req, bodysize); 523} 524 525void ne_set_request_body_fd(ne_request *req, int fd, 526 ne_off_t offset, ne_off_t length) 527{ 528 req->body.file.fd = fd; 529 req->body.file.offset = offset; 530 req->body.file.length = length; 531 req->body_cb = body_fd_send; 532 req->body_ud = req; 533 set_body_length(req, length); 534} 535 536void ne_set_request_flag(ne_request *req, ne_request_flag flag, int value) 537{ 538 if (flag < NE_SESSFLAG_LAST) { 539 req->flags[flag] = value; 540 } 541} 542 543int ne_get_request_flag(ne_request *req, ne_request_flag flag) 544{ 545 if (flag < NE_REQFLAG_LAST) { 546 return req->flags[flag]; 547 } 548 return -1; 549} 550 551void ne_add_request_header(ne_request *req, const char *name, 552 const char *value) 553{ 554 ne_buffer_concat(req->headers, name, ": ", value, EOL, NULL); 555} 556 557void ne_print_request_header(ne_request *req, const char *name, 558 const char *format, ...) 559{ 560 va_list params; 561 char buf[NE_BUFSIZ]; 562 563 va_start(params, format); 564 ne_vsnprintf(buf, sizeof buf, format, params); 565 va_end(params); 566 567 ne_buffer_concat(req->headers, name, ": ", buf, EOL, NULL); 568} 569 570/* Returns the value of the response header 'name', for which the hash 571 * value is 'h', or NULL if the header is not found. */ 572static inline char *get_response_header_hv(ne_request *req, unsigned int h, 573 const char *name) 574{ 575 struct field *f; 576 577 for (f = req->response_headers[h]; f; f = f->next) 578 if (strcmp(f->name, name) == 0) 579 return f->value; 580 581 return NULL; 582} 583 584const char *ne_get_response_header(ne_request *req, const char *name) 585{ 586 char *lcname = ne_strdup(name); 587 unsigned int hash = hash_and_lower(lcname); 588 char *value = get_response_header_hv(req, hash, lcname); 589 ne_free(lcname); 590 return value; 591} 592 593/* The return value of the iterator function is a pointer to the 594 * struct field of the previously returned header. */ 595void *ne_response_header_iterate(ne_request *req, void *iterator, 596 const char **name, const char **value) 597{ 598 struct field *f = iterator; 599 unsigned int n; 600 601 if (f == NULL) { 602 n = 0; 603 } else if ((f = f->next) == NULL) { 604 n = req->current_index + 1; 605 } 606 607 if (f == NULL) { 608 while (n < HH_HASHSIZE && req->response_headers[n] == NULL) 609 n++; 610 if (n == HH_HASHSIZE) 611 return NULL; /* no more headers */ 612 f = req->response_headers[n]; 613 req->current_index = n; 614 } 615 616 *name = f->name; 617 *value = f->value; 618 return f; 619} 620 621/* Removes the response header 'name', which has hash value 'hash'. */ 622static void remove_response_header(ne_request *req, const char *name, 623 unsigned int hash) 624{ 625 struct field **ptr = req->response_headers + hash; 626 627 while (*ptr) { 628 struct field *const f = *ptr; 629 630 if (strcmp(f->name, name) == 0) { 631 *ptr = f->next; 632 ne_free(f->name); 633 ne_free(f->value); 634 ne_free(f); 635 return; 636 } 637 638 ptr = &f->next; 639 } 640} 641 642/* Free all stored response headers. */ 643static void free_response_headers(ne_request *req) 644{ 645 int n; 646 647 for (n = 0; n < HH_HASHSIZE; n++) { 648 struct field **ptr = req->response_headers + n; 649 650 while (*ptr) { 651 struct field *const f = *ptr; 652 *ptr = f->next; 653 ne_free(f->name); 654 ne_free(f->value); 655 ne_free(f); 656 } 657 } 658} 659 660void ne_add_response_body_reader(ne_request *req, ne_accept_response acpt, 661 ne_block_reader rdr, void *userdata) 662{ 663 struct body_reader *new = ne_malloc(sizeof *new); 664 new->accept_response = acpt; 665 new->handler = rdr; 666 new->userdata = userdata; 667 new->next = req->body_readers; 668 req->body_readers = new; 669} 670 671void ne_request_destroy(ne_request *req) 672{ 673 struct body_reader *rdr, *next_rdr; 674 struct hook *hk, *next_hk; 675 676 ne_free(req->uri); 677 ne_free(req->method); 678 679 for (rdr = req->body_readers; rdr != NULL; rdr = next_rdr) { 680 next_rdr = rdr->next; 681 ne_free(rdr); 682 } 683 684 free_response_headers(req); 685 686 ne_buffer_destroy(req->headers); 687 688 NE_DEBUG(NE_DBG_HTTP, "Running destroy hooks.\n"); 689 for (hk = req->session->destroy_req_hooks; hk; hk = next_hk) { 690 ne_destroy_req_fn fn = (ne_destroy_req_fn)hk->fn; 691 next_hk = hk->next; 692 fn(req, hk->userdata); 693 } 694 695 for (hk = req->private; hk; hk = next_hk) { 696 next_hk = hk->next; 697 ne_free(hk); 698 } 699 700 if (req->status.reason_phrase) 701 ne_free(req->status.reason_phrase); 702 703 NE_DEBUG(NE_DBG_HTTP, "Request ends.\n"); 704 ne_free(req); 705} 706 707 708/* Reads a block of the response into BUFFER, which is of size 709 * *BUFLEN. Returns zero on success or non-zero on error. On 710 * success, *BUFLEN is updated to be the number of bytes read into 711 * BUFFER (which will be 0 to indicate the end of the repsonse). On 712 * error, the connection is closed and the session error string is 713 * set. */ 714static int read_response_block(ne_request *req, struct ne_response *resp, 715 char *buffer, size_t *buflen) 716{ 717 ne_socket *const sock = req->session->socket; 718 size_t willread; 719 ssize_t readlen; 720 721 switch (resp->mode) { 722 case R_CHUNKED: 723 /* Chunked transfer-encoding: chunk syntax is "SIZE CRLF CHUNK 724 * CRLF SIZE CRLF CHUNK CRLF ..." followed by zero-length 725 * chunk: "CHUNK CRLF 0 CRLF". resp.chunk.remain contains the 726 * number of bytes left to read in the current chunk. */ 727 if (resp->body.chunk.remain == 0) { 728 unsigned long chunk_len; 729 char *ptr; 730 731 /* Read the chunk size line into a temporary buffer. */ 732 SOCK_ERR(req, 733 ne_sock_readline(sock, req->respbuf, sizeof req->respbuf), 734 _("Could not read chunk size")); 735 NE_DEBUG(NE_DBG_HTTP, "[chunk] < %s", req->respbuf); 736 chunk_len = strtoul(req->respbuf, &ptr, 16); 737 /* limit chunk size to <= UINT_MAX, so it will probably 738 * fit in a size_t. */ 739 if (ptr == req->respbuf || 740 chunk_len == ULONG_MAX || chunk_len > UINT_MAX) { 741 return aborted(req, _("Could not parse chunk size"), 0); 742 } 743 NE_DEBUG(NE_DBG_HTTP, "Got chunk size: %lu\n", chunk_len); 744 resp->body.chunk.remain = chunk_len; 745 } 746 willread = resp->body.chunk.remain > *buflen 747 ? *buflen : resp->body.chunk.remain; 748 break; 749 case R_CLENGTH: 750 willread = resp->body.clen.remain > (off_t)*buflen 751 ? *buflen : (size_t)resp->body.clen.remain; 752 break; 753 case R_TILLEOF: 754 willread = *buflen; 755 break; 756 case R_NO_BODY: 757 default: 758 willread = 0; 759 break; 760 } 761 if (willread == 0) { 762 *buflen = 0; 763 return 0; 764 } 765 NE_DEBUG(NE_DBG_HTTP, 766 "Reading %" NE_FMT_SIZE_T " bytes of response body.\n", willread); 767 readlen = ne_sock_read(sock, buffer, willread); 768 769 /* EOF is only valid when response body is delimited by it. 770 * Strictly, an SSL truncation should not be treated as an EOF in 771 * any case, but SSL servers are just too buggy. */ 772 if (resp->mode == R_TILLEOF && 773 (readlen == NE_SOCK_CLOSED || readlen == NE_SOCK_TRUNC)) { 774 NE_DEBUG(NE_DBG_HTTP, "Got EOF.\n"); 775 req->can_persist = 0; 776 readlen = 0; 777 } else if (readlen < 0) { 778 return aborted(req, _("Could not read response body"), readlen); 779 } else { 780 NE_DEBUG(NE_DBG_HTTP, "Got %" NE_FMT_SSIZE_T " bytes.\n", readlen); 781 } 782 /* safe to cast: readlen guaranteed to be >= 0 above */ 783 *buflen = (size_t)readlen; 784 NE_DEBUG(NE_DBG_HTTPBODY, 785 "Read block (%" NE_FMT_SSIZE_T " bytes):\n[%.*s]\n", 786 readlen, (int)readlen, buffer); 787 if (resp->mode == R_CHUNKED) { 788 resp->body.chunk.remain -= readlen; 789 if (resp->body.chunk.remain == 0) { 790 char crlfbuf[2]; 791 /* If we've read a whole chunk, read a CRLF */ 792 readlen = ne_sock_fullread(sock, crlfbuf, 2); 793 if (readlen < 0) 794 return aborted(req, _("Could not read chunk delimiter"), 795 readlen); 796 else if (crlfbuf[0] != '\r' || crlfbuf[1] != '\n') 797 return aborted(req, _("Chunk delimiter was invalid"), 0); 798 } 799 } else if (resp->mode == R_CLENGTH) { 800 resp->body.clen.remain -= readlen; 801 } 802 resp->progress += readlen; 803 return NE_OK; 804} 805 806ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen) 807{ 808 struct body_reader *rdr; 809 size_t readlen = buflen; 810 struct ne_response *const resp = &req->resp; 811 812 if (read_response_block(req, resp, buffer, &readlen)) 813 return -1; 814 815 if (readlen) { 816 req->session->status.sr.progress += readlen; 817 notify_status(req->session, ne_status_recving); 818 } 819 820 for (rdr = req->body_readers; rdr!=NULL; rdr=rdr->next) { 821 if (rdr->use && rdr->handler(rdr->userdata, buffer, readlen) != 0) { 822 ne_close_connection(req->session); 823 return -1; 824 } 825 } 826 827 return readlen; 828} 829 830/* Build the request string, returning the buffer. */ 831static ne_buffer *build_request(ne_request *req) 832{ 833 struct hook *hk; 834 ne_buffer *buf = ne_buffer_create(); 835 836 /* Add Request-Line and headers: */ 837 ne_buffer_concat(buf, req->method, " ", req->uri, " HTTP/1.1" EOL, NULL); 838 839 /* Add custom headers: */ 840 ne_buffer_append(buf, req->headers->data, ne_buffer_size(req->headers)); 841 842 if (req->body_length && req->flags[NE_REQFLAG_EXPECT100]) { 843 ne_buffer_czappend(buf, "Expect: 100-continue\r\n"); 844 } 845 846 NE_DEBUG(NE_DBG_HTTP, "Running pre_send hooks\n"); 847 for (hk = req->session->pre_send_hooks; hk!=NULL; hk = hk->next) { 848 ne_pre_send_fn fn = (ne_pre_send_fn)hk->fn; 849 fn(req, hk->userdata, buf); 850 } 851 852 ne_buffer_czappend(buf, "\r\n"); 853 return buf; 854} 855 856#ifdef NE_DEBUGGING 857#define DEBUG_DUMP_REQUEST(x) dump_request(x) 858 859static void dump_request(const char *request) 860{ 861 if (ne_debug_mask & NE_DBG_HTTPPLAIN) { 862 /* Display everything mode */ 863 NE_DEBUG(NE_DBG_HTTP, "Sending request headers:\n%s", request); 864 } else if (ne_debug_mask & NE_DBG_HTTP) { 865 /* Blank out the Authorization paramaters */ 866 char *reqdebug = ne_strdup(request), *pnt = reqdebug; 867 while ((pnt = strstr(pnt, "Authorization: ")) != NULL) { 868 for (pnt += 15; *pnt != '\r' && *pnt != '\0'; pnt++) { 869 *pnt = 'x'; 870 } 871 } 872 NE_DEBUG(NE_DBG_HTTP, "Sending request headers:\n%s", reqdebug); 873 ne_free(reqdebug); 874 } 875} 876 877#else 878#define DEBUG_DUMP_REQUEST(x) 879#endif /* DEBUGGING */ 880 881/* remove trailing EOL from 'buf', where strlen(buf) == *len. *len is 882 * adjusted in accordance with any changes made to the string to 883 * remain equal to strlen(buf). */ 884static inline void strip_eol(char *buf, ssize_t *len) 885{ 886 char *pnt = buf + *len - 1; 887 while (pnt >= buf && (*pnt == '\r' || *pnt == '\n')) { 888 *pnt-- = '\0'; 889 (*len)--; 890 } 891} 892 893/* Read and parse response status-line into 'status'. 'retry' is non-zero 894 * if an NE_RETRY should be returned if an EOF is received. */ 895static int read_status_line(ne_request *req, ne_status *status, int retry) 896{ 897 char *buffer = req->respbuf; 898 ssize_t ret; 899 900 ret = ne_sock_readline(req->session->socket, buffer, sizeof req->respbuf); 901 if (ret <= 0) { 902 int aret = aborted(req, _("Could not read status line"), ret); 903 return RETRY_RET(retry, ret, aret); 904 } 905 906 NE_DEBUG(NE_DBG_HTTP, "[status-line] < %s", buffer); 907 strip_eol(buffer, &ret); 908 909 if (status->reason_phrase) ne_free(status->reason_phrase); 910 memset(status, 0, sizeof *status); 911 912 /* Hack to allow ShoutCast-style servers, if requested. */ 913 if (req->session->flags[NE_SESSFLAG_ICYPROTO] 914 && strncmp(buffer, "ICY ", 4) == 0 && strlen(buffer) > 8 915 && buffer[7] == ' ') { 916 status->code = atoi(buffer + 4); 917 status->major_version = 1; 918 status->minor_version = 0; 919 status->reason_phrase = ne_strclean(ne_strdup(buffer + 8)); 920 status->klass = buffer[4] - '0'; 921 NE_DEBUG(NE_DBG_HTTP, "[status-line] ICY protocol; code %d\n", 922 status->code); 923 } else if (ne_parse_statusline(buffer, status)) { 924 return aborted(req, _("Could not parse response status line"), 0); 925 } 926 927 return 0; 928} 929 930/* Discard a set of message headers. */ 931static int discard_headers(ne_request *req) 932{ 933 do { 934 SOCK_ERR(req, ne_sock_readline(req->session->socket, req->respbuf, 935 sizeof req->respbuf), 936 _("Could not read interim response headers")); 937 NE_DEBUG(NE_DBG_HTTP, "[discard] < %s", req->respbuf); 938 } while (strcmp(req->respbuf, EOL) != 0); 939 return NE_OK; 940} 941 942/* Send the request, and read the response Status-Line. Returns: 943 * NE_RETRY connection closed by server; persistent connection 944 * timeout 945 * NE_OK success 946 * NE_* error 947 * On NE_RETRY and NE_* responses, the connection will have been 948 * closed already. 949 */ 950static int send_request(ne_request *req, const ne_buffer *request) 951{ 952 ne_session *const sess = req->session; 953 ne_status *const status = &req->status; 954 int sentbody = 0; /* zero until body has been sent. */ 955 int ret, retry; /* retry non-zero whilst the request should be retried */ 956 ssize_t sret; 957 958 /* Send the Request-Line and headers */ 959 NE_DEBUG(NE_DBG_HTTP, "Sending request-line and headers:\n"); 960 /* Open the connection if necessary */ 961 ret = open_connection(sess); 962 if (ret) return ret; 963 964 /* Allow retry if a persistent connection has been used. */ 965 retry = sess->persisted; 966 967 sret = ne_sock_fullwrite(req->session->socket, request->data, 968 ne_buffer_size(request)); 969 if (sret < 0) { 970 int aret = aborted(req, _("Could not send request"), sret); 971 return RETRY_RET(retry, sret, aret); 972 } 973 974 if (!req->flags[NE_REQFLAG_EXPECT100] && req->body_length > 0) { 975 /* Send request body, if not using 100-continue. */ 976 ret = send_request_body(req, retry); 977 if (ret) { 978 return ret; 979 } 980 } 981 982 NE_DEBUG(NE_DBG_HTTP, "Request sent; retry is %d.\n", retry); 983 984 /* Loop eating interim 1xx responses (RFC2616 says these MAY be 985 * sent by the server, even if 100-continue is not used). */ 986 while ((ret = read_status_line(req, status, retry)) == NE_OK 987 && status->klass == 1) { 988 NE_DEBUG(NE_DBG_HTTP, "Interim %d response.\n", status->code); 989 retry = 0; /* successful read() => never retry now. */ 990 /* Discard headers with the interim response. */ 991 if ((ret = discard_headers(req)) != NE_OK) break; 992 993 if (req->flags[NE_REQFLAG_EXPECT100] && (status->code == 100) 994 && req->body_length > 0 && !sentbody) { 995 /* Send the body after receiving the first 100 Continue */ 996 if ((ret = send_request_body(req, 0)) != NE_OK) break; 997 sentbody = 1; 998 } 999 } 1000 1001 return ret; 1002} 1003 1004/* Read a message header from sock into buf, which has size 'buflen'. 1005 * 1006 * Returns: 1007 * NE_RETRY: Success, read a header into buf. 1008 * NE_OK: End of headers reached. 1009 * NE_ERROR: Error (session error is set, connection closed). 1010 */ 1011static int read_message_header(ne_request *req, char *buf, size_t buflen) 1012{ 1013 ssize_t n; 1014 ne_socket *sock = req->session->socket; 1015 1016 n = ne_sock_readline(sock, buf, buflen); 1017 if (n <= 0) 1018 return aborted(req, _("Error reading response headers"), n); 1019 NE_DEBUG(NE_DBG_HTTP, "[hdr] %s", buf); 1020 1021 strip_eol(buf, &n); 1022 1023 if (n == 0) { 1024 NE_DEBUG(NE_DBG_HTTP, "End of headers.\n"); 1025 return NE_OK; 1026 } 1027 1028 buf += n; 1029 buflen -= n; 1030 1031 while (buflen > 0) { 1032 char ch; 1033 1034 /* Collect any extra lines into buffer */ 1035 SOCK_ERR(req, ne_sock_peek(sock, &ch, 1), 1036 _("Error reading response headers")); 1037 1038 if (ch != ' ' && ch != '\t') { 1039 /* No continuation of this header: stop reading. */ 1040 return NE_RETRY; 1041 } 1042 1043 /* Otherwise, read the next line onto the end of 'buf'. */ 1044 n = ne_sock_readline(sock, buf, buflen); 1045 if (n <= 0) { 1046 return aborted(req, _("Error reading response headers"), n); 1047 } 1048 1049 NE_DEBUG(NE_DBG_HTTP, "[cont] %s", buf); 1050 1051 strip_eol(buf, &n); 1052 1053 /* assert(buf[0] == ch), which implies len(buf) > 0. 1054 * Otherwise the TCP stack is lying, but we'll be paranoid. 1055 * This might be a \t, so replace it with a space to be 1056 * friendly to applications (2616 says we MAY do this). */ 1057 if (n) buf[0] = ' '; 1058 1059 /* ready for the next header. */ 1060 buf += n; 1061 buflen -= n; 1062 } 1063 1064 ne_set_error(req->session, _("Response header too long")); 1065 return NE_ERROR; 1066} 1067 1068#define MAX_HEADER_LEN (8192) 1069 1070/* Add a respnose header field for the given request, using 1071 * precalculated hash value. */ 1072static void add_response_header(ne_request *req, unsigned int hash, 1073 char *name, char *value) 1074{ 1075 struct field **nextf = &req->response_headers[hash]; 1076 size_t vlen = strlen(value); 1077 1078 while (*nextf) { 1079 struct field *const f = *nextf; 1080 if (strcmp(f->name, name) == 0) { 1081 if (vlen + f->vlen < MAX_HEADER_LEN) { 1082 /* merge the header field */ 1083 f->value = ne_realloc(f->value, f->vlen + vlen + 3); 1084 memcpy(f->value + f->vlen, ", ", 2); 1085 memcpy(f->value + f->vlen + 2, value, vlen + 1); 1086 f->vlen += vlen + 2; 1087 } 1088 return; 1089 } 1090 nextf = &f->next; 1091 } 1092 1093 (*nextf) = ne_malloc(sizeof **nextf); 1094 (*nextf)->name = ne_strdup(name); 1095 (*nextf)->value = ne_strdup(value); 1096 (*nextf)->vlen = vlen; 1097 (*nextf)->next = NULL; 1098} 1099 1100/* Read response headers. Returns NE_* code, sets session error and 1101 * closes connection on error. */ 1102static int read_response_headers(ne_request *req) 1103{ 1104 char hdr[MAX_HEADER_LEN]; 1105 int ret, count = 0; 1106 1107 while ((ret = read_message_header(req, hdr, sizeof hdr)) == NE_RETRY 1108 && ++count < MAX_HEADER_FIELDS) { 1109 char *pnt; 1110 unsigned int hash = 0; 1111 1112 /* Strip any trailing whitespace */ 1113 pnt = hdr + strlen(hdr) - 1; 1114 while (pnt > hdr && (*pnt == ' ' || *pnt == '\t')) 1115 *pnt-- = '\0'; 1116 1117 /* Convert the header name to lower case and hash it. */ 1118 for (pnt = hdr; (*pnt != '\0' && *pnt != ':' && 1119 *pnt != ' ' && *pnt != '\t'); pnt++) { 1120 *pnt = ne_tolower(*pnt); 1121 hash = HH_ITERATE(hash,*pnt); 1122 } 1123 1124 /* Skip over any whitespace before the colon. */ 1125 while (*pnt == ' ' || *pnt == '\t') 1126 *pnt++ = '\0'; 1127 1128 /* ignore header lines which lack a ':'. */ 1129 if (*pnt != ':') 1130 continue; 1131 1132 /* NUL-terminate at the colon (when no whitespace before) */ 1133 *pnt++ = '\0'; 1134 1135 /* Skip any whitespace after the colon... */ 1136 while (*pnt == ' ' || *pnt == '\t') 1137 pnt++; 1138 1139 /* pnt now points to the header value. */ 1140 NE_DEBUG(NE_DBG_HTTP, "Header Name: [%s], Value: [%s]\n", hdr, pnt); 1141 add_response_header(req, hash, hdr, pnt); 1142 } 1143 1144 if (count == MAX_HEADER_FIELDS) 1145 ret = aborted( 1146 req, _("Response exceeded maximum number of header fields"), 0); 1147 1148 return ret; 1149} 1150 1151/* Perform any necessary DNS lookup for the host given by *info; 1152 * returns NE_ code with error string set on error. */ 1153static int lookup_host(ne_session *sess, struct host_info *info) 1154{ 1155 NE_DEBUG(NE_DBG_HTTP, "Doing DNS lookup on %s...\n", info->hostname); 1156 sess->status.lu.hostname = info->hostname; 1157 notify_status(sess, ne_status_lookup); 1158 info->address = ne_addr_resolve(info->hostname, 0); 1159 if (ne_addr_result(info->address)) { 1160 char buf[256]; 1161 ne_set_error(sess, _("Could not resolve hostname `%s': %s"), 1162 info->hostname, 1163 ne_addr_error(info->address, buf, sizeof buf)); 1164 ne_addr_destroy(info->address); 1165 info->address = NULL; 1166 return NE_LOOKUP; 1167 } else { 1168 return NE_OK; 1169 } 1170} 1171 1172int ne_begin_request(ne_request *req) 1173{ 1174 struct body_reader *rdr; 1175 ne_buffer *data; 1176 const ne_status *const st = &req->status; 1177 const char *value; 1178 struct hook *hk; 1179 int ret, forced_closure = 0; 1180 1181 /* If a non-idempotent request is sent on a persisted connection, 1182 * then it is impossible to distinguish between a server failure 1183 * and a connection timeout if an EOF/RST is received. So don't 1184 * do that. */ 1185 if (!req->flags[NE_REQFLAG_IDEMPOTENT] && req->session->persisted 1186 && !req->session->flags[NE_SESSFLAG_CONNAUTH]) { 1187 NE_DEBUG(NE_DBG_HTTP, "req: Closing connection for non-idempotent " 1188 "request.\n"); 1189 ne_close_connection(req->session); 1190 } 1191 1192 /* Build the request string, and send it */ 1193 data = build_request(req); 1194 DEBUG_DUMP_REQUEST(data->data); 1195 ret = send_request(req, data); 1196 /* Retry this once after a persistent connection timeout. */ 1197 if (ret == NE_RETRY) { 1198 NE_DEBUG(NE_DBG_HTTP, "Persistent connection timed out, retrying.\n"); 1199 ret = send_request(req, data); 1200 } 1201 ne_buffer_destroy(data); 1202 if (ret != NE_OK) return ret == NE_RETRY ? NE_ERROR : ret; 1203 1204 /* Determine whether server claims HTTP/1.1 compliance. */ 1205 req->session->is_http11 = (st->major_version == 1 && 1206 st->minor_version > 0) || st->major_version > 1; 1207 1208 /* Persistent connections supported implicitly in HTTP/1.1 */ 1209 if (req->session->is_http11) req->can_persist = 1; 1210 1211 ne_set_error(req->session, "%d %s", st->code, st->reason_phrase); 1212 1213 /* Empty the response header hash, in case this request was 1214 * retried: */ 1215 free_response_headers(req); 1216 1217 /* Read the headers */ 1218 ret = read_response_headers(req); 1219 if (ret) return ret; 1220 1221 /* check the Connection header */ 1222 value = get_response_header_hv(req, HH_HV_CONNECTION, "connection"); 1223 if (value) { 1224 char *vcopy = ne_strdup(value), *ptr = vcopy; 1225 1226 do { 1227 char *token = ne_shave(ne_token(&ptr, ','), " \t"); 1228 unsigned int hash = hash_and_lower(token); 1229 1230 if (strcmp(token, "close") == 0) { 1231 req->can_persist = 0; 1232 forced_closure = 1; 1233 } else if (strcmp(token, "keep-alive") == 0) { 1234 req->can_persist = 1; 1235 } else if (!req->session->is_http11 1236 && strcmp(token, "connection")) { 1237 /* Strip the header per 2616��14.10, last para. Avoid 1238 * danger from "Connection: connection". */ 1239 remove_response_header(req, token, hash); 1240 } 1241 } while (ptr); 1242 1243 ne_free(vcopy); 1244 } 1245 1246 /* Support "Proxy-Connection: keep-alive" for compatibility with 1247 * some HTTP/1.0 proxies; it is risky to do this, because an 1248 * intermediary proxy may not support this HTTP/1.0 extension, but 1249 * will not strip the header either. Persistent connection 1250 * support is enabled based on the presence of this header if: 1251 * a) it is *necessary* to do so due to the use of a connection-auth 1252 * scheme, and 1253 * b) connection closure was not forced via "Connection: close". */ 1254 if (req->session->nexthop->proxy == PROXY_HTTP && !req->session->is_http11 1255 && !forced_closure && req->session->flags[NE_SESSFLAG_CONNAUTH]) { 1256 value = get_response_header_hv(req, HH_HV_PROXY_CONNECTION, 1257 "proxy-connection"); 1258 if (value && ne_strcasecmp(value, "keep-alive") == 0) { 1259 NE_DEBUG(NE_DBG_HTTP, "req: Using persistent connection " 1260 "for HTTP/1.0 proxy requiring conn-auth hack.\n"); 1261 req->can_persist = 1; 1262 } 1263 } 1264 1265 /* Decide which method determines the response message-length per 1266 * 2616��4.4 (multipart/byteranges is not supported): */ 1267 1268#ifdef NE_HAVE_SSL 1269 /* Special case for CONNECT handling: the response has no body, 1270 * and the connection can persist. */ 1271 if (req->session->in_connect && st->klass == 2) { 1272 req->resp.mode = R_NO_BODY; 1273 req->can_persist = 1; 1274 } else 1275#endif 1276 /* HEAD requests and 204, 304 responses have no response body, 1277 * regardless of what headers are present. */ 1278 if (req->method_is_head || st->code == 204 || st->code == 304) { 1279 req->resp.mode = R_NO_BODY; 1280 } 1281 /* Broken intermediaries exist which use "transfer-encoding: identity" 1282 * to mean "no transfer-coding". So that case must be ignored. */ 1283 else if ((value = get_response_header_hv(req, HH_HV_TRANSFER_ENCODING, 1284 "transfer-encoding")) != NULL 1285 && ne_strcasecmp(value, "identity") != 0) { 1286 /* Otherwise, fail iff an unknown transfer-coding is used. */ 1287 if (ne_strcasecmp(value, "chunked") == 0) { 1288 req->resp.mode = R_CHUNKED; 1289 req->resp.body.chunk.remain = 0; 1290 } 1291 else { 1292 return aborted(req, _("Unknown transfer-coding in response"), 0); 1293 } 1294 } 1295 else if ((value = get_response_header_hv(req, HH_HV_CONTENT_LENGTH, 1296 "content-length")) != NULL) { 1297 char *endptr = NULL; 1298 ne_off_t len = ne_strtoff(value, &endptr, 10); 1299 1300 if (*value && len != NE_OFFT_MAX && len >= 0 && endptr && *endptr == '\0') { 1301 req->resp.mode = R_CLENGTH; 1302 req->resp.body.clen.total = req->resp.body.clen.remain = len; 1303 } else { 1304 /* fail for an invalid content-length header. */ 1305 return aborted(req, _("Invalid Content-Length in response"), 0); 1306 } 1307 } else { 1308 req->resp.mode = R_TILLEOF; /* otherwise: read-till-eof mode */ 1309 } 1310 1311 NE_DEBUG(NE_DBG_HTTP, "Running post_headers hooks\n"); 1312 for (hk = req->session->post_headers_hooks; hk != NULL; hk = hk->next) { 1313 ne_post_headers_fn fn = (ne_post_headers_fn)hk->fn; 1314 fn(req, hk->userdata, &req->status); 1315 } 1316 1317 /* Prepare for reading the response entity-body. Call each of the 1318 * body readers and ask them whether they want to accept this 1319 * response or not. */ 1320 for (rdr = req->body_readers; rdr != NULL; rdr=rdr->next) { 1321 rdr->use = rdr->accept_response(rdr->userdata, req, st); 1322 } 1323 1324 req->session->status.sr.progress = 0; 1325 req->session->status.sr.total = 1326 req->resp.mode == R_CLENGTH ? req->resp.body.clen.total : -1; 1327 notify_status(req->session, ne_status_recving); 1328 1329 return NE_OK; 1330} 1331 1332int ne_end_request(ne_request *req) 1333{ 1334 struct hook *hk; 1335 int ret; 1336 1337 /* Read headers in chunked trailers */ 1338 if (req->resp.mode == R_CHUNKED) { 1339 ret = read_response_headers(req); 1340 if (ret) return ret; 1341 } else { 1342 ret = NE_OK; 1343 } 1344 1345 NE_DEBUG(NE_DBG_HTTP, "Running post_send hooks\n"); 1346 for (hk = req->session->post_send_hooks; 1347 ret == NE_OK && hk != NULL; hk = hk->next) { 1348 ne_post_send_fn fn = (ne_post_send_fn)hk->fn; 1349 ret = fn(req, hk->userdata, &req->status); 1350 } 1351 1352 /* Close the connection if persistent connections are disabled or 1353 * not supported by the server. */ 1354 if (!req->session->flags[NE_SESSFLAG_PERSIST] || !req->can_persist) 1355 ne_close_connection(req->session); 1356 else 1357 req->session->persisted = 1; 1358 1359 return ret; 1360} 1361 1362int ne_read_response_to_fd(ne_request *req, int fd) 1363{ 1364 ssize_t len; 1365 1366 1367 while ((len = ne_read_response_block(req, req->respbuf, 1368 sizeof req->respbuf)) > 0) { 1369 const char *block = req->respbuf; 1370 1371 do { 1372 //next 3 rows add by alan 1373 if(exit_loop == 1){ 1374 return NE_WEBDAV_QUIT; 1375 } 1376 ssize_t ret = write(fd, block, len); 1377 if (ret == -1 && errno == EINTR) { 1378 continue; 1379 } else if (ret < 0) { 1380 char err[200]; 1381 ne_strerror(errno, err, sizeof err); 1382 ne_set_error(ne_get_session(req), 1383 _("Could not write to file: %s"), err); 1384 return NE_ERROR; 1385 } else { 1386 len -= ret; 1387 block += ret; 1388 } 1389 } while (len > 0); 1390 } 1391 1392 return len == 0 ? NE_OK : NE_ERROR; 1393} 1394 1395int ne_discard_response(ne_request *req) 1396{ 1397 ssize_t len; 1398 1399 do { 1400 len = ne_read_response_block(req, req->respbuf, sizeof req->respbuf); 1401 } while (len > 0); 1402 1403 return len == 0 ? NE_OK : NE_ERROR; 1404} 1405 1406int ne_request_dispatch(ne_request *req) 1407{ 1408 int ret; 1409 1410 do { 1411 1412 ret = ne_begin_request(req); 1413 if (ret == NE_OK) ret = ne_discard_response(req); 1414 if (ret == NE_OK) ret = ne_end_request(req); 1415 } while (ret == NE_RETRY); 1416 1417 NE_DEBUG(NE_DBG_HTTP | NE_DBG_FLUSH, 1418 "Request ends, status %d class %dxx, error line:\n%s\n", 1419 req->status.code, req->status.klass, req->session->error); 1420 1421 return ret; 1422} 1423 1424const ne_status *ne_get_status(const ne_request *req) 1425{ 1426 return &req->status; 1427} 1428 1429ne_session *ne_get_session(const ne_request *req) 1430{ 1431 return req->session; 1432} 1433 1434#ifdef NE_HAVE_SSL 1435/* Create a CONNECT tunnel through the proxy server. 1436 * Returns HTTP_* */ 1437static int proxy_tunnel(ne_session *sess) 1438{ 1439 /* Hack up an HTTP CONNECT request... */ 1440 ne_request *req; 1441 int ret = NE_OK; 1442 char ruri[200]; 1443 1444 /* Can't use server.hostport here; Request-URI must include `:port' */ 1445 ne_snprintf(ruri, sizeof ruri, "%s:%u", sess->server.hostname, 1446 sess->server.port); 1447 req = ne_request_create(sess, "CONNECT", ruri); 1448 1449 sess->in_connect = 1; 1450 ret = ne_request_dispatch(req); 1451 sess->in_connect = 0; 1452 1453 sess->persisted = 0; /* don't treat this is a persistent connection. */ 1454 1455 if (ret != NE_OK || !sess->connected || req->status.klass != 2) { 1456 char *err = ne_strdup(sess->error); 1457 ne_set_error(sess, _("Could not create SSL connection " 1458 "through proxy server: %s"), err); 1459 ne_free(err); 1460 if (ret == NE_OK) ret = NE_ERROR; 1461 } 1462 1463 ne_request_destroy(req); 1464 return ret; 1465} 1466#endif 1467 1468/* Return the first resolved address for the given host. */ 1469static const ne_inet_addr *resolve_first(struct host_info *host) 1470{ 1471 return host->network ? host->network : ne_addr_first(host->address); 1472} 1473 1474/* Return the next resolved address for the given host or NULL if 1475 * there are no more addresses. */ 1476static const ne_inet_addr *resolve_next(struct host_info *host) 1477{ 1478 return host->network ? NULL : ne_addr_next(host->address); 1479} 1480 1481/* Make new TCP connection to server at 'host' of type 'name'. Note 1482 * that once a connection to a particular network address has 1483 * succeeded, that address will be used first for the next attempt to 1484 * connect. */ 1485static int do_connect(ne_session *sess, struct host_info *host) 1486{ 1487 int ret; 1488 1489 /* Resolve hostname if necessary. */ 1490 if (host->address == NULL && host->network == NULL) { 1491 ret = lookup_host(sess, host); 1492 if (ret) return ret; 1493 } 1494 1495 if ((sess->socket = ne_sock_create()) == NULL) { 1496 ne_set_error(sess, _("Could not create socket")); 1497 return NE_ERROR; 1498 } 1499 1500 if (sess->cotimeout) 1501 ne_sock_connect_timeout(sess->socket, sess->cotimeout); 1502 1503 if (sess->local_addr) 1504 ne_sock_prebind(sess->socket, sess->local_addr, 0); 1505 1506 if (host->current == NULL) 1507 host->current = resolve_first(host); 1508 1509 sess->status.ci.hostname = host->hostname; 1510 1511 do { 1512 sess->status.ci.address = host->current; 1513 notify_status(sess, ne_status_connecting); 1514#ifdef NE_DEBUGGING 1515 if (ne_debug_mask & NE_DBG_HTTP) { 1516 char buf[150]; 1517 NE_DEBUG(NE_DBG_HTTP, "req: Connecting to %s:%u\n", 1518 ne_iaddr_print(host->current, buf, sizeof buf), 1519 host->port); 1520 } 1521#endif 1522 ret = ne_sock_connect(sess->socket, host->current, host->port); 1523 } while (ret && /* try the next address... */ 1524 (host->current = resolve_next(host)) != NULL); 1525 1526 if (ret) { 1527 const char *msg; 1528 1529 if (host->proxy == PROXY_NONE) 1530 msg = _("Could not connect to server"); 1531 else 1532 msg = _("Could not connect to proxy server"); 1533 1534 ne_set_error(sess, "%s: %s", msg, ne_sock_error(sess->socket)); 1535 ne_sock_close(sess->socket); 1536 return ret == NE_SOCK_TIMEOUT ? NE_TIMEOUT : NE_CONNECT; 1537 } 1538 1539 if (sess->rdtimeout) 1540 ne_sock_read_timeout(sess->socket, sess->rdtimeout); 1541 1542 notify_status(sess, ne_status_connected); 1543 sess->nexthop = host; 1544 1545 sess->connected = 1; 1546 /* clear persistent connection flag. */ 1547 sess->persisted = 0; 1548 return NE_OK; 1549} 1550 1551/* For a SOCKSv4 proxy only, the IP address of the origin server (in 1552 * addition to the proxy) must be known, and must be an IPv4 address. 1553 * Returns NE_*; connection closed and error string set on error. */ 1554static int socks_origin_lookup(ne_session *sess) 1555{ 1556 const ne_inet_addr *ia; 1557 int ret; 1558 1559 ret = lookup_host(sess, &sess->server); 1560 if (ret) { 1561 /* lookup_host already set the error string. */ 1562 ne_close_connection(sess); 1563 return ret; 1564 } 1565 1566 /* Find the first IPv4 address available for the server. */ 1567 for (ia = ne_addr_first(sess->server.address); 1568 ia && ne_iaddr_typeof(ia) == ne_iaddr_ipv6; 1569 ia = ne_addr_next(sess->server.address)) { 1570 /* noop */ 1571 } 1572 1573 /* ... if any */ 1574 if (ia == NULL) { 1575 ne_set_error(sess, _("Could not find IPv4 address of " 1576 "hostname %s for SOCKS v4 proxy"), 1577 sess->server.hostname); 1578 ne_close_connection(sess); 1579 return NE_LOOKUP; 1580 } 1581 1582 sess->server.current = ia; 1583 1584 return ret; 1585} 1586 1587static int open_connection(ne_session *sess) 1588{ 1589 int ret; 1590 1591 if (sess->connected) return NE_OK; 1592 1593 if (!sess->proxies) { 1594 ret = do_connect(sess, &sess->server); 1595 if (ret) { 1596 sess->nexthop = NULL; 1597 return ret; 1598 } 1599 } 1600 else { 1601 struct host_info *hi; 1602 1603 /* Attempt to re-use proxy to avoid iterating through 1604 * unnecessarily. */ 1605 if (sess->prev_proxy) 1606 ret = do_connect(sess, sess->prev_proxy); 1607 else 1608 ret = NE_ERROR; 1609 1610 /* Otherwise, try everything - but omitting prev_proxy if that 1611 * has already been tried. */ 1612 for (hi = sess->proxies; hi && ret; hi = hi->next) { 1613 if (hi != sess->prev_proxy) 1614 ret = do_connect(sess, hi); 1615 } 1616 1617 if (ret == NE_OK && sess->nexthop->proxy == PROXY_SOCKS) { 1618 /* Special-case for SOCKS v4 proxies, which require the 1619 * client to resolve the origin server IP address. */ 1620 if (sess->socks_ver == NE_SOCK_SOCKSV4) { 1621 ret = socks_origin_lookup(sess); 1622 } 1623 1624 if (ret == NE_OK) { 1625 /* Perform the SOCKS handshake, instructing the proxy 1626 * to set up the connection to the origin server. */ 1627 ret = ne_sock_proxy(sess->socket, sess->socks_ver, 1628 sess->server.current, 1629 sess->server.hostname, sess->server.port, 1630 sess->socks_user, sess->socks_password); 1631 if (ret) { 1632 ne_set_error(sess, 1633 _("Could not establish connection from " 1634 "SOCKS proxy (%s:%u): %s"), 1635 sess->nexthop->hostname, 1636 sess->nexthop->port, 1637 ne_sock_error(sess->socket)); 1638 ne_close_connection(sess); 1639 ret = NE_ERROR; 1640 } 1641 } 1642 } 1643 1644 if (ret != NE_OK) { 1645 sess->nexthop = NULL; 1646 sess->prev_proxy = NULL; 1647 return ret; 1648 } 1649 1650 /* Success - make this proxy stick. */ 1651 sess->prev_proxy = hi; 1652 } 1653 1654#ifdef NE_HAVE_SSL 1655 /* Negotiate SSL layer if required. */ 1656 if (sess->use_ssl && !sess->in_connect) { 1657 /* Set up CONNECT tunnel if using an HTTP proxy. */ 1658 if (sess->nexthop->proxy == PROXY_HTTP) 1659 ret = proxy_tunnel(sess); 1660 1661 if (ret == NE_OK) { 1662 ret = ne__negotiate_ssl(sess); 1663 if (ret != NE_OK) 1664 ne_close_connection(sess); 1665 } 1666 } 1667#endif 1668 1669 return ret; 1670} 1671