1 /*
2    HTTP request/response handling
3    Copyright (C) 1999-2004, 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 #include <sys/stat.h>
30 #ifdef __EMX__
31 #include <sys/select.h>
32 #endif
33 
34 #ifdef HAVE_LIMITS_H
35 #include <limits.h> /* for UINT_MAX etc */
36 #endif
37 
38 #include <ctype.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #ifdef HAVE_STRING_H
42 #include <string.h>
43 #endif
44 #ifdef HAVE_STRINGS_H
45 #include <strings.h>
46 #endif
47 #ifdef HAVE_STDLIB_H
48 #include <stdlib.h>
49 #endif
50 #ifdef HAVE_UNISTD_H
51 #include <unistd.h>
52 #endif
53 
54 #include "ne_i18n.h"
55 
56 #include "ne_alloc.h"
57 #include "ne_request.h"
58 #include "ne_string.h" /* for ne_buffer */
59 #include "ne_utils.h"
60 #include "ne_socket.h"
61 #include "ne_uri.h"
62 
63 #include "ne_private.h"
64 
65 #define HTTP_EXPECT_TIMEOUT 15
66 /* 100-continue only used if size > HTTP_EXPECT_MINSIZ */
67 #define HTTP_EXPECT_MINSIZE 1024
68 
69 /* with thanks to Jim Blandy; this macro simplified loads of code. */
70 #define HTTP_ERR(x) do { int _ret = (x); if (_ret != NE_OK) return _ret; } while (0)
71 
72 #define SOCK_ERR(req, op, msg) do { ssize_t sret = (op); \
73 if (sret < 0) return aborted(req, msg, sret); } while (0)
74 
75 /* This is called with each of the headers in the response */
76 struct header_handler {
77     char *name;
78     ne_header_handler handler;
79     void *userdata;
80     struct header_handler *next;
81 };
82 
83 /* TODO: could unify these all into a generic callback list */
84 
85 struct body_reader {
86     ne_block_reader handler;
87     ne_accept_response accept_response;
88     unsigned int use:1;
89     void *userdata;
90     struct body_reader *next;
91 };
92 
93 struct ne_request_s {
94     char *method, *uri; /* method and Request-URI */
95 
96     ne_buffer *headers; /* request headers */
97 
98     /* Request body. */
99     ne_provide_body body_cb;
100     void *body_ud;
101 
102     /* Comes from either an fd or a buffer. */
103     union {
104 	int fd;
105 	struct {
106 	    const char *buffer, *pnt;
107 	    size_t left;
108 	} buf;
109     } body;
110 
111     size_t body_size, body_progress;
112 
113     /* temporary store for response lines. */
114     char respbuf[BUFSIZ];
115 
116     /**** Response ***/
117 
118     /* The transfer encoding types */
119     struct ne_response {
120 	int length;            /* Response entity-body content-length */
121 	size_t left;              /* Bytes left to read */
122 	size_t chunk_left;        /* Bytes of chunk left to read */
123 	size_t total;             /* total bytes read so far. */
124 	/* how the message length is detemined: */
125 	enum {
126 	    R_TILLEOF = 0, /* read till eof */
127 	    R_NO_BODY, /* implicitly no body (HEAD, 204, 205, 304) */
128 	    R_CHUNKED, /* using chunked transfer-encoding */
129 	    R_CLENGTH  /* using given content-length */
130 	} mode;
131     } resp;
132 
133     /* List of callbacks which are passed response headers */
134     struct header_handler *header_catchers;
135 
136     struct hook *private;
137 
138     /* We store response header handlers in a hash table.  The hash is
139      * derived from the header name in lower case. */
140 
141     /* FIXME: this comment is WAY out of date, and no longer in any
142      * way true. */
143 
144     /* 53 is magic, of course.  For a standard ne_get() (with
145      * redirects), 9 header handlers are defined.  Two of these are
146      * for Content-Length (which is a bug, and should be fixed
147      * really).  Ignoring that hash clash, the 8 *different* handlers
148      * all hash uniquely into the hash table of size 53.  */
149 #define HH_HASHSIZE 53
150 
151     struct header_handler *header_handlers[HH_HASHSIZE];
152     /* List of callbacks which are passed response body blocks */
153     struct body_reader *body_readers;
154 
155     /*** Miscellaneous ***/
156     unsigned int method_is_head:1;
157     unsigned int use_expect100:1;
158     unsigned int can_persist:1;
159 
160     ne_session *session;
161     ne_status status;
162 };
163 
164 static int open_connection(ne_request *req);
165 
166 /* The iterative step used to produce the hash value.  This is DJB's
167  * magic "*33" hash function.  Ralf Engelschall has done some amazing
168  * statistical analysis to show that *33 really is a good hash
169  * function: check the new-httpd list archives, or his 'str' library
170  * source code, for the details.
171  *
172  * TODO: due to limited range of characters used in header names,
173  * could maybe get a better hash function to use? */
174 
175 #define HH_ITERATE(hash, ch) (((hash)*33 + (ch)) % HH_HASHSIZE);
176 
177 /* Returns hash value for header 'name', converting it to lower-case
178  * in-place. */
hash_and_lower(char * name)179 static inline unsigned int hash_and_lower(char *name)
180 {
181     char *pnt;
182     unsigned int hash = 0;
183 
184     for (pnt = name; *pnt != '\0'; pnt++) {
185 	*pnt = tolower(*pnt);
186 	hash = HH_ITERATE(hash,*pnt);
187     }
188 
189     return hash;
190 }
191 
192 /* Abort a request due to an non-recoverable HTTP protocol error,
193  * whilst doing 'doing'.  'code', if non-zero, is the socket error
194  * code, NE_SOCK_*, or if zero, is ignored. */
aborted(ne_request * req,const char * doing,ssize_t code)195 static int aborted(ne_request *req, const char *doing, ssize_t code)
196 {
197     ne_session *sess = req->session;
198     int ret = NE_ERROR;
199 
200     NE_DEBUG(NE_DBG_HTTP, "Aborted request (%" NE_FMT_SSIZE_T "): %s\n",
201 	     code, doing);
202 
203     switch(code) {
204     case NE_SOCK_CLOSED:
205 	if (sess->use_proxy) {
206 	    ne_set_error(sess, _("%s: connection was closed by proxy server."),
207 			 doing);
208 	} else {
209 	    ne_set_error(sess, _("%s: connection was closed by server."),
210 			 doing);
211 	}
212 	break;
213     case NE_SOCK_TIMEOUT:
214 	ne_set_error(sess, _("%s: connection timed out."), doing);
215 	ret = NE_TIMEOUT;
216 	break;
217     case NE_SOCK_ERROR:
218     case NE_SOCK_RESET:
219     case NE_SOCK_TRUNC:
220         ne_set_error(sess, "%s: %s", doing, ne_sock_error(sess->socket));
221         break;
222     case 0:
223 	ne_set_error(sess, "%s", doing);
224 	break;
225     }
226 
227     ne_close_connection(sess);
228     return ret;
229 }
230 
notify_status(ne_session * sess,ne_conn_status status,const char * info)231 static void notify_status(ne_session *sess, ne_conn_status status,
232 			  const char *info)
233 {
234     if (sess->notify_cb) {
235 	sess->notify_cb(sess->notify_ud, status, info);
236     }
237 }
238 
ne_duplicate_header(void * userdata,const char * value)239 void ne_duplicate_header(void *userdata, const char *value)
240 {
241     char **location = userdata;
242     *location = ne_strdup(value);
243 }
244 
ne_handle_numeric_header(void * userdata,const char * value)245 void ne_handle_numeric_header(void *userdata, const char *value)
246 {
247     int *location = userdata;
248     *location = atoi(value);
249 }
250 
get_private(const struct hook * hk,const char * id)251 static void *get_private(const struct hook *hk, const char *id)
252 {
253     for (; hk != NULL; hk = hk->next)
254 	if (strcmp(hk->id, id) == 0)
255 	    return hk->userdata;
256     return NULL;
257 }
258 
ne_get_request_private(ne_request * req,const char * id)259 void *ne_get_request_private(ne_request *req, const char *id)
260 {
261     return get_private(req->private, id);
262 }
263 
ne_get_session_private(ne_session * sess,const char * id)264 void *ne_get_session_private(ne_session *sess, const char *id)
265 {
266     return get_private(sess->private, id);
267 }
268 
269 typedef void (*void_fn)(void);
270 
271 #define ADD_HOOK(hooks, fn, ud) add_hook(&(hooks), NULL, (void_fn)(fn), (ud))
272 
add_hook(struct hook ** hooks,const char * id,void_fn fn,void * ud)273 static void add_hook(struct hook **hooks, const char *id, void_fn fn, void *ud)
274 {
275     struct hook *hk = ne_malloc(sizeof (struct hook)), *pos;
276 
277     if (*hooks != NULL) {
278 	for (pos = *hooks; pos->next != NULL; pos = pos->next)
279 	    /* nullop */;
280 	pos->next = hk;
281     } else {
282 	*hooks = hk;
283     }
284 
285     hk->id = id;
286     hk->fn = fn;
287     hk->userdata = ud;
288     hk->next = NULL;
289 }
290 
ne_hook_create_request(ne_session * sess,ne_create_request_fn fn,void * userdata)291 void ne_hook_create_request(ne_session *sess,
292 			    ne_create_request_fn fn, void *userdata)
293 {
294     ADD_HOOK(sess->create_req_hooks, fn, userdata);
295 }
296 
ne_hook_pre_send(ne_session * sess,ne_pre_send_fn fn,void * userdata)297 void ne_hook_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata)
298 {
299     ADD_HOOK(sess->pre_send_hooks, fn, userdata);
300 }
301 
ne_hook_post_send(ne_session * sess,ne_post_send_fn fn,void * userdata)302 void ne_hook_post_send(ne_session *sess, ne_post_send_fn fn, void *userdata)
303 {
304     ADD_HOOK(sess->post_send_hooks, fn, userdata);
305 }
306 
ne_hook_destroy_request(ne_session * sess,ne_destroy_req_fn fn,void * userdata)307 void ne_hook_destroy_request(ne_session *sess,
308 			     ne_destroy_req_fn fn, void *userdata)
309 {
310     ADD_HOOK(sess->destroy_req_hooks, fn, userdata);
311 }
312 
ne_hook_destroy_session(ne_session * sess,ne_destroy_sess_fn fn,void * userdata)313 void ne_hook_destroy_session(ne_session *sess,
314 			     ne_destroy_sess_fn fn, void *userdata)
315 {
316     ADD_HOOK(sess->destroy_sess_hooks, fn, userdata);
317 }
318 
319 /* 0.24.x hack to fix ne_compress layer problems */
ne_kill_pre_send(ne_session * sess,ne_pre_send_fn fn,void * userdata)320 void ne_kill_pre_send(ne_session *sess, ne_pre_send_fn fn, void *userdata)
321 {
322     struct hook **last, *hk;
323 
324     last = &sess->pre_send_hooks;
325     hk = *last;
326 
327     while (hk) {
328         if (hk->fn == (void_fn)fn && hk->userdata == userdata) {
329             *last = hk->next;
330             ne_free(hk);
331             return;
332         }
333         last = &hk->next;
334         hk = *last;
335     }
336 }
337 
ne_set_session_private(ne_session * sess,const char * id,void * userdata)338 void ne_set_session_private(ne_session *sess, const char *id, void *userdata)
339 {
340     add_hook(&sess->private, id, NULL, userdata);
341 }
342 
ne_set_request_private(ne_request * req,const char * id,void * userdata)343 void ne_set_request_private(ne_request *req, const char *id, void *userdata)
344 {
345     add_hook(&req->private, id, NULL, userdata);
346 }
347 
body_string_send(void * userdata,char * buffer,size_t count)348 static ssize_t body_string_send(void *userdata, char *buffer, size_t count)
349 {
350     ne_request *req = userdata;
351 
352     if (count == 0) {
353 	req->body.buf.left = req->body_size;
354 	req->body.buf.pnt = req->body.buf.buffer;
355     } else {
356 	/* if body_left == 0 we fall through and return 0. */
357 	if (req->body.buf.left < count)
358 	    count = req->body.buf.left;
359 
360 	memcpy(buffer, req->body.buf.pnt, count);
361 	req->body.buf.pnt += count;
362 	req->body.buf.left -= count;
363     }
364 
365     return count;
366 }
367 
body_fd_send(void * userdata,char * buffer,size_t count)368 static ssize_t body_fd_send(void *userdata, char *buffer, size_t count)
369 {
370     ne_request *req = userdata;
371 
372     if (count) {
373 	return read(req->body.fd, buffer, count);
374     } else {
375 	/* rewind since we may have to send it again */
376 	return lseek(req->body.fd, SEEK_SET, 0);
377     }
378 }
379 
380 /* Pulls the request body from the source and pushes it to the given
381  * callback.  Returns 0 on success, or NE_* code */
ne_pull_request_body(ne_request * req,ne_push_fn fn,void * ud)382 int ne_pull_request_body(ne_request *req, ne_push_fn fn, void *ud)
383 {
384     int ret = 0;
385     char buffer[BUFSIZ];
386     ssize_t bytes;
387 
388     /* tell the source to start again from the beginning. */
389     (void) req->body_cb(req->body_ud, NULL, 0);
390 
391     /* TODO: should this attempt to pull exactly the number of bytes
392      * they specified were in the body? Currently it just pulls until
393      * they return zero. That makes it possible to extend this to do
394      * chunked request bodies (i.e. indefinitely long, no C-L), so
395      * this is probably a better long-term interface. */
396     while ((bytes = req->body_cb(req->body_ud, buffer, sizeof buffer)) > 0) {
397 	ret = fn(ud, buffer, bytes);
398 	if (ret < 0)
399 	    break;
400 	NE_DEBUG(NE_DBG_HTTPBODY,
401 		 "Body block (%" NE_FMT_SSIZE_T " bytes):\n[%.*s]\n",
402 		 bytes, (int)bytes, buffer);
403     }
404 
405     if (bytes < 0) {
406 	ne_set_error(req->session, _("Error reading request body."));
407 	ret = NE_ERROR;
408     }
409 
410     return ret;
411 }
412 
send_with_progress(void * userdata,const char * data,size_t n)413 static int send_with_progress(void *userdata, const char *data, size_t n)
414 {
415     ne_request *req = userdata;
416     int ret;
417 
418     ret = ne_sock_fullwrite(req->session->socket, data, n);
419     if (ret == 0) {
420 	req->body_progress += n;
421 	req->session->progress_cb(req->session->progress_ud,
422 				  req->body_progress, req->body_size);
423     }
424 
425     return ret;
426 }
427 
428 /* Sends the request body down the socket.
429  * Returns 0 on success, or NE_* code */
send_request_body(ne_request * req)430 static int send_request_body(ne_request *req)
431 {
432     int ret;
433     NE_DEBUG(NE_DBG_HTTP, "Sending request body...\n");
434     if (req->session->progress_cb) {
435 	/* with progress callbacks. */
436 	req->body_progress = 0;
437 	ret = ne_pull_request_body(req, send_with_progress, req);
438     } else {
439 	/* without progress callbacks. */
440 	ret = ne_pull_request_body(req, (ne_push_fn)ne_sock_fullwrite,
441 				   req->session->socket);
442     }
443 
444     NE_DEBUG(NE_DBG_HTTP, "Request body sent: %s.\n", ret?"failed":"okay");
445     return ret;
446 }
447 
448 /* Lob the User-Agent, connection and host headers in to the request
449  * headers */
add_fixed_headers(ne_request * req)450 static void add_fixed_headers(ne_request *req)
451 {
452     if (req->session->user_agent) {
453         ne_buffer_zappend(req->headers, req->session->user_agent);
454     }
455 
456     /* Send Connection: Keep-Alive to pre-1.1 origin servers to try
457      * harder to get a persistent connection, except if using a proxy
458      * as per 2068 sec 19.7.1.  Always add TE: trailers since those
459      * are understood. */
460     if (!req->session->is_http11 && !req->session->use_proxy) {
461 	ne_buffer_zappend(req->headers,
462                           "Keep-Alive: " EOL
463                           "Connection: TE, Keep-Alive" EOL
464                           "TE: trailers" EOL);
465     } else {
466 	ne_buffer_zappend(req->headers,
467                           "Connection: TE" EOL
468                           "TE: trailers" EOL);
469     }
470 
471 }
472 
ne_accept_always(void * userdata,ne_request * req,const ne_status * st)473 int ne_accept_always(void *userdata, ne_request *req, const ne_status *st)
474 {
475     return 1;
476 }
477 
ne_accept_2xx(void * userdata,ne_request * req,const ne_status * st)478 int ne_accept_2xx(void *userdata, ne_request *req, const ne_status *st)
479 {
480     return (st->klass == 2);
481 }
482 
483 /* Handler for the "Transfer-Encoding" response header: treat *any*
484  * such header as implying a chunked response, per the "Protocol
485  * Compliance" statement in the manual. */
te_hdr_handler(void * userdata,const char * value)486 static void te_hdr_handler(void *userdata, const char *value)
487 {
488     struct ne_response *resp = userdata;
489 
490     resp->mode = R_CHUNKED;
491 }
492 
493 /* Handler for the "Connection" response header */
connection_hdr_handler(void * userdata,const char * value)494 static void connection_hdr_handler(void *userdata, const char *value)
495 {
496     ne_request *req = userdata;
497     if (strcasecmp(value, "close") == 0) {
498 	req->can_persist = 0;
499     } else if (strcasecmp(value, "Keep-Alive") == 0) {
500 	req->can_persist = 1;
501     }
502 }
503 
clength_hdr_handler(void * userdata,const char * value)504 static void clength_hdr_handler(void *userdata, const char *value)
505 {
506     struct ne_response *resp = userdata;
507     size_t len = strtoul(value, NULL, 10);
508     if (len != ULONG_MAX && resp->mode == R_TILLEOF) {
509 	resp->mode = R_CLENGTH;
510 	resp->length = len;
511     }
512 }
513 
ne_request_create(ne_session * sess,const char * method,const char * path)514 ne_request *ne_request_create(ne_session *sess,
515 			      const char *method, const char *path)
516 {
517     ne_request *req = ne_calloc(sizeof *req);
518 
519     NE_DEBUG(NE_DBG_HTTP, "Creating request...\n");
520 
521     req->session = sess;
522     req->headers = ne_buffer_create();
523 
524     /* Add in the fixed headers */
525     add_fixed_headers(req);
526 
527     /* Set the standard stuff */
528     req->method = ne_strdup(method);
529     req->method_is_head = (strcmp(method, "HEAD") == 0);
530 
531     /* Add in handlers for all the standard HTTP headers. */
532     ne_add_response_header_handler(req, "Content-Length",
533 				   clength_hdr_handler, &req->resp);
534     ne_add_response_header_handler(req, "Transfer-Encoding",
535 				   te_hdr_handler, &req->resp);
536     ne_add_response_header_handler(req, "Connection",
537 				   connection_hdr_handler, req);
538 
539     /* Only use an absoluteURI here when absolutely necessary: some
540      * servers can't parse them. */
541     if (req->session->use_proxy && !req->session->use_ssl && path[0] == '/')
542 	req->uri = ne_concat(req->session->scheme, "://",
543 			     req->session->server.hostport, path, NULL);
544     else
545 	req->uri = ne_strdup(path);
546 
547     {
548 	struct hook *hk;
549 
550 	NE_DEBUG(NE_DBG_HTTP, "Running request create hooks.\n");
551 
552 	for (hk = sess->create_req_hooks; hk != NULL; hk = hk->next) {
553 	    ne_create_request_fn fn = (ne_create_request_fn)hk->fn;
554 	    fn(req, hk->userdata, method, req->uri);
555 	}
556     }
557 
558     NE_DEBUG(NE_DBG_HTTP, "Request created.\n");
559 
560     return req;
561 }
562 
set_body_size(ne_request * req,size_t size)563 static void set_body_size(ne_request *req, size_t size)
564 {
565     req->body_size = size;
566     ne_print_request_header(req, "Content-Length", "%" NE_FMT_SIZE_T, size);
567 }
568 
ne_set_request_body_buffer(ne_request * req,const char * buffer,size_t size)569 void ne_set_request_body_buffer(ne_request *req, const char *buffer,
570 				size_t size)
571 {
572     req->body.buf.buffer = buffer;
573     req->body_cb = body_string_send;
574     req->body_ud = req;
575     set_body_size(req, size);
576 }
577 
ne_set_request_body_provider(ne_request * req,size_t bodysize,ne_provide_body provider,void * ud)578 void ne_set_request_body_provider(ne_request *req, size_t bodysize,
579 				  ne_provide_body provider, void *ud)
580 {
581     req->body_cb = provider;
582     req->body_ud = ud;
583     set_body_size(req, bodysize);
584 }
585 
ne_set_request_body_fd(ne_request * req,int fd)586 int ne_set_request_body_fd(ne_request *req, int fd)
587 {
588     struct stat bodyst;
589 
590     /* Get file length */
591     if (fstat(fd, &bodyst) < 0) {
592 	char err[200];
593 	ne_strerror(errno, err, sizeof err);
594 	ne_set_error(req->session, _("Could not determine file length: %s"),
595 		     err);
596 	NE_DEBUG(NE_DBG_HTTP, "Stat failed: %s\n", err);
597 	return -1;
598     }
599     req->body.fd = fd;
600     req->body_cb = body_fd_send;
601     req->body_ud = req;
602     set_body_size(req, bodyst.st_size);
603     return 0;
604 }
605 
ne_add_request_header(ne_request * req,const char * name,const char * value)606 void ne_add_request_header(ne_request *req, const char *name,
607 			   const char *value)
608 {
609     ne_buffer_concat(req->headers, name, ": ", value, EOL, NULL);
610 }
611 
ne_print_request_header(ne_request * req,const char * name,const char * format,...)612 void ne_print_request_header(ne_request *req, const char *name,
613 			     const char *format, ...)
614 {
615     va_list params;
616     char buf[BUFSIZ];
617 
618     va_start(params, format);
619     ne_vsnprintf(buf, sizeof buf, format, params);
620     va_end(params);
621 
622     ne_buffer_concat(req->headers, name, ": ", buf, EOL, NULL);
623 }
624 
625 void
ne_add_response_header_handler(ne_request * req,const char * name,ne_header_handler hdl,void * userdata)626 ne_add_response_header_handler(ne_request *req, const char *name,
627 			       ne_header_handler hdl, void *userdata)
628 {
629     struct header_handler *new = ne_calloc(sizeof *new);
630     unsigned int hash;
631     new->name = ne_strdup(name);
632     new->handler = hdl;
633     new->userdata = userdata;
634     hash = hash_and_lower(new->name);
635     new->next = req->header_handlers[hash];
636     req->header_handlers[hash] = new;
637 }
638 
ne_add_response_header_catcher(ne_request * req,ne_header_handler hdl,void * userdata)639 void ne_add_response_header_catcher(ne_request *req,
640 				    ne_header_handler hdl, void *userdata)
641 {
642     struct header_handler *new = ne_calloc(sizeof *new);
643     new->handler = hdl;
644     new->userdata = userdata;
645     new->next = req->header_catchers;
646     req->header_catchers = new;
647 }
648 
ne_add_response_body_reader(ne_request * req,ne_accept_response acpt,ne_block_reader rdr,void * userdata)649 void ne_add_response_body_reader(ne_request *req, ne_accept_response acpt,
650 				 ne_block_reader rdr, void *userdata)
651 {
652     struct body_reader *new = ne_malloc(sizeof *new);
653     new->accept_response = acpt;
654     new->handler = rdr;
655     new->userdata = userdata;
656     new->next = req->body_readers;
657     req->body_readers = new;
658 }
659 
ne_request_destroy(ne_request * req)660 void ne_request_destroy(ne_request *req)
661 {
662     struct body_reader *rdr, *next_rdr;
663     struct header_handler *hdlr, *next_hdlr;
664     struct hook *hk, *next_hk;
665     int n;
666 
667     ne_free(req->uri);
668     ne_free(req->method);
669 
670     for (rdr = req->body_readers; rdr != NULL; rdr = next_rdr) {
671 	next_rdr = rdr->next;
672 	ne_free(rdr);
673     }
674 
675     for (hdlr = req->header_catchers; hdlr != NULL; hdlr = next_hdlr) {
676 	next_hdlr = hdlr->next;
677 	ne_free(hdlr);
678     }
679 
680     for (n = 0; n < HH_HASHSIZE; n++) {
681 	for (hdlr = req->header_handlers[n]; hdlr != NULL;
682 	     hdlr = next_hdlr) {
683 	    next_hdlr = hdlr->next;
684 	    ne_free(hdlr->name);
685 	    ne_free(hdlr);
686 	}
687     }
688 
689     ne_buffer_destroy(req->headers);
690 
691     NE_DEBUG(NE_DBG_HTTP, "Running destroy hooks.\n");
692     for (hk = req->session->destroy_req_hooks; hk; hk = hk->next) {
693 	ne_destroy_req_fn fn = (ne_destroy_req_fn)hk->fn;
694 	fn(req, hk->userdata);
695     }
696 
697     for (hk = req->private; hk; hk = next_hk) {
698 	next_hk = hk->next;
699 	ne_free(hk);
700     }
701 
702     if (req->status.reason_phrase)
703 	ne_free(req->status.reason_phrase);
704 
705     NE_DEBUG(NE_DBG_HTTP, "Request ends.\n");
706     ne_free(req);
707 }
708 
709 
710 /* Reads a block of the response into buffer, which is of size buflen.
711  * Returns number of bytes read, 0 on end-of-response, or NE_* on error.
712  * TODO?: only make one actual read() call in here...
713  */
read_response_block(ne_request * req,struct ne_response * resp,char * buffer,size_t * buflen)714 static int read_response_block(ne_request *req, struct ne_response *resp,
715 			       char *buffer, size_t *buflen)
716 {
717     size_t willread;
718     ssize_t readlen;
719     ne_socket *sock = req->session->socket;
720     switch (resp->mode) {
721     case R_CHUNKED:
722 	/* We are doing a chunked transfer-encoding.
723 	 * It goes:  `SIZE CRLF CHUNK CRLF SIZE CRLF CHUNK CRLF ...'
724 	 * ended by a `CHUNK CRLF 0 CRLF', a 0-sized chunk.
725 	 * The slight complication is that we have to cope with
726 	 * partial reads of chunks.
727 	 * For this reason, resp.chunk_left contains the number of
728 	 * bytes left to read in the current chunk.
729 	 */
730 	if (resp->chunk_left == 0) {
731 	    unsigned long int chunk_len;
732 	    char *ptr;
733 	    /* We are at the start of a new chunk. */
734 	    NE_DEBUG(NE_DBG_HTTP, "New chunk.\n");
735 	    SOCK_ERR(req, ne_sock_readline(sock, buffer, *buflen),
736 		     _("Could not read chunk size"));
737 	    NE_DEBUG(NE_DBG_HTTP, "[Chunk Size] < %s", buffer);
738 	    chunk_len = strtoul(buffer, &ptr, 16);
739 	    /* limit chunk size to <= UINT_MAX, so it will probably
740 	     * fit in a size_t. */
741 	    if (ptr == buffer ||
742 		chunk_len == ULONG_MAX || chunk_len > UINT_MAX) {
743 		return aborted(req, _("Could not parse chunk size"), 0);
744 	    }
745 	    NE_DEBUG(NE_DBG_HTTP, "Got chunk size: %lu\n", chunk_len);
746 	    if (chunk_len == 0) {
747 		/* Zero-size chunk == end of response. */
748 		NE_DEBUG(NE_DBG_HTTP, "Zero-size chunk.\n");
749 		*buflen = 0;
750 		return NE_OK;
751 	    }
752 	    resp->chunk_left = chunk_len;
753 	}
754 	willread = resp->chunk_left;
755 	break;
756     case R_CLENGTH:
757 	willread = resp->left;
758 	break;
759     case R_TILLEOF:
760 	willread = *buflen;
761 	break;
762     case R_NO_BODY:
763     default:
764 	willread = 0;
765 	break;
766     }
767     if (willread > *buflen) willread = *buflen;
768     else if (willread == 0) {
769 	*buflen = 0;
770 	return 0;
771     }
772     NE_DEBUG(NE_DBG_HTTP,
773 	     "Reading %" NE_FMT_SIZE_T " bytes of response body.\n", willread);
774     readlen = ne_sock_read(sock, buffer, willread);
775 
776     /* EOF is only valid when response body is delimited by it.
777      * Strictly, an SSL truncation should not be treated as an EOF in
778      * any case, but SSL servers are just too buggy.  */
779     if (resp->mode == R_TILLEOF &&
780 	(readlen == NE_SOCK_CLOSED || readlen == NE_SOCK_TRUNC)) {
781 	NE_DEBUG(NE_DBG_HTTP, "Got EOF.\n");
782 	req->can_persist = 0;
783 	readlen = 0;
784     } else if (readlen < 0) {
785 	return aborted(req, _("Could not read response body"), readlen);
786     } else {
787 	NE_DEBUG(NE_DBG_HTTP, "Got %" NE_FMT_SSIZE_T " bytes.\n", readlen);
788     }
789     /* safe to cast: readlen guaranteed to be >= 0 above */
790     *buflen = (size_t)readlen;
791     NE_DEBUG(NE_DBG_HTTPBODY,
792 	     "Read block (%" NE_FMT_SSIZE_T " bytes):\n[%.*s]\n",
793 	     readlen, (int)readlen, buffer);
794     if (resp->mode == R_CHUNKED) {
795 	resp->chunk_left -= readlen;
796 	if (resp->chunk_left == 0) {
797 	    char crlfbuf[2];
798 	    /* If we've read a whole chunk, read a CRLF */
799 	    readlen = ne_sock_fullread(sock, crlfbuf, 2);
800             if (readlen < 0)
801                 return aborted(req, _("Could not read chunk delimiter"),
802                                readlen);
803             else if (crlfbuf[0] != '\r' || crlfbuf[1] != '\n')
804                 return aborted(req, _("Chunk delimiter was invalid"), 0);
805 	}
806     } else if (resp->mode == R_CLENGTH) {
807 	resp->left -= readlen;
808     }
809     return NE_OK;
810 }
811 
ne_read_response_block(ne_request * req,char * buffer,size_t buflen)812 ssize_t ne_read_response_block(ne_request *req, char *buffer, size_t buflen)
813 {
814     struct body_reader *rdr;
815     size_t readlen = buflen;
816 
817     if (read_response_block(req, &req->resp, buffer, &readlen))
818 	return -1;
819 
820     req->resp.total += readlen;
821 
822     if (req->session->progress_cb) {
823 	req->session->progress_cb(req->session->progress_ud, req->resp.total,
824 				  (req->resp.mode==R_CLENGTH)?req->resp.length:-1);
825     }
826 
827     /* TODO: call the readers when this fails too. */
828     for (rdr = req->body_readers; rdr!=NULL; rdr=rdr->next) {
829 	if (rdr->use) rdr->handler(rdr->userdata, buffer, readlen);
830     }
831 
832     return readlen;
833 }
834 
835 /* Build the request string, returning the buffer. */
build_request(ne_request * req)836 static ne_buffer *build_request(ne_request *req)
837 {
838     struct hook *hk;
839     ne_buffer *buf = ne_buffer_create();
840 
841     /* Add Request-Line and Host header: */
842     ne_buffer_concat(buf, req->method, " ", req->uri, " HTTP/1.1" EOL,
843 		     "Host: ", req->session->server.hostport, EOL, NULL);
844 
845     /* Add custom headers: */
846     ne_buffer_append(buf, req->headers->data, ne_buffer_size(req->headers));
847 
848 #define E100 "Expect: 100-continue" EOL
849     if (req->use_expect100)
850 	ne_buffer_append(buf, E100, strlen(E100));
851 
852     NE_DEBUG(NE_DBG_HTTP, "Running pre_send hooks\n");
853     for (hk = req->session->pre_send_hooks; hk!=NULL; hk = hk->next) {
854 	ne_pre_send_fn fn = (ne_pre_send_fn)hk->fn;
855 	fn(req, hk->userdata, buf);
856     }
857 
858     ne_buffer_append(buf, "\r\n", 2);
859     return buf;
860 }
861 
862 #ifdef NE_DEBUGGING
863 #define DEBUG_DUMP_REQUEST(x) dump_request(x)
864 
dump_request(const char * request)865 static void dump_request(const char *request)
866 {
867     if ((NE_DBG_HTTPPLAIN&ne_debug_mask) == NE_DBG_HTTPPLAIN) {
868 	/* Display everything mode */
869 	NE_DEBUG(NE_DBG_HTTP, "Sending request headers:\n%s", request);
870     } else {
871 	/* Blank out the Authorization paramaters */
872 	char *reqdebug = ne_strdup(request), *pnt = reqdebug;
873 	while ((pnt = strstr(pnt, "Authorization: ")) != NULL) {
874 	    for (pnt += 15; *pnt != '\r' && *pnt != '\0'; pnt++) {
875 		*pnt = 'x';
876 	    }
877 	}
878 	NE_DEBUG(NE_DBG_HTTP, "Sending request headers:\n%s", reqdebug);
879 	ne_free(reqdebug);
880     }
881 }
882 
883 #else
884 #define DEBUG_DUMP_REQUEST(x)
885 #endif /* DEBUGGING */
886 
887 /* remove trailing EOL from 'buf', where strlen(buf) == *len.  *len is
888  * adjusted in accordance with any changes made to the string to
889  * remain equal to strlen(buf). */
strip_eol(char * buf,ssize_t * len)890 static inline void strip_eol(char *buf, ssize_t *len)
891 {
892     char *pnt = &buf[*len-1];
893     while (pnt >= buf && (*pnt == '\r' || *pnt == '\n')) {
894 	*pnt-- = '\0';
895 	(*len)--;
896     }
897 }
898 
899 /* For accurate persistent connection handling, for any write() or
900  * read() operation for a new request on an already-open connection,
901  * an EOF or RST error MUST be treated as a persistent connection
902  * timeout, and the request retried on a new connection.  Once a
903  * read() operation has succeeded, any subsequent error MUST be
904  * treated as fatal.  A 'retry' flag is used; retry=1 represents the
905  * first case, retry=0 the latter. */
906 
907 /* RETRY_RET() crafts a function return value given the 'retry' flag,
908  * the socket error 'code', and the return value 'acode' from the
909  * aborted() function. */
910 #define RETRY_RET(retry, code, acode) \
911 ((((code) == NE_SOCK_CLOSED || (code) == NE_SOCK_RESET || \
912  (code) == NE_SOCK_TRUNC) && retry) ? NE_RETRY : (acode))
913 
914 /* Read and parse response status-line into 'status'.  'retry' is non-zero
915  * if an NE_RETRY should be returned if an EOF is received. */
read_status_line(ne_request * req,ne_status * status,int retry)916 static int read_status_line(ne_request *req, ne_status *status, int retry)
917 {
918     char *buffer = req->respbuf;
919     ssize_t ret;
920 
921     ret = ne_sock_readline(req->session->socket, buffer, sizeof req->respbuf);
922     if (ret <= 0) {
923 	int aret = aborted(req, _("Could not read status line"), ret);
924 	return RETRY_RET(retry, ret, aret);
925     }
926 
927     NE_DEBUG(NE_DBG_HTTP, "[status-line] < %s", buffer);
928     strip_eol(buffer, &ret);
929 
930     if (status->reason_phrase) ne_free(status->reason_phrase);
931     memset(status, 0, sizeof *status);
932 
933     if (ne_parse_statusline(buffer, status))
934 	return aborted(req, _("Could not parse response status line."), 0);
935 
936     return 0;
937 }
938 
939 /* Discard a set of message headers. */
discard_headers(ne_request * req)940 static int discard_headers(ne_request *req)
941 {
942     do {
943 	SOCK_ERR(req, ne_sock_readline(req->session->socket, req->respbuf,
944 				       sizeof req->respbuf),
945 		 _("Could not read interim response headers"));
946 	NE_DEBUG(NE_DBG_HTTP, "[discard] < %s", req->respbuf);
947     } while (strcmp(req->respbuf, EOL) != 0);
948     return NE_OK;
949 }
950 
951 /* Send the request, and read the response Status-Line. Returns:
952  *   NE_RETRY   connection closed by server; persistent connection
953  *		timeout
954  *   NE_OK	success
955  *   NE_*	error
956  * On NE_RETRY and NE_* responses, the connection will have been
957  * closed already.
958  */
send_request(ne_request * req,const ne_buffer * request)959 static int send_request(ne_request *req, const ne_buffer *request)
960 {
961     ne_session *sess = req->session;
962     ssize_t ret = NE_OK;
963     int sentbody = 0; /* zero until body has been sent. */
964     int retry; /* non-zero whilst the request should be retried */
965     ne_status *status = &req->status;
966 
967     /* Send the Request-Line and headers */
968     NE_DEBUG(NE_DBG_HTTP, "Sending request-line and headers:\n");
969     /* Open the connection if necessary */
970     HTTP_ERR(open_connection(req));
971 
972     /* Allow retry if a persistent connection has been used. */
973     retry = sess->persisted;
974 
975     ret = ne_sock_fullwrite(req->session->socket, request->data,
976 			    ne_buffer_size(request));
977     if (ret < 0) {
978 	int aret = aborted(req, _("Could not send request"), ret);
979 	return RETRY_RET(retry, ret, aret);
980     }
981 
982     if (!req->use_expect100 && req->body_size > 0) {
983 	/* Send request body, if not using 100-continue. */
984 	ret = send_request_body(req);
985 	if (ret < 0) {
986 	    int aret = aborted(req, _("Could not send request body"), ret);
987 	    return RETRY_RET(sess, ret, aret);
988 	}
989     }
990 
991     NE_DEBUG(NE_DBG_HTTP, "Request sent; retry is %d.\n", retry);
992 
993     /* Loop eating interim 1xx responses (RFC2616 says these MAY be
994      * sent by the server, even if 100-continue is not used). */
995     while ((ret = read_status_line(req, status, retry)) == NE_OK
996 	   && status->klass == 1) {
997 	NE_DEBUG(NE_DBG_HTTP, "Interim %d response.\n", status->code);
998 	retry = 0; /* successful read() => never retry now. */
999 	/* Discard headers with the interim response. */
1000 	if ((ret = discard_headers(req)) != NE_OK) break;
1001 
1002 	if (req->use_expect100 && (status->code == 100) && !sentbody) {
1003 	    /* Send the body after receiving the first 100 Continue */
1004 	    if ((ret = send_request_body(req)) != NE_OK) break;
1005 	    sentbody = 1;
1006 	}
1007     }
1008 
1009     return ret;
1010 }
1011 
1012 /* Read a message header from sock into buf, which has size 'buflen'.
1013  *
1014  * Returns:
1015  *   NE_RETRY: Success, read a header into buf.
1016  *   NE_OK: End of headers reached.
1017  *   NE_ERROR: Error (session error is set).
1018  */
read_message_header(ne_request * req,char * buf,size_t buflen)1019 static int read_message_header(ne_request *req, char *buf, size_t buflen)
1020 {
1021     ssize_t n;
1022     ne_socket *sock = req->session->socket;
1023 
1024     n = ne_sock_readline(sock, buf, buflen);
1025     if (n <= 0)
1026 	return aborted(req, _("Error reading response headers"), n);
1027     NE_DEBUG(NE_DBG_HTTP, "[hdr] %s", buf);
1028 
1029     strip_eol(buf, &n);
1030 
1031     if (n == 0) {
1032 	NE_DEBUG(NE_DBG_HTTP, "End of headers.\n");
1033 	return NE_OK;
1034     }
1035 
1036     buf += n;
1037     buflen -= n;
1038 
1039     while (buflen > 0) {
1040 	char ch;
1041 
1042 	/* Collect any extra lines into buffer */
1043 	SOCK_ERR(req, ne_sock_peek(sock, &ch, 1),
1044 		 _("Error reading response headers"));
1045 
1046 	if (ch != ' ' && ch != '\t') {
1047 	    /* No continuation of this header: stop reading. */
1048 	    return NE_RETRY;
1049 	}
1050 
1051 	/* Otherwise, read the next line onto the end of 'buf'. */
1052 	n = ne_sock_readline(sock, buf, buflen);
1053 	if (n <= 0) {
1054 	    return aborted(req, _("Error reading response headers"), n);
1055 	}
1056 
1057 	NE_DEBUG(NE_DBG_HTTP, "[cont] %s", buf);
1058 
1059 	strip_eol(buf, &n);
1060 
1061 	/* assert(buf[0] == ch), which implies len(buf) > 0.
1062 	 * Otherwise the TCP stack is lying, but we'll be paranoid.
1063 	 * This might be a \t, so replace it with a space to be
1064 	 * friendly to applications (2616 says we MAY do this). */
1065 	if (n) buf[0] = ' ';
1066 
1067 	/* ready for the next header. */
1068 	buf += n;
1069 	buflen -= n;
1070     }
1071 
1072     ne_set_error(req->session, _("Response header too long"));
1073     return NE_ERROR;
1074 }
1075 
1076 /* Apache's default is 100, seems reasonable. */
1077 #define MAX_HEADER_FIELDS 100
1078 
1079 /* Read response headers.  Returns NE_* code, sets session error. */
read_response_headers(ne_request * req)1080 static int read_response_headers(ne_request *req)
1081 {
1082     char hdr[8192]; /* max header length */
1083     int ret, count = 0;
1084 
1085     while ((ret = read_message_header(req, hdr, sizeof hdr)) == NE_RETRY
1086 	   && ++count < MAX_HEADER_FIELDS) {
1087 	struct header_handler *hdl;
1088 	char *pnt;
1089 	unsigned int hash = 0;
1090 
1091 	for (hdl = req->header_catchers; hdl != NULL; hdl = hdl->next)
1092 	    hdl->handler(hdl->userdata, hdr);
1093 
1094 	/* Strip any trailing whitespace */
1095 	pnt = hdr + strlen(hdr) - 1;
1096 	while (pnt > hdr && (*pnt == ' ' || *pnt == '\t'))
1097 	    *pnt-- = '\0';
1098 
1099 	/* Convert the header name to lower case and hash it. */
1100 	for (pnt = hdr; (*pnt != '\0' && *pnt != ':' &&
1101 			 *pnt != ' ' && *pnt != '\t'); pnt++) {
1102 	    *pnt = tolower(*pnt);
1103 	    hash = HH_ITERATE(hash,*pnt);
1104 	}
1105 
1106 	/* Skip over any whitespace before the colon. */
1107 	while (*pnt == ' ' || *pnt == '\t')
1108 	    *pnt++ = '\0';
1109 
1110 	/* ignore header lines which lack a ':'. */
1111 	if (*pnt != ':')
1112 	    continue;
1113 
1114 	/* NUL-terminate at the colon (when no whitespace before) */
1115 	*pnt++ = '\0';
1116 
1117 	/* Skip any whitespace after the colon... */
1118 	while (*pnt == ' ' || *pnt == '\t')
1119 	    pnt++;
1120 
1121 	/* pnt now points to the header value. */
1122 	NE_DEBUG(NE_DBG_HTTP, "Header Name: [%s], Value: [%s]\n", hdr, pnt);
1123 
1124 	/* Iterate through the header handlers */
1125 	for (hdl = req->header_handlers[hash]; hdl != NULL; hdl = hdl->next) {
1126 	    if (strcmp(hdr, hdl->name) == 0)
1127 		hdl->handler(hdl->userdata, pnt);
1128 	}
1129     }
1130 
1131     if (count == MAX_HEADER_FIELDS)
1132 	ret = aborted(
1133 	    req, _("Response exceeded maximum number of header fields."), 0);
1134 
1135     return ret;
1136 }
1137 
lookup_host(ne_session * sess,struct host_info * info)1138 static int lookup_host(ne_session *sess, struct host_info *info)
1139 {
1140     NE_DEBUG(NE_DBG_HTTP, "Doing DNS lookup on %s...\n", info->hostname);
1141     if (sess->notify_cb)
1142 	sess->notify_cb(sess->notify_ud, ne_conn_namelookup, info->hostname);
1143     info->address = ne_addr_resolve(info->hostname, 0);
1144     if (ne_addr_result(info->address)) {
1145 	char buf[256];
1146 	ne_set_error(sess, _("Could not resolve hostname `%s': %s"),
1147 		     info->hostname,
1148 		     ne_addr_error(info->address, buf, sizeof buf));
1149 	ne_addr_destroy(info->address);
1150 	info->address = NULL;
1151 	return NE_LOOKUP;
1152     } else {
1153 	return NE_OK;
1154     }
1155 }
1156 
ne_begin_request(ne_request * req)1157 int ne_begin_request(ne_request *req)
1158 {
1159     struct body_reader *rdr;
1160     struct host_info *host;
1161     ne_buffer *data;
1162     const ne_status *const st = &req->status;
1163     int ret;
1164 
1165     /* Resolve hostname if necessary. */
1166     host = req->session->use_proxy?&req->session->proxy:&req->session->server;
1167     if (host->address == NULL)
1168 	HTTP_ERR(lookup_host(req->session, host));
1169 
1170     req->resp.mode = R_TILLEOF;
1171 
1172     /* FIXME: Determine whether to use the Expect: 100-continue header. */
1173     req->use_expect100 = (req->session->expect100_works > -1) &&
1174 	(req->body_size > HTTP_EXPECT_MINSIZE) && req->session->is_http11;
1175 
1176     /* Build the request string, and send it */
1177     data = build_request(req);
1178     DEBUG_DUMP_REQUEST(data->data);
1179     ret = send_request(req, data);
1180     /* Retry this once after a persistent connection timeout. */
1181     if (ret == NE_RETRY && !req->session->no_persist) {
1182 	NE_DEBUG(NE_DBG_HTTP, "Persistent connection timed out, retrying.\n");
1183 	ret = send_request(req, data);
1184     }
1185     ne_buffer_destroy(data);
1186     if (ret != NE_OK) return ret;
1187 
1188     /* Determine whether server claims HTTP/1.1 compliance. */
1189     req->session->is_http11 = (st->major_version == 1 &&
1190                                st->minor_version > 0) || st->major_version > 1;
1191 
1192     /* Persistent connections supported implicitly in HTTP/1.1 */
1193     if (req->session->is_http11) req->can_persist = 1;
1194 
1195     ne_set_error(req->session, "%d %s", st->code, st->reason_phrase);
1196 
1197     /* Read the headers */
1198     HTTP_ERR(read_response_headers(req));
1199 
1200 #ifdef NEON_SSL
1201     /* Special case for CONNECT handling: the response has no body,
1202      * and the connection can persist. */
1203     if (req->session->in_connect && st->klass == 2) {
1204 	req->resp.mode = R_NO_BODY;
1205 	req->can_persist = 1;
1206     }
1207 #endif
1208 
1209     /* HEAD requests and 204, 205, 304 responses have no response body,
1210      * regardless of what headers are present. */
1211     if (req->method_is_head || st->code==204 || st->code==205 || st->code==304)
1212     	req->resp.mode = R_NO_BODY;
1213 
1214     /* Prepare for reading the response entity-body.  Call each of the
1215      * body readers and ask them whether they want to accept this
1216      * response or not. */
1217     for (rdr = req->body_readers; rdr != NULL; rdr=rdr->next) {
1218 	rdr->use = rdr->accept_response(rdr->userdata, req, st);
1219     }
1220 
1221     req->resp.left = req->resp.length;
1222     req->resp.chunk_left = 0;
1223 
1224     return NE_OK;
1225 }
1226 
ne_end_request(ne_request * req)1227 int ne_end_request(ne_request *req)
1228 {
1229     struct hook *hk;
1230     int ret = NE_OK;
1231 
1232     /* Read headers in chunked trailers */
1233     if (req->resp.mode == R_CHUNKED)
1234 	HTTP_ERR(read_response_headers(req));
1235 
1236     NE_DEBUG(NE_DBG_HTTP, "Running post_send hooks\n");
1237     for (hk = req->session->post_send_hooks;
1238 	 ret == NE_OK && hk != NULL; hk = hk->next) {
1239 	ne_post_send_fn fn = (ne_post_send_fn)hk->fn;
1240 	ret = fn(req, hk->userdata, &req->status);
1241     }
1242 
1243     /* Close the connection if persistent connections are disabled or
1244      * not supported by the server. */
1245     if (req->session->no_persist || !req->can_persist)
1246 	ne_close_connection(req->session);
1247     else
1248 	req->session->persisted = 1;
1249 
1250     return ret;
1251 }
1252 
ne_request_dispatch(ne_request * req)1253 int ne_request_dispatch(ne_request *req)
1254 {
1255     int ret;
1256 
1257     /* Loop sending the request:
1258      * Retry whilst authentication fails and we supply it. */
1259 
1260     do {
1261 	ssize_t len;
1262 
1263 	HTTP_ERR(ne_begin_request(req));
1264 
1265 	do {
1266 	    len = ne_read_response_block(req, req->respbuf,
1267 					 sizeof req->respbuf);
1268 	} while (len > 0);
1269 
1270 	if (len < 0) {
1271 	    return NE_ERROR;
1272 	}
1273 
1274 	ret = ne_end_request(req);
1275 
1276     } while (ret == NE_RETRY);
1277 
1278     NE_DEBUG(NE_DBG_HTTP | NE_DBG_FLUSH,
1279 	   "Request ends, status %d class %dxx, error line:\n%s\n",
1280 	   req->status.code, req->status.klass, req->session->error);
1281 
1282     return ret;
1283 }
1284 
ne_get_status(const ne_request * req)1285 const ne_status *ne_get_status(const ne_request *req)
1286 {
1287     return &req->status;
1288 }
1289 
ne_get_session(const ne_request * req)1290 ne_session *ne_get_session(const ne_request *req)
1291 {
1292     return req->session;
1293 }
1294 
1295 #ifdef NEON_SSL
1296 /* Create a CONNECT tunnel through the proxy server.
1297  * Returns HTTP_* */
proxy_tunnel(ne_session * sess)1298 static int proxy_tunnel(ne_session *sess)
1299 {
1300     /* Hack up an HTTP CONNECT request... */
1301     ne_request *req;
1302     int ret = NE_OK;
1303     char ruri[200];
1304 
1305     /* Can't use server.hostport here; Request-URI must include `:port' */
1306     ne_snprintf(ruri, sizeof ruri, "%s:%u", sess->server.hostname,
1307 		sess->server.port);
1308     req = ne_request_create(sess, "CONNECT", ruri);
1309 
1310     sess->in_connect = 1;
1311     ret = ne_request_dispatch(req);
1312     sess->in_connect = 0;
1313 
1314     sess->persisted = 0; /* don't treat this is a persistent connection. */
1315 
1316     if (ret != NE_OK || !sess->connected || req->status.klass != 2) {
1317 	ne_set_error
1318 	    (sess, _("Could not create SSL connection through proxy server"));
1319 	ret = NE_ERROR;
1320     }
1321 
1322     ne_request_destroy(req);
1323     return ret;
1324 }
1325 #endif
1326 
1327 /* Make new TCP connection to server at 'host' of type 'name'.  Note
1328  * that once a connection to a particular network address has
1329  * succeeded, that address will be used first for the next attempt to
1330  * connect. */
1331 /* TODO: an alternate implementation could always cycle through the
1332  * addresses: this could ease server load, but could hurt SSL session
1333  * caching for SSL sessions, which would increase server load. */
do_connect(ne_request * req,struct host_info * host,const char * err)1334 static int do_connect(ne_request *req, struct host_info *host, const char *err)
1335 {
1336     ne_session *const sess = req->session;
1337     int ret;
1338 
1339     if ((sess->socket = ne_sock_create()) == NULL) {
1340         ne_set_error(sess, _("Could not create socket"));
1341         return NE_ERROR;
1342     }
1343 
1344     if (host->current == NULL)
1345 	host->current = ne_addr_first(host->address);
1346 
1347     do {
1348 	notify_status(sess, ne_conn_connecting, host->hostport);
1349 #ifdef NE_DEBUGGING
1350 	if (ne_debug_mask & NE_DBG_HTTP) {
1351 	    char buf[150];
1352 	    NE_DEBUG(NE_DBG_HTTP, "Connecting to %s\n",
1353 		     ne_iaddr_print(host->current, buf, sizeof buf));
1354 	}
1355 #endif
1356 	ret = ne_sock_connect(sess->socket, host->current, host->port);
1357     } while (ret && /* try the next address... */
1358 	     (host->current = ne_addr_next(host->address)) != NULL);
1359 
1360     if (ret) {
1361         ne_set_error(sess, "%s: %s", err, ne_sock_error(sess->socket));
1362         ne_sock_close(sess->socket);
1363 	return NE_CONNECT;
1364     }
1365 
1366     notify_status(sess, ne_conn_connected, sess->proxy.hostport);
1367 
1368     if (sess->rdtimeout)
1369 	ne_sock_read_timeout(sess->socket, sess->rdtimeout);
1370 
1371     sess->connected = 1;
1372     /* clear persistent connection flag. */
1373     sess->persisted = 0;
1374     return NE_OK;
1375 }
1376 
open_connection(ne_request * req)1377 static int open_connection(ne_request *req)
1378 {
1379     ne_session *sess = req->session;
1380     int ret;
1381 
1382     if (sess->connected) return NE_OK;
1383 
1384     if (!sess->use_proxy)
1385 	ret = do_connect(req, &sess->server, _("Could not connect to server"));
1386     else
1387 	ret = do_connect(req, &sess->proxy,
1388 			 _("Could not connect to proxy server"));
1389 
1390     if (ret != NE_OK) return ret;
1391 
1392 #ifdef NEON_SSL
1393     /* Negotiate SSL layer if required. */
1394     if (sess->use_ssl && !sess->in_connect) {
1395         /* CONNECT tunnel */
1396         if (req->session->use_proxy)
1397             ret = proxy_tunnel(sess);
1398 
1399         if (ret == NE_OK)
1400             ret = ne_negotiate_ssl(req);
1401 
1402         /* This is probably only really needed for ne_negotiate_ssl
1403          * failures as proxy_tunnel will fail via aborted(). */
1404         if (ret != NE_OK)
1405             ne_close_connection(sess);
1406     }
1407 #endif
1408 
1409     return ret;
1410 }
1411