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