1 /*
2  * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /**
27  * @file
28  *
29  * Hyper Text Transfer Protocol (HTTP) core functionality
30  *
31  */
32 
33 #include <stdint.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <byteswap.h>
39 #include <errno.h>
40 #include <ctype.h>
41 #include <assert.h>
42 #include <ipxe/uri.h>
43 #include <ipxe/refcnt.h>
44 #include <ipxe/iobuf.h>
45 #include <ipxe/xfer.h>
46 #include <ipxe/open.h>
47 #include <ipxe/process.h>
48 #include <ipxe/retry.h>
49 #include <ipxe/timer.h>
50 #include <ipxe/linebuf.h>
51 #include <ipxe/xferbuf.h>
52 #include <ipxe/blockdev.h>
53 #include <ipxe/acpi.h>
54 #include <ipxe/version.h>
55 #include <ipxe/params.h>
56 #include <ipxe/profile.h>
57 #include <ipxe/vsprintf.h>
58 #include <ipxe/errortab.h>
59 #include <ipxe/http.h>
60 
61 /* Disambiguate the various error causes */
62 #define EACCES_401 __einfo_error ( EINFO_EACCES_401 )
63 #define EINFO_EACCES_401 \
64 	__einfo_uniqify ( EINFO_EACCES, 0x01, "HTTP 401 Unauthorized" )
65 #define EINVAL_STATUS __einfo_error ( EINFO_EINVAL_STATUS )
66 #define EINFO_EINVAL_STATUS \
67 	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid status line" )
68 #define EINVAL_HEADER __einfo_error ( EINFO_EINVAL_HEADER )
69 #define EINFO_EINVAL_HEADER \
70 	__einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid header" )
71 #define EINVAL_CONTENT_LENGTH __einfo_error ( EINFO_EINVAL_CONTENT_LENGTH )
72 #define EINFO_EINVAL_CONTENT_LENGTH \
73 	__einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid content length" )
74 #define EINVAL_CHUNK_LENGTH __einfo_error ( EINFO_EINVAL_CHUNK_LENGTH )
75 #define EINFO_EINVAL_CHUNK_LENGTH \
76 	__einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid chunk length" )
77 #define EIO_OTHER __einfo_error ( EINFO_EIO_OTHER )
78 #define EINFO_EIO_OTHER \
79 	__einfo_uniqify ( EINFO_EIO, 0x01, "Unrecognised HTTP response code" )
80 #define EIO_CONTENT_LENGTH __einfo_error ( EINFO_EIO_CONTENT_LENGTH )
81 #define EINFO_EIO_CONTENT_LENGTH \
82 	__einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )
83 #define EIO_4XX __einfo_error ( EINFO_EIO_4XX )
84 #define EINFO_EIO_4XX \
85 	__einfo_uniqify ( EINFO_EIO, 0x04, "HTTP 4xx Client Error" )
86 #define EIO_5XX __einfo_error ( EINFO_EIO_5XX )
87 #define EINFO_EIO_5XX \
88 	__einfo_uniqify ( EINFO_EIO, 0x05, "HTTP 5xx Server Error" )
89 #define ENOENT_404 __einfo_error ( EINFO_ENOENT_404 )
90 #define EINFO_ENOENT_404 \
91 	__einfo_uniqify ( EINFO_ENOENT, 0x01, "HTTP 404 Not Found" )
92 #define ENOTSUP_CONNECTION __einfo_error ( EINFO_ENOTSUP_CONNECTION )
93 #define EINFO_ENOTSUP_CONNECTION \
94 	__einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported connection header" )
95 #define ENOTSUP_TRANSFER __einfo_error ( EINFO_ENOTSUP_TRANSFER )
96 #define EINFO_ENOTSUP_TRANSFER \
97 	__einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported transfer encoding" )
98 #define EPERM_403 __einfo_error ( EINFO_EPERM_403 )
99 #define EINFO_EPERM_403 \
100 	__einfo_uniqify ( EINFO_EPERM, 0x01, "HTTP 403 Forbidden" )
101 #define EPROTO_UNSOLICITED __einfo_error ( EINFO_EPROTO_UNSOLICITED )
102 #define EINFO_EPROTO_UNSOLICITED \
103 	__einfo_uniqify ( EINFO_EPROTO, 0x01, "Unsolicited data" )
104 
105 /** Retry delay used when we cannot understand the Retry-After header */
106 #define HTTP_RETRY_SECONDS 5
107 
108 /** Receive profiler */
109 static struct profiler http_rx_profiler __profiler = { .name = "http.rx" };
110 
111 /** Data transfer profiler */
112 static struct profiler http_xfer_profiler __profiler = { .name = "http.xfer" };
113 
114 /** Human-readable error messages */
115 struct errortab http_errors[] __errortab = {
116 	__einfo_errortab ( EINFO_EIO_4XX ),
117 	__einfo_errortab ( EINFO_EIO_5XX ),
118 };
119 
120 static struct http_state http_request;
121 static struct http_state http_headers;
122 static struct http_state http_trailers;
123 static struct http_transfer_encoding http_transfer_identity;
124 
125 /******************************************************************************
126  *
127  * Methods
128  *
129  ******************************************************************************
130  */
131 
132 /** HTTP HEAD method */
133 struct http_method http_head = {
134 	.name = "HEAD",
135 };
136 
137 /** HTTP GET method */
138 struct http_method http_get = {
139 	.name = "GET",
140 };
141 
142 /** HTTP POST method */
143 struct http_method http_post = {
144 	.name = "POST",
145 };
146 
147 /******************************************************************************
148  *
149  * Utility functions
150  *
151  ******************************************************************************
152  */
153 
154 /**
155  * Handle received HTTP line-buffered data
156  *
157  * @v http		HTTP transaction
158  * @v iobuf		I/O buffer
159  * @v linebuf		Line buffer
160  * @ret rc		Return status code
161  */
http_rx_linebuf(struct http_transaction * http,struct io_buffer * iobuf,struct line_buffer * linebuf)162 static int http_rx_linebuf ( struct http_transaction *http,
163 			     struct io_buffer *iobuf,
164 			     struct line_buffer *linebuf ) {
165 	int consumed;
166 	int rc;
167 
168 	/* Buffer received line */
169 	consumed = line_buffer ( linebuf, iobuf->data, iob_len ( iobuf ) );
170 	if ( consumed < 0 ) {
171 		rc = consumed;
172 		DBGC ( http, "HTTP %p could not buffer line: %s\n",
173 		       http, strerror ( rc ) );
174 		return rc;
175 	}
176 
177 	/* Consume line */
178 	iob_pull ( iobuf, consumed );
179 
180 	return 0;
181 }
182 
183 /**
184  * Get HTTP response token
185  *
186  * @v line		Line position
187  * @v value		Token value to fill in (if any)
188  * @ret token		Token, or NULL
189  */
http_token(char ** line,char ** value)190 char * http_token ( char **line, char **value ) {
191 	char *token;
192 	char quote = '\0';
193 	char c;
194 
195 	/* Avoid returning uninitialised data */
196 	if ( value )
197 		*value = NULL;
198 
199 	/* Skip any initial whitespace or commas */
200 	while ( ( isspace ( **line ) ) || ( **line == ',' ) )
201 		(*line)++;
202 
203 	/* Check for end of line and record token position */
204 	if ( ! **line )
205 		return NULL;
206 	token = *line;
207 
208 	/* Scan for end of token */
209 	while ( ( c = **line ) ) {
210 
211 		/* Terminate if we hit an unquoted whitespace or comma */
212 		if ( ( isspace ( c ) || ( c == ',' ) ) && ! quote )
213 			break;
214 
215 		/* Terminate if we hit a closing quote */
216 		if ( c == quote )
217 			break;
218 
219 		/* Check for value separator */
220 		if ( value && ( ! *value ) && ( c == '=' ) ) {
221 
222 			/* Terminate key portion of token */
223 			*((*line)++) = '\0';
224 
225 			/* Check for quote character */
226 			c = **line;
227 			if ( ( c == '"' ) || ( c == '\'' ) ) {
228 				quote = c;
229 				(*line)++;
230 			}
231 
232 			/* Record value portion of token */
233 			*value = *line;
234 
235 		} else {
236 
237 			/* Move to next character */
238 			(*line)++;
239 		}
240 	}
241 
242 	/* Terminate token, if applicable */
243 	if ( c )
244 		*((*line)++) = '\0';
245 
246 	return token;
247 }
248 
249 /******************************************************************************
250  *
251  * Transactions
252  *
253  ******************************************************************************
254  */
255 
256 /**
257  * Free HTTP transaction
258  *
259  * @v refcnt		Reference count
260  */
http_free(struct refcnt * refcnt)261 static void http_free ( struct refcnt *refcnt ) {
262 	struct http_transaction *http =
263 		container_of ( refcnt, struct http_transaction, refcnt );
264 
265 	empty_line_buffer ( &http->response.headers );
266 	empty_line_buffer ( &http->linebuf );
267 	uri_put ( http->uri );
268 	free ( http );
269 }
270 
271 /**
272  * Close HTTP transaction
273  *
274  * @v http		HTTP transaction
275  * @v rc		Reason for close
276  */
http_close(struct http_transaction * http,int rc)277 static void http_close ( struct http_transaction *http, int rc ) {
278 
279 	/* Stop process */
280 	process_del ( &http->process );
281 
282 	/* Stop timer */
283 	stop_timer ( &http->timer );
284 
285 	/* Close all interfaces */
286 	intfs_shutdown ( rc, &http->conn, &http->transfer, &http->content,
287 			 &http->xfer, NULL );
288 }
289 
290 /**
291  * Close HTTP transaction with error (even if none specified)
292  *
293  * @v http		HTTP transaction
294  * @v rc		Reason for close
295  */
http_close_error(struct http_transaction * http,int rc)296 static void http_close_error ( struct http_transaction *http, int rc ) {
297 
298 	/* Treat any close as an error */
299 	http_close ( http, ( rc ? rc : -EPIPE ) );
300 }
301 
302 /**
303  * Reopen stale HTTP connection
304  *
305  * @v http		HTTP transaction
306  */
http_reopen(struct http_transaction * http)307 static void http_reopen ( struct http_transaction *http ) {
308 	int rc;
309 
310 	/* Close existing connection */
311 	intf_restart ( &http->conn, -ECANCELED );
312 
313 	/* Reopen connection */
314 	if ( ( rc = http_connect ( &http->conn, http->uri ) ) != 0 ) {
315 		DBGC ( http, "HTTP %p could not reconnect: %s\n",
316 		       http, strerror ( rc ) );
317 		goto err_connect;
318 	}
319 
320 	/* Reset state */
321 	http->state = &http_request;
322 
323 	/* Reschedule transmission process */
324 	process_add ( &http->process );
325 
326 	return;
327 
328  err_connect:
329 	http_close ( http, rc );
330 }
331 
332 /**
333  * Handle retry timer expiry
334  *
335  * @v timer		Retry timer
336  * @v over		Failure indicator
337  */
http_expired(struct retry_timer * timer,int over __unused)338 static void http_expired ( struct retry_timer *timer, int over __unused ) {
339 	struct http_transaction *http =
340 		container_of ( timer, struct http_transaction, timer );
341 
342 	/* Reopen connection */
343 	http_reopen ( http );
344 }
345 
346 /**
347  * HTTP transmit process
348  *
349  * @v http		HTTP transaction
350  */
http_step(struct http_transaction * http)351 static void http_step ( struct http_transaction *http ) {
352 	int rc;
353 
354 	/* Do nothing if we have nothing to transmit */
355 	if ( ! http->state->tx )
356 		return;
357 
358 	/* Do nothing until connection is ready */
359 	if ( ! xfer_window ( &http->conn ) )
360 		return;
361 
362 	/* Notify data transfer interface that window may have changed */
363 	xfer_window_changed ( &http->xfer );
364 
365 	/* Do nothing until data transfer interface is ready */
366 	if ( ! xfer_window ( &http->xfer ) )
367 		return;
368 
369 	/* Transmit data */
370 	if ( ( rc = http->state->tx ( http ) ) != 0 )
371 		goto err;
372 
373 	return;
374 
375  err:
376 	http_close ( http, rc );
377 }
378 
379 /**
380  * Handle received HTTP data
381  *
382  * @v http		HTTP transaction
383  * @v iobuf		I/O buffer
384  * @v meta		Transfer metadata
385  * @ret rc		Return status code
386  *
387  * This function takes ownership of the I/O buffer.
388  */
http_conn_deliver(struct http_transaction * http,struct io_buffer * iobuf,struct xfer_metadata * meta __unused)389 static int http_conn_deliver ( struct http_transaction *http,
390 			       struct io_buffer *iobuf,
391 			       struct xfer_metadata *meta __unused ) {
392 	int rc;
393 
394 	/* Handle received data */
395 	profile_start ( &http_rx_profiler );
396 	while ( iobuf && iob_len ( iobuf ) ) {
397 
398 		/* Sanity check */
399 		if ( ( ! http->state ) || ( ! http->state->rx ) ) {
400 			DBGC ( http, "HTTP %p unexpected data\n", http );
401 			rc = -EPROTO_UNSOLICITED;
402 			goto err;
403 		}
404 
405 		/* Receive (some) data */
406 		if ( ( rc = http->state->rx ( http, &iobuf ) ) != 0 )
407 			goto err;
408 	}
409 
410 	/* Free I/O buffer, if applicable */
411 	free_iob ( iobuf );
412 
413 	profile_stop ( &http_rx_profiler );
414 	return 0;
415 
416  err:
417 	free_iob ( iobuf );
418 	http_close ( http, rc );
419 	return rc;
420 }
421 
422 /**
423  * Handle server connection close
424  *
425  * @v http		HTTP transaction
426  * @v rc		Reason for close
427  */
http_conn_close(struct http_transaction * http,int rc)428 static void http_conn_close ( struct http_transaction *http, int rc ) {
429 
430 	/* Sanity checks */
431 	assert ( http->state != NULL );
432 	assert ( http->state->close != NULL );
433 
434 	/* Restart server connection interface */
435 	intf_restart ( &http->conn, rc );
436 
437 	/* Hand off to state-specific method */
438 	http->state->close ( http, rc );
439 }
440 
441 /**
442  * Handle received content-decoded data
443  *
444  * @v http		HTTP transaction
445  * @v iobuf		I/O buffer
446  * @v meta		Data transfer metadata
447  */
http_content_deliver(struct http_transaction * http,struct io_buffer * iobuf,struct xfer_metadata * meta)448 static int http_content_deliver ( struct http_transaction *http,
449 				  struct io_buffer *iobuf,
450 				  struct xfer_metadata *meta ) {
451 	int rc;
452 
453 	/* Ignore content if this is anything other than a successful
454 	 * transfer.
455 	 */
456 	if ( http->response.rc != 0 ) {
457 		free_iob ( iobuf );
458 		return 0;
459 	}
460 
461 	/* Deliver to data transfer interface */
462 	profile_start ( &http_xfer_profiler );
463 	if ( ( rc = xfer_deliver ( &http->xfer, iob_disown ( iobuf ),
464 				   meta ) ) != 0 )
465 		return rc;
466 	profile_stop ( &http_xfer_profiler );
467 
468 	return 0;
469 }
470 
471 /**
472  * Get underlying data transfer buffer
473  *
474  * @v http		HTTP transaction
475  * @ret xferbuf		Data transfer buffer, or NULL on error
476  */
477 static struct xfer_buffer *
http_content_buffer(struct http_transaction * http)478 http_content_buffer ( struct http_transaction *http ) {
479 
480 	/* Deny access to the data transfer buffer if this is anything
481 	 * other than a successful transfer.
482 	 */
483 	if ( http->response.rc != 0 )
484 		return NULL;
485 
486 	/* Hand off to data transfer interface */
487 	return xfer_buffer ( &http->xfer );
488 }
489 
490 /**
491  * Read from block device (when HTTP block device support is not present)
492  *
493  * @v http		HTTP transaction
494  * @v data		Data interface
495  * @v lba		Starting logical block address
496  * @v count		Number of logical blocks
497  * @v buffer		Data buffer
498  * @v len		Length of data buffer
499  * @ret rc		Return status code
500  */
http_block_read(struct http_transaction * http __unused,struct interface * data __unused,uint64_t lba __unused,unsigned int count __unused,userptr_t buffer __unused,size_t len __unused)501 __weak int http_block_read ( struct http_transaction *http __unused,
502 			     struct interface *data __unused,
503 			     uint64_t lba __unused, unsigned int count __unused,
504 			     userptr_t buffer __unused, size_t len __unused ) {
505 
506 	return -ENOTSUP;
507 }
508 
509 /**
510  * Read block device capacity (when HTTP block device support is not present)
511  *
512  * @v control		Control interface
513  * @v data		Data interface
514  * @ret rc		Return status code
515  */
http_block_read_capacity(struct http_transaction * http __unused,struct interface * data __unused)516 __weak int http_block_read_capacity ( struct http_transaction *http __unused,
517 				      struct interface *data __unused ) {
518 
519 	return -ENOTSUP;
520 }
521 
522 /** HTTP data transfer interface operations */
523 static struct interface_operation http_xfer_operations[] = {
524 	INTF_OP ( block_read, struct http_transaction *, http_block_read ),
525 	INTF_OP ( block_read_capacity, struct http_transaction *,
526 		  http_block_read_capacity ),
527 	INTF_OP ( xfer_window_changed, struct http_transaction *, http_step ),
528 	INTF_OP ( intf_close, struct http_transaction *, http_close ),
529 };
530 
531 /** HTTP data transfer interface descriptor */
532 static struct interface_descriptor http_xfer_desc =
533 	INTF_DESC_PASSTHRU ( struct http_transaction, xfer,
534 			     http_xfer_operations, content );
535 
536 /** HTTP content-decoded interface operations */
537 static struct interface_operation http_content_operations[] = {
538 	INTF_OP ( xfer_deliver, struct http_transaction *,
539 		  http_content_deliver ),
540 	INTF_OP ( xfer_buffer, struct http_transaction *, http_content_buffer ),
541 	INTF_OP ( intf_close, struct http_transaction *, http_close ),
542 };
543 
544 /** HTTP content-decoded interface descriptor */
545 static struct interface_descriptor http_content_desc =
546 	INTF_DESC_PASSTHRU ( struct http_transaction, content,
547 			     http_content_operations, xfer );
548 
549 /** HTTP transfer-decoded interface operations */
550 static struct interface_operation http_transfer_operations[] = {
551 	INTF_OP ( intf_close, struct http_transaction *, http_close ),
552 };
553 
554 /** HTTP transfer-decoded interface descriptor */
555 static struct interface_descriptor http_transfer_desc =
556 	INTF_DESC_PASSTHRU ( struct http_transaction, transfer,
557 			     http_transfer_operations, conn );
558 
559 /** HTTP server connection interface operations */
560 static struct interface_operation http_conn_operations[] = {
561 	INTF_OP ( xfer_deliver, struct http_transaction *, http_conn_deliver ),
562 	INTF_OP ( xfer_window_changed, struct http_transaction *, http_step ),
563 	INTF_OP ( pool_reopen, struct http_transaction *, http_reopen ),
564 	INTF_OP ( intf_close, struct http_transaction *, http_conn_close ),
565 };
566 
567 /** HTTP server connection interface descriptor */
568 static struct interface_descriptor http_conn_desc =
569 	INTF_DESC_PASSTHRU ( struct http_transaction, conn,
570 			     http_conn_operations, transfer );
571 
572 /** HTTP process descriptor */
573 static struct process_descriptor http_process_desc =
574 	PROC_DESC_ONCE ( struct http_transaction, process, http_step );
575 
576 /**
577  * Open HTTP transaction
578  *
579  * @v xfer		Data transfer interface
580  * @v method		Request method
581  * @v uri		Request URI
582  * @v range		Content range (if any)
583  * @v content		Request content (if any)
584  * @ret rc		Return status code
585  */
http_open(struct interface * xfer,struct http_method * method,struct uri * uri,struct http_request_range * range,struct http_request_content * content)586 int http_open ( struct interface *xfer, struct http_method *method,
587 		struct uri *uri, struct http_request_range *range,
588 		struct http_request_content *content ) {
589 	struct http_transaction *http;
590 	struct uri request_uri;
591 	struct uri request_host;
592 	size_t request_uri_len;
593 	size_t request_host_len;
594 	size_t content_len;
595 	char *request_uri_string;
596 	char *request_host_string;
597 	void *content_data;
598 	int rc;
599 
600 	/* Calculate request URI length */
601 	memset ( &request_uri, 0, sizeof ( request_uri ) );
602 	request_uri.path = ( uri->path ? uri->path : "/" );
603 	request_uri.query = uri->query;
604 	request_uri_len =
605 		( format_uri ( &request_uri, NULL, 0 ) + 1 /* NUL */);
606 
607 	/* Calculate host name length */
608 	memset ( &request_host, 0, sizeof ( request_host ) );
609 	request_host.host = uri->host;
610 	request_host.port = uri->port;
611 	request_host_len =
612 		( format_uri ( &request_host, NULL, 0 ) + 1 /* NUL */ );
613 
614 	/* Calculate request content length */
615 	content_len = ( content ? content->len : 0 );
616 
617 	/* Allocate and initialise structure */
618 	http = zalloc ( sizeof ( *http ) + request_uri_len + request_host_len +
619 			content_len );
620 	if ( ! http ) {
621 		rc = -ENOMEM;
622 		goto err_alloc;
623 	}
624 	request_uri_string = ( ( ( void * ) http ) + sizeof ( *http ) );
625 	request_host_string = ( request_uri_string + request_uri_len );
626 	content_data = ( request_host_string + request_host_len );
627 	format_uri ( &request_uri, request_uri_string, request_uri_len );
628 	format_uri ( &request_host, request_host_string, request_host_len );
629 	ref_init ( &http->refcnt, http_free );
630 	intf_init ( &http->xfer, &http_xfer_desc, &http->refcnt );
631 	intf_init ( &http->content, &http_content_desc, &http->refcnt );
632 	intf_init ( &http->transfer, &http_transfer_desc, &http->refcnt );
633 	intf_init ( &http->conn, &http_conn_desc, &http->refcnt );
634 	intf_plug_plug ( &http->transfer, &http->content );
635 	process_init ( &http->process, &http_process_desc, &http->refcnt );
636 	timer_init ( &http->timer, http_expired, &http->refcnt );
637 	http->uri = uri_get ( uri );
638 	http->request.method = method;
639 	http->request.uri = request_uri_string;
640 	http->request.host = request_host_string;
641 	if ( range ) {
642 		memcpy ( &http->request.range, range,
643 			 sizeof ( http->request.range ) );
644 	}
645 	if ( content ) {
646 		http->request.content.type = content->type;
647 		http->request.content.data = content_data;
648 		http->request.content.len = content_len;
649 		memcpy ( content_data, content->data, content_len );
650 	}
651 	http->state = &http_request;
652 	DBGC2 ( http, "HTTP %p %s://%s%s\n", http, http->uri->scheme,
653 		http->request.host, http->request.uri );
654 
655 	/* Open connection */
656 	if ( ( rc = http_connect ( &http->conn, uri ) ) != 0 ) {
657 		DBGC ( http, "HTTP %p could not connect: %s\n",
658 		       http, strerror ( rc ) );
659 		goto err_connect;
660 	}
661 
662 	/* Attach to parent interface, mortalise self, and return */
663 	intf_plug_plug ( &http->xfer, xfer );
664 	ref_put ( &http->refcnt );
665 	return 0;
666 
667  err_connect:
668 	http_close ( http, rc );
669 	ref_put ( &http->refcnt );
670  err_alloc:
671 	return rc;
672 }
673 
674 /**
675  * Redirect HTTP transaction
676  *
677  * @v http		HTTP transaction
678  * @v location		New location
679  * @ret rc		Return status code
680  */
http_redirect(struct http_transaction * http,const char * location)681 static int http_redirect ( struct http_transaction *http,
682 			   const char *location ) {
683 	struct uri *location_uri;
684 	struct uri *resolved_uri;
685 	int rc;
686 
687 	DBGC2 ( http, "HTTP %p redirecting to \"%s\"\n", http, location );
688 
689 	/* Parse location URI */
690 	location_uri = parse_uri ( location );
691 	if ( ! location_uri ) {
692 		rc = -ENOMEM;
693 		goto err_parse_uri;
694 	}
695 
696 	/* Resolve as relative to original URI */
697 	resolved_uri = resolve_uri ( http->uri, location_uri );
698 	if ( ! resolved_uri ) {
699 		rc = -ENOMEM;
700 		goto err_resolve_uri;
701 	}
702 
703 	/* Redirect to new URI */
704 	if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI,
705 				    resolved_uri ) ) != 0 ) {
706 		DBGC ( http, "HTTP %p could not redirect: %s\n",
707 		       http, strerror ( rc ) );
708 		goto err_redirect;
709 	}
710 
711  err_redirect:
712 	uri_put ( resolved_uri );
713  err_resolve_uri:
714 	uri_put ( location_uri );
715  err_parse_uri:
716 	return rc;
717 }
718 
719 /**
720  * Handle successful transfer completion
721  *
722  * @v http		HTTP transaction
723  * @ret rc		Return status code
724  */
http_transfer_complete(struct http_transaction * http)725 static int http_transfer_complete ( struct http_transaction *http ) {
726 	struct http_authentication *auth;
727 	const char *location;
728 	int rc;
729 
730 	/* Keep connection alive if applicable */
731 	if ( http->response.flags & HTTP_RESPONSE_KEEPALIVE )
732 		pool_recycle ( &http->conn );
733 
734 	/* Restart server connection interface */
735 	intf_restart ( &http->conn, 0 );
736 
737 	/* No more data is expected */
738 	http->state = NULL;
739 
740 	/* If transaction is successful, then close the
741 	 * transfer-decoded interface.  The content encoding may
742 	 * choose whether or not to immediately terminate the
743 	 * transaction.
744 	 */
745 	if ( http->response.rc == 0 ) {
746 		intf_shutdown ( &http->transfer, 0 );
747 		return 0;
748 	}
749 
750 	/* Perform redirection, if applicable */
751 	if ( ( location = http->response.location ) ) {
752 		if ( ( rc = http_redirect ( http, location ) ) != 0 )
753 			return rc;
754 		http_close ( http, 0 );
755 		return 0;
756 	}
757 
758 	/* Fail unless a retry is permitted */
759 	if ( ! ( http->response.flags & HTTP_RESPONSE_RETRY ) )
760 		return http->response.rc;
761 
762 	/* Perform authentication, if applicable */
763 	if ( ( auth = http->response.auth.auth ) ) {
764 		http->request.auth.auth = auth;
765 		DBGC2 ( http, "HTTP %p performing %s authentication\n",
766 			http, auth->name );
767 		if ( ( rc = auth->authenticate ( http ) ) != 0 ) {
768 			DBGC ( http, "HTTP %p could not authenticate: %s\n",
769 			       http, strerror ( rc ) );
770 			return rc;
771 		}
772 	}
773 
774 	/* Restart content decoding interfaces */
775 	intfs_restart ( http->response.rc, &http->content, &http->transfer,
776 			NULL );
777 	intf_plug_plug ( &http->transfer, &http->content );
778 	http->len = 0;
779 	assert ( http->remaining == 0 );
780 
781 	/* Retry immediately if applicable.  We cannot rely on an
782 	 * immediate timer expiry, since certain Microsoft-designed
783 	 * HTTP extensions such as NTLM break the fundamentally
784 	 * stateless nature of HTTP and rely on the same connection
785 	 * being reused for authentication.  See RFC7230 section 2.3
786 	 * for further details.
787 	 */
788 	if ( ! http->response.retry_after ) {
789 		http_reopen ( http );
790 		return 0;
791 	}
792 
793 	/* Start timer to initiate retry */
794 	DBGC2 ( http, "HTTP %p retrying after %d seconds\n",
795 		http, http->response.retry_after );
796 	start_timer_fixed ( &http->timer,
797 			    ( http->response.retry_after * TICKS_PER_SEC ) );
798 	return 0;
799 }
800 
801 /******************************************************************************
802  *
803  * Requests
804  *
805  ******************************************************************************
806  */
807 
808 /**
809  * Construct HTTP request headers
810  *
811  * @v http		HTTP transaction
812  * @v buf		Buffer
813  * @v len		Length of buffer
814  * @ret len		Length, or negative error
815  */
http_format_headers(struct http_transaction * http,char * buf,size_t len)816 static int http_format_headers ( struct http_transaction *http, char *buf,
817 				 size_t len ) {
818 	struct http_request_header *header;
819 	size_t used;
820 	size_t remaining;
821 	char *line;
822 	int value_len;
823 	int rc;
824 
825 	/* Construct request line */
826 	used = ssnprintf ( buf, len, "%s %s HTTP/1.1",
827 			   http->request.method->name, http->request.uri );
828 	if ( used < len )
829 		DBGC2 ( http, "HTTP %p TX %s\n", http, buf );
830 	used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
831 
832 	/* Construct all headers */
833 	for_each_table_entry ( header, HTTP_REQUEST_HEADERS ) {
834 
835 		/* Determine header value length */
836 		value_len = header->format ( http, NULL, 0 );
837 		if ( value_len < 0 ) {
838 			rc = value_len;
839 			return rc;
840 		}
841 
842 		/* Skip zero-length headers */
843 		if ( ! value_len )
844 			continue;
845 
846 		/* Construct header */
847 		line = ( buf + used );
848 		used += ssnprintf ( ( buf + used ), ( len - used ), "%s: ",
849 				    header->name );
850 		remaining = ( ( used < len ) ? ( len - used ) : 0 );
851 		used += header->format ( http, ( buf + used ), remaining );
852 		if ( used < len )
853 			DBGC2 ( http, "HTTP %p TX %s\n", http, line );
854 		used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
855 	}
856 
857 	/* Construct terminating newline */
858 	used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
859 
860 	return used;
861 }
862 
863 /**
864  * Construct HTTP "Host" header
865  *
866  * @v http		HTTP transaction
867  * @v buf		Buffer
868  * @v len		Length of buffer
869  * @ret len		Length of header value, or negative error
870  */
http_format_host(struct http_transaction * http,char * buf,size_t len)871 static int http_format_host ( struct http_transaction *http, char *buf,
872 			      size_t len ) {
873 
874 	/* Construct host URI */
875 	return snprintf ( buf, len, "%s", http->request.host );
876 }
877 
878 /** HTTP "Host" header "*/
879 struct http_request_header http_request_host __http_request_header = {
880 	.name = "Host",
881 	.format = http_format_host,
882 };
883 
884 /**
885  * Construct HTTP "User-Agent" header
886  *
887  * @v http		HTTP transaction
888  * @v buf		Buffer
889  * @v len		Length of buffer
890  * @ret len		Length of header value, or negative error
891  */
http_format_user_agent(struct http_transaction * http __unused,char * buf,size_t len)892 static int http_format_user_agent ( struct http_transaction *http __unused,
893 				    char *buf, size_t len ) {
894 
895 	/* Construct user agent */
896 	return snprintf ( buf, len, "iPXE/%s", product_version );
897 }
898 
899 /** HTTP "User-Agent" header */
900 struct http_request_header http_request_user_agent __http_request_header = {
901 	.name = "User-Agent",
902 	.format = http_format_user_agent,
903 };
904 
905 /**
906  * Construct HTTP "Connection" header
907  *
908  * @v http		HTTP transaction
909  * @v buf		Buffer
910  * @v len		Length of buffer
911  * @ret len		Length of header value, or negative error
912  */
http_format_connection(struct http_transaction * http __unused,char * buf,size_t len)913 static int http_format_connection ( struct http_transaction *http __unused,
914 				    char *buf, size_t len ) {
915 
916 	/* Always request keep-alive */
917 	return snprintf ( buf, len, "keep-alive" );
918 }
919 
920 /** HTTP "Connection" header */
921 struct http_request_header http_request_connection __http_request_header = {
922 	.name = "Connection",
923 	.format = http_format_connection,
924 };
925 
926 /**
927  * Construct HTTP "Range" header
928  *
929  * @v http		HTTP transaction
930  * @v buf		Buffer
931  * @v len		Length of buffer
932  * @ret len		Length of header value, or negative error
933  */
http_format_range(struct http_transaction * http,char * buf,size_t len)934 static int http_format_range ( struct http_transaction *http,
935 			       char *buf, size_t len ) {
936 
937 	/* Construct range, if applicable */
938 	if ( http->request.range.len ) {
939 		return snprintf ( buf, len, "bytes=%zd-%zd",
940 				  http->request.range.start,
941 				  ( http->request.range.start +
942 				    http->request.range.len - 1 ) );
943 	} else {
944 		return 0;
945 	}
946 }
947 
948 /** HTTP "Range" header */
949 struct http_request_header http_request_range __http_request_header = {
950 	.name = "Range",
951 	.format = http_format_range,
952 };
953 
954 /**
955  * Construct HTTP "Content-Type" header
956  *
957  * @v http		HTTP transaction
958  * @v buf		Buffer
959  * @v len		Length of buffer
960  * @ret len		Length of header value, or negative error
961  */
http_format_content_type(struct http_transaction * http,char * buf,size_t len)962 static int http_format_content_type ( struct http_transaction *http,
963 				      char *buf, size_t len ) {
964 
965 	/* Construct content type, if applicable */
966 	if ( http->request.content.type ) {
967 		return snprintf ( buf, len, "%s", http->request.content.type );
968 	} else {
969 		return 0;
970 	}
971 }
972 
973 /** HTTP "Content-Type" header */
974 struct http_request_header http_request_content_type __http_request_header = {
975 	.name = "Content-Type",
976 	.format = http_format_content_type,
977 };
978 
979 /**
980  * Construct HTTP "Content-Length" header
981  *
982  * @v http		HTTP transaction
983  * @v buf		Buffer
984  * @v len		Length of buffer
985  * @ret len		Length of header value, or negative error
986  */
http_format_content_length(struct http_transaction * http,char * buf,size_t len)987 static int http_format_content_length ( struct http_transaction *http,
988 					char *buf, size_t len ) {
989 
990 	/* Construct content length, if applicable */
991 	if ( http->request.content.len ) {
992 		return snprintf ( buf, len, "%zd", http->request.content.len );
993 	} else {
994 		return 0;
995 	}
996 }
997 
998 /** HTTP "Content-Length" header */
999 struct http_request_header http_request_content_length __http_request_header = {
1000 	.name = "Content-Length",
1001 	.format = http_format_content_length,
1002 };
1003 
1004 /**
1005  * Construct HTTP "Accept-Encoding" header
1006  *
1007  * @v http		HTTP transaction
1008  * @v buf		Buffer
1009  * @v len		Length of buffer
1010  * @ret len		Length of header value, or negative error
1011  */
http_format_accept_encoding(struct http_transaction * http,char * buf,size_t len)1012 static int http_format_accept_encoding ( struct http_transaction *http,
1013 					 char *buf, size_t len ) {
1014 	struct http_content_encoding *encoding;
1015 	const char *sep = "";
1016 	size_t used = 0;
1017 
1018 	/* Construct list of content encodings */
1019 	for_each_table_entry ( encoding, HTTP_CONTENT_ENCODINGS ) {
1020 		if ( encoding->supported && ( ! encoding->supported ( http ) ) )
1021 			continue;
1022 		used += ssnprintf ( ( buf + used ), ( len - used ),
1023 				    "%s%s", sep, encoding->name );
1024 		sep = ", ";
1025 	}
1026 
1027 	return used;
1028 }
1029 
1030 /** HTTP "Accept-Encoding" header */
1031 struct http_request_header http_request_accept_encoding __http_request_header ={
1032 	.name = "Accept-Encoding",
1033 	.format = http_format_accept_encoding,
1034 };
1035 
1036 /**
1037  * Transmit request
1038  *
1039  * @v http		HTTP transaction
1040  * @ret rc		Return status code
1041  */
http_tx_request(struct http_transaction * http)1042 static int http_tx_request ( struct http_transaction *http ) {
1043 	struct io_buffer *iobuf;
1044 	int len;
1045 	int check_len;
1046 	int rc;
1047 
1048 	/* Calculate request length */
1049 	len = http_format_headers ( http, NULL, 0 );
1050 	if ( len < 0 ) {
1051 		rc = len;
1052 		DBGC ( http, "HTTP %p could not construct request: %s\n",
1053 		       http, strerror ( rc ) );
1054 		goto err_len;
1055 	}
1056 
1057 	/* Allocate I/O buffer */
1058 	iobuf = alloc_iob ( len + 1 /* NUL */ + http->request.content.len );
1059 	if ( ! iobuf ) {
1060 		rc = -ENOMEM;
1061 		goto err_alloc;
1062 	}
1063 
1064 	/* Construct request */
1065 	check_len = http_format_headers ( http, iob_put ( iobuf, len ),
1066 					  ( len + 1 /* NUL */ ) );
1067 	assert ( check_len == len );
1068 	memcpy ( iob_put ( iobuf, http->request.content.len ),
1069 		 http->request.content.data, http->request.content.len );
1070 
1071 	/* Deliver request */
1072 	if ( ( rc = xfer_deliver_iob ( &http->conn,
1073 				       iob_disown ( iobuf ) ) ) != 0 ) {
1074 		DBGC ( http, "HTTP %p could not deliver request: %s\n",
1075 		       http, strerror ( rc ) );
1076 		goto err_deliver;
1077 	}
1078 
1079 	/* Clear any previous response */
1080 	empty_line_buffer ( &http->response.headers );
1081 	memset ( &http->response, 0, sizeof ( http->response ) );
1082 
1083 	/* Move to response headers state */
1084 	http->state = &http_headers;
1085 
1086 	return 0;
1087 
1088  err_deliver:
1089 	free_iob ( iobuf );
1090  err_alloc:
1091  err_len:
1092 	return rc;
1093 }
1094 
1095 /** HTTP request state */
1096 static struct http_state http_request = {
1097 	.tx = http_tx_request,
1098 	.close = http_close_error,
1099 };
1100 
1101 /******************************************************************************
1102  *
1103  * Response headers
1104  *
1105  ******************************************************************************
1106  */
1107 
1108 /**
1109  * Parse HTTP status line
1110  *
1111  * @v http		HTTP transaction
1112  * @v line		Status line
1113  * @ret rc		Return status code
1114  */
http_parse_status(struct http_transaction * http,char * line)1115 static int http_parse_status ( struct http_transaction *http, char *line ) {
1116 	char *endp;
1117 	char *version;
1118 	char *vernum;
1119 	char *status;
1120 	int response_rc;
1121 
1122 	DBGC2 ( http, "HTTP %p RX %s\n", http, line );
1123 
1124 	/* Parse HTTP version */
1125 	version = http_token ( &line, NULL );
1126 	if ( ( ! version ) || ( strncmp ( version, "HTTP/", 5 ) != 0 ) ) {
1127 		DBGC ( http, "HTTP %p malformed version \"%s\"\n", http, line );
1128 		return -EINVAL_STATUS;
1129 	}
1130 
1131 	/* Keepalive is enabled by default for anything newer than HTTP/1.0 */
1132 	vernum = ( version + 5 /* "HTTP/" (presence already checked) */ );
1133 	if ( vernum[0] == '0' ) {
1134 		/* HTTP/0.x : keepalive not enabled by default */
1135 	} else if ( strncmp ( vernum, "1.0", 3 ) == 0 ) {
1136 		/* HTTP/1.0 : keepalive not enabled by default */
1137 	} else {
1138 		/* HTTP/1.1 or newer: keepalive enabled by default */
1139 		http->response.flags |= HTTP_RESPONSE_KEEPALIVE;
1140 	}
1141 
1142 	/* Parse status code */
1143 	status = line;
1144 	http->response.status = strtoul ( status, &endp, 10 );
1145 	if ( *endp != ' ' ) {
1146 		DBGC ( http, "HTTP %p malformed status code \"%s\"\n",
1147 		       http, status );
1148 		return -EINVAL_STATUS;
1149 	}
1150 
1151 	/* Convert HTTP status code to iPXE return status code */
1152 	if ( status[0] == '2' ) {
1153 		/* 2xx Success */
1154 		response_rc = 0;
1155 	} else if ( status[0] == '3' ) {
1156 		/* 3xx Redirection */
1157 		response_rc = -EXDEV;
1158 	} else if ( http->response.status == 401 ) {
1159 		/* 401 Unauthorized */
1160 		response_rc = -EACCES_401;
1161 	} else if ( http->response.status == 403 ) {
1162 		/* 403 Forbidden */
1163 		response_rc = -EPERM_403;
1164 	} else if ( http->response.status == 404 ) {
1165 		/* 404 Not Found */
1166 		response_rc = -ENOENT_404;
1167 	} else if ( status[0] == '4' ) {
1168 		/* 4xx Client Error (not already specified) */
1169 		response_rc = -EIO_4XX;
1170 	} else if ( status[0] == '5' ) {
1171 		/* 5xx Server Error */
1172 		response_rc = -EIO_5XX;
1173 	} else {
1174 		/* Unrecognised */
1175 		response_rc = -EIO_OTHER;
1176 	}
1177 	http->response.rc = response_rc;
1178 	if ( response_rc )
1179 		DBGC ( http, "HTTP %p status %s\n", http, status );
1180 
1181 	return 0;
1182 }
1183 
1184 /**
1185  * Parse HTTP header
1186  *
1187  * @v http		HTTP transaction
1188  * @v line		Header line
1189  * @ret rc		Return status code
1190  */
http_parse_header(struct http_transaction * http,char * line)1191 static int http_parse_header ( struct http_transaction *http, char *line ) {
1192 	struct http_response_header *header;
1193 	char *name = line;
1194 	char *sep;
1195 
1196 	DBGC2 ( http, "HTTP %p RX %s\n", http, line );
1197 
1198 	/* Extract header name */
1199 	sep = strchr ( line, ':' );
1200 	if ( ! sep ) {
1201 		DBGC ( http, "HTTP %p malformed header \"%s\"\n", http, line );
1202 		return -EINVAL_HEADER;
1203 	}
1204 	*sep = '\0';
1205 
1206 	/* Extract remainder of line */
1207 	line = ( sep + 1 );
1208 	while ( isspace ( *line ) )
1209 		line++;
1210 
1211 	/* Process header, if recognised */
1212 	for_each_table_entry ( header, HTTP_RESPONSE_HEADERS ) {
1213 		if ( strcasecmp ( name, header->name ) == 0 )
1214 			return header->parse ( http, line );
1215 	}
1216 
1217 	/* Unrecognised headers should be ignored */
1218 	return 0;
1219 }
1220 
1221 /**
1222  * Parse HTTP response headers
1223  *
1224  * @v http		HTTP transaction
1225  * @ret rc		Return status code
1226  */
http_parse_headers(struct http_transaction * http)1227 static int http_parse_headers ( struct http_transaction *http ) {
1228 	char *line;
1229 	char *next;
1230 	int rc;
1231 
1232 	/* Get status line */
1233 	line = http->response.headers.data;
1234 	assert ( line != NULL );
1235 	next = ( line + strlen ( line ) + 1 /* NUL */ );
1236 
1237 	/* Parse status line */
1238 	if ( ( rc = http_parse_status ( http, line ) ) != 0 )
1239 		return rc;
1240 
1241 	/* Process header lines */
1242 	while ( 1 ) {
1243 
1244 		/* Move to next line */
1245 		line = next;
1246 		next = ( line + strlen ( line ) + 1 /* NUL */ );
1247 
1248 		/* Stop on terminating blank line */
1249 		if ( ! line[0] )
1250 			return 0;
1251 
1252 		/* Process header line */
1253 		if ( ( rc = http_parse_header ( http, line ) ) != 0 )
1254 			return rc;
1255 	}
1256 }
1257 
1258 /**
1259  * Parse HTTP "Location" header
1260  *
1261  * @v http		HTTP transaction
1262  * @v line		Remaining header line
1263  * @ret rc		Return status code
1264  */
http_parse_location(struct http_transaction * http,char * line)1265 static int http_parse_location ( struct http_transaction *http, char *line ) {
1266 
1267 	/* Store location */
1268 	http->response.location = line;
1269 	return 0;
1270 }
1271 
1272 /** HTTP "Location" header */
1273 struct http_response_header http_response_location __http_response_header = {
1274 	.name = "Location",
1275 	.parse = http_parse_location,
1276 };
1277 
1278 /**
1279  * Parse HTTP "Transfer-Encoding" header
1280  *
1281  * @v http		HTTP transaction
1282  * @v line		Remaining header line
1283  * @ret rc		Return status code
1284  */
http_parse_transfer_encoding(struct http_transaction * http,char * line)1285 static int http_parse_transfer_encoding ( struct http_transaction *http,
1286 					  char *line ) {
1287 	struct http_transfer_encoding *encoding;
1288 
1289 	/* Check for known transfer encodings */
1290 	for_each_table_entry ( encoding, HTTP_TRANSFER_ENCODINGS ) {
1291 		if ( strcasecmp ( line, encoding->name ) == 0 ) {
1292 			http->response.transfer.encoding = encoding;
1293 			return 0;
1294 		}
1295 	}
1296 
1297 	DBGC ( http, "HTTP %p unrecognised Transfer-Encoding \"%s\"\n",
1298 	       http, line );
1299 	return -ENOTSUP_TRANSFER;
1300 }
1301 
1302 /** HTTP "Transfer-Encoding" header */
1303 struct http_response_header
1304 http_response_transfer_encoding __http_response_header = {
1305 	.name = "Transfer-Encoding",
1306 	.parse = http_parse_transfer_encoding,
1307 };
1308 
1309 /**
1310  * Parse HTTP "Connection" header
1311  *
1312  * @v http		HTTP transaction
1313  * @v line		Remaining header line
1314  * @ret rc		Return status code
1315  */
http_parse_connection(struct http_transaction * http,char * line)1316 static int http_parse_connection ( struct http_transaction *http, char *line ) {
1317 	char *token;
1318 
1319 	/* Check for known connection intentions */
1320 	while ( ( token = http_token ( &line, NULL ) ) ) {
1321 		if ( strcasecmp ( token, "keep-alive" ) == 0 )
1322 			http->response.flags |= HTTP_RESPONSE_KEEPALIVE;
1323 		if ( strcasecmp ( token, "close" ) == 0 )
1324 			http->response.flags &= ~HTTP_RESPONSE_KEEPALIVE;
1325 	}
1326 
1327 	return 0;
1328 }
1329 
1330 /** HTTP "Connection" header */
1331 struct http_response_header http_response_connection __http_response_header = {
1332 	.name = "Connection",
1333 	.parse = http_parse_connection,
1334 };
1335 
1336 /**
1337  * Parse HTTP "Content-Length" header
1338  *
1339  * @v http		HTTP transaction
1340  * @v line		Remaining header line
1341  * @ret rc		Return status code
1342  */
http_parse_content_length(struct http_transaction * http,char * line)1343 static int http_parse_content_length ( struct http_transaction *http,
1344 				       char *line ) {
1345 	char *endp;
1346 
1347 	/* Parse length */
1348 	http->response.content.len = strtoul ( line, &endp, 10 );
1349 	if ( *endp != '\0' ) {
1350 		DBGC ( http, "HTTP %p invalid Content-Length \"%s\"\n",
1351 		       http, line );
1352 		return -EINVAL_CONTENT_LENGTH;
1353 	}
1354 
1355 	/* Record that we have a content length (since it may be zero) */
1356 	http->response.flags |= HTTP_RESPONSE_CONTENT_LEN;
1357 
1358 	return 0;
1359 }
1360 
1361 /** HTTP "Content-Length" header */
1362 struct http_response_header
1363 http_response_content_length __http_response_header = {
1364 	.name = "Content-Length",
1365 	.parse = http_parse_content_length,
1366 };
1367 
1368 /**
1369  * Parse HTTP "Content-Encoding" header
1370  *
1371  * @v http		HTTP transaction
1372  * @v line		Remaining header line
1373  * @ret rc		Return status code
1374  */
http_parse_content_encoding(struct http_transaction * http,char * line)1375 static int http_parse_content_encoding ( struct http_transaction *http,
1376 					 char *line ) {
1377 	struct http_content_encoding *encoding;
1378 
1379 	/* Check for known content encodings */
1380 	for_each_table_entry ( encoding, HTTP_CONTENT_ENCODINGS ) {
1381 		if ( encoding->supported && ( ! encoding->supported ( http ) ) )
1382 			continue;
1383 		if ( strcasecmp ( line, encoding->name ) == 0 ) {
1384 			http->response.content.encoding = encoding;
1385 			return 0;
1386 		}
1387 	}
1388 
1389 	/* Some servers (e.g. Apache) have a habit of specifying
1390 	 * unwarranted content encodings.  For example, if Apache
1391 	 * detects (via /etc/httpd/conf/magic) that a file's contents
1392 	 * are gzip-compressed, it will set "Content-Encoding: x-gzip"
1393 	 * regardless of the client's Accept-Encoding header.  The
1394 	 * only viable way to handle such servers is to treat unknown
1395 	 * content encodings as equivalent to "identity".
1396 	 */
1397 	DBGC ( http, "HTTP %p unrecognised Content-Encoding \"%s\"\n",
1398 	       http, line );
1399 	return 0;
1400 }
1401 
1402 /** HTTP "Content-Encoding" header */
1403 struct http_response_header
1404 http_response_content_encoding __http_response_header = {
1405 	.name = "Content-Encoding",
1406 	.parse = http_parse_content_encoding,
1407 };
1408 
1409 /**
1410  * Parse HTTP "Retry-After" header
1411  *
1412  * @v http		HTTP transaction
1413  * @v line		Remaining header line
1414  * @ret rc		Return status code
1415  */
http_parse_retry_after(struct http_transaction * http,char * line)1416 static int http_parse_retry_after ( struct http_transaction *http,
1417 				    char *line ) {
1418 	char *endp;
1419 
1420 	/* Try to parse value as a simple number of seconds */
1421 	http->response.retry_after = strtoul ( line, &endp, 10 );
1422 	if ( *endp != '\0' ) {
1423 		/* For any value which is not a simple number of
1424 		 * seconds (e.g. a full HTTP date), just retry after a
1425 		 * fixed delay, since we don't have code able to parse
1426 		 * full HTTP dates.
1427 		 */
1428 		http->response.retry_after = HTTP_RETRY_SECONDS;
1429 		DBGC ( http, "HTTP %p cannot understand Retry-After \"%s\"; "
1430 		       "using %d seconds\n", http, line, HTTP_RETRY_SECONDS );
1431 	}
1432 
1433 	/* Allow HTTP request to be retried after specified delay */
1434 	http->response.flags |= HTTP_RESPONSE_RETRY;
1435 
1436 	return 0;
1437 }
1438 
1439 /** HTTP "Retry-After" header */
1440 struct http_response_header http_response_retry_after __http_response_header = {
1441 	.name = "Retry-After",
1442 	.parse = http_parse_retry_after,
1443 };
1444 
1445 /**
1446  * Handle received HTTP headers
1447  *
1448  * @v http		HTTP transaction
1449  * @v iobuf		I/O buffer (may be claimed)
1450  * @ret rc		Return status code
1451  */
http_rx_headers(struct http_transaction * http,struct io_buffer ** iobuf)1452 static int http_rx_headers ( struct http_transaction *http,
1453 			     struct io_buffer **iobuf ) {
1454 	struct http_transfer_encoding *transfer;
1455 	struct http_content_encoding *content;
1456 	char *line;
1457 	int rc;
1458 
1459 	/* Buffer header line */
1460 	if ( ( rc = http_rx_linebuf ( http, *iobuf,
1461 				      &http->response.headers ) ) != 0 )
1462 		return rc;
1463 
1464 	/* Wait until we see the empty line marking end of headers */
1465 	line = buffered_line ( &http->response.headers );
1466 	if ( ( line == NULL ) || ( line[0] != '\0' ) )
1467 		return 0;
1468 
1469 	/* Process headers */
1470 	if ( ( rc = http_parse_headers ( http ) ) != 0 )
1471 		return rc;
1472 
1473 	/* Initialise content encoding, if applicable */
1474 	if ( ( content = http->response.content.encoding ) &&
1475 	     ( ( rc = content->init ( http ) ) != 0 ) ) {
1476 		DBGC ( http, "HTTP %p could not initialise %s content "
1477 		       "encoding: %s\n", http, content->name, strerror ( rc ) );
1478 		return rc;
1479 	}
1480 
1481 	/* Presize receive buffer, if we have a content length */
1482 	if ( http->response.content.len ) {
1483 		xfer_seek ( &http->transfer, http->response.content.len );
1484 		xfer_seek ( &http->transfer, 0 );
1485 	}
1486 
1487 	/* Complete transfer if this is a HEAD request */
1488 	if ( http->request.method == &http_head ) {
1489 		if ( ( rc = http_transfer_complete ( http ) ) != 0 )
1490 			return rc;
1491 		return 0;
1492 	}
1493 
1494 	/* Default to identity transfer encoding, if none specified */
1495 	if ( ! http->response.transfer.encoding )
1496 		http->response.transfer.encoding = &http_transfer_identity;
1497 
1498 	/* Move to transfer encoding-specific data state */
1499 	transfer = http->response.transfer.encoding;
1500 	http->state = &transfer->state;
1501 
1502 	/* Initialise transfer encoding */
1503 	if ( ( rc = transfer->init ( http ) ) != 0 ) {
1504 		DBGC ( http, "HTTP %p could not initialise %s transfer "
1505 		       "encoding: %s\n", http, transfer->name, strerror ( rc ));
1506 		return rc;
1507 	}
1508 
1509 	return 0;
1510 }
1511 
1512 /** HTTP response headers state */
1513 static struct http_state http_headers = {
1514 	.rx = http_rx_headers,
1515 	.close = http_close_error,
1516 };
1517 
1518 /******************************************************************************
1519  *
1520  * Identity transfer encoding
1521  *
1522  ******************************************************************************
1523  */
1524 
1525 /**
1526  * Initialise transfer encoding
1527  *
1528  * @v http		HTTP transaction
1529  * @ret rc		Return status code
1530  */
http_init_transfer_identity(struct http_transaction * http)1531 static int http_init_transfer_identity ( struct http_transaction *http ) {
1532 	int rc;
1533 
1534 	/* Complete transfer immediately if we have a zero content length */
1535 	if ( ( http->response.flags & HTTP_RESPONSE_CONTENT_LEN ) &&
1536 	     ( http->response.content.len == 0 ) &&
1537 	     ( ( rc = http_transfer_complete ( http ) ) != 0 ) )
1538 		return rc;
1539 
1540 	return 0;
1541 }
1542 
1543 /**
1544  * Handle received data
1545  *
1546  * @v http		HTTP transaction
1547  * @v iobuf		I/O buffer (may be claimed)
1548  * @ret rc		Return status code
1549  */
http_rx_transfer_identity(struct http_transaction * http,struct io_buffer ** iobuf)1550 static int http_rx_transfer_identity ( struct http_transaction *http,
1551 				       struct io_buffer **iobuf ) {
1552 	size_t len = iob_len ( *iobuf );
1553 	int rc;
1554 
1555 	/* Update lengths */
1556 	http->len += len;
1557 
1558 	/* Fail if this transfer would overrun the expected content
1559 	 * length (if any).
1560 	 */
1561 	if ( ( http->response.flags & HTTP_RESPONSE_CONTENT_LEN ) &&
1562 	     ( http->len > http->response.content.len ) ) {
1563 		DBGC ( http, "HTTP %p content length overrun\n", http );
1564 		return -EIO_CONTENT_LENGTH;
1565 	}
1566 
1567 	/* Hand off to content encoding */
1568 	if ( ( rc = xfer_deliver_iob ( &http->transfer,
1569 				       iob_disown ( *iobuf ) ) ) != 0 )
1570 		return rc;
1571 
1572 	/* Complete transfer if we have received the expected content
1573 	 * length (if any).
1574 	 */
1575 	if ( ( http->response.flags & HTTP_RESPONSE_CONTENT_LEN ) &&
1576 	     ( http->len == http->response.content.len ) &&
1577 	     ( ( rc = http_transfer_complete ( http ) ) != 0 ) )
1578 		return rc;
1579 
1580 	return 0;
1581 }
1582 
1583 /**
1584  * Handle server connection close
1585  *
1586  * @v http		HTTP transaction
1587  * @v rc		Reason for close
1588  */
http_close_transfer_identity(struct http_transaction * http,int rc)1589 static void http_close_transfer_identity ( struct http_transaction *http,
1590 					   int rc ) {
1591 
1592 	/* Fail if any error occurred */
1593 	if ( rc != 0 )
1594 		goto err;
1595 
1596 	/* Fail if we have a content length (since we would have
1597 	 * already closed the connection if we had received the
1598 	 * correct content length).
1599 	 */
1600 	if ( http->response.flags & HTTP_RESPONSE_CONTENT_LEN ) {
1601 		DBGC ( http, "HTTP %p content length underrun\n", http );
1602 		rc = EIO_CONTENT_LENGTH;
1603 		goto err;
1604 	}
1605 
1606 	/* Indicate that transfer is complete */
1607 	if ( ( rc = http_transfer_complete ( http ) ) != 0 )
1608 		goto err;
1609 
1610 	return;
1611 
1612  err:
1613 	http_close ( http, rc );
1614 }
1615 
1616 /** Identity transfer encoding */
1617 static struct http_transfer_encoding http_transfer_identity = {
1618 	.name = "identity",
1619 	.init = http_init_transfer_identity,
1620 	.state = {
1621 		.rx = http_rx_transfer_identity,
1622 		.close = http_close_transfer_identity,
1623 	},
1624 };
1625 
1626 /******************************************************************************
1627  *
1628  * Chunked transfer encoding
1629  *
1630  ******************************************************************************
1631  */
1632 
1633 /**
1634  * Initialise transfer encoding
1635  *
1636  * @v http		HTTP transaction
1637  * @ret rc		Return status code
1638  */
http_init_transfer_chunked(struct http_transaction * http)1639 static int http_init_transfer_chunked ( struct http_transaction *http ) {
1640 
1641 	/* Sanity checks */
1642 	assert ( http->remaining == 0 );
1643 	assert ( http->linebuf.len == 0 );
1644 
1645 	return 0;
1646 }
1647 
1648 /**
1649  * Handle received chunk length
1650  *
1651  * @v http		HTTP transaction
1652  * @v iobuf		I/O buffer (may be claimed)
1653  * @ret rc		Return status code
1654  */
http_rx_chunk_len(struct http_transaction * http,struct io_buffer ** iobuf)1655 static int http_rx_chunk_len ( struct http_transaction *http,
1656 			       struct io_buffer **iobuf ) {
1657 	char *line;
1658 	char *endp;
1659 	size_t len;
1660 	int rc;
1661 
1662 	/* Receive into temporary line buffer */
1663 	if ( ( rc = http_rx_linebuf ( http, *iobuf, &http->linebuf ) ) != 0 )
1664 		return rc;
1665 
1666 	/* Wait until we receive a non-empty line */
1667 	line = buffered_line ( &http->linebuf );
1668 	if ( ( line == NULL ) || ( line[0] == '\0' ) )
1669 		return 0;
1670 
1671 	/* Parse chunk length */
1672 	http->remaining = strtoul ( line, &endp, 16 );
1673 	if ( *endp != '\0' ) {
1674 		DBGC ( http, "HTTP %p invalid chunk length \"%s\"\n",
1675 		       http, line );
1676 		return -EINVAL_CHUNK_LENGTH;
1677 	}
1678 
1679 	/* Empty line buffer */
1680 	empty_line_buffer ( &http->linebuf );
1681 
1682 	/* Update expected length */
1683 	len = ( http->len + http->remaining );
1684 	xfer_seek ( &http->transfer, len );
1685 	xfer_seek ( &http->transfer, http->len );
1686 
1687 	/* If chunk length is zero, then move to response trailers state */
1688 	if ( ! http->remaining )
1689 		http->state = &http_trailers;
1690 
1691 	return 0;
1692 }
1693 
1694 /**
1695  * Handle received chunk data
1696  *
1697  * @v http		HTTP transaction
1698  * @v iobuf		I/O buffer (may be claimed)
1699  * @ret rc		Return status code
1700  */
http_rx_chunk_data(struct http_transaction * http,struct io_buffer ** iobuf)1701 static int http_rx_chunk_data ( struct http_transaction *http,
1702 				struct io_buffer **iobuf ) {
1703 	struct io_buffer *payload;
1704 	uint8_t *crlf;
1705 	size_t len;
1706 	int rc;
1707 
1708 	/* In the common case of a final chunk in a packet which also
1709 	 * includes the terminating CRLF, strip the terminating CRLF
1710 	 * (which we would ignore anyway) and hence avoid
1711 	 * unnecessarily copying the data.
1712 	 */
1713 	if ( iob_len ( *iobuf ) == ( http->remaining + 2 /* CRLF */ ) ) {
1714 		crlf = ( (*iobuf)->data + http->remaining );
1715 		if ( ( crlf[0] == '\r' ) && ( crlf[1] == '\n' ) )
1716 			iob_unput ( (*iobuf), 2 /* CRLF */ );
1717 	}
1718 	len = iob_len ( *iobuf );
1719 
1720 	/* Use whole/partial buffer as applicable */
1721 	if ( len <= http->remaining ) {
1722 
1723 		/* Whole buffer is to be consumed: decrease remaining
1724 		 * length and use original I/O buffer as payload.
1725 		 */
1726 		payload = iob_disown ( *iobuf );
1727 		http->len += len;
1728 		http->remaining -= len;
1729 
1730 	} else {
1731 
1732 		/* Partial buffer is to be consumed: copy data to a
1733 		 * temporary I/O buffer.
1734 		 */
1735 		payload = alloc_iob ( http->remaining );
1736 		if ( ! payload ) {
1737 			rc = -ENOMEM;
1738 			goto err;
1739 		}
1740 		memcpy ( iob_put ( payload, http->remaining ), (*iobuf)->data,
1741 			 http->remaining );
1742 		iob_pull ( *iobuf, http->remaining );
1743 		http->len += http->remaining;
1744 		http->remaining = 0;
1745 	}
1746 
1747 	/* Hand off to content encoding */
1748 	if ( ( rc = xfer_deliver_iob ( &http->transfer,
1749 				       iob_disown ( payload ) ) ) != 0 )
1750 		goto err;
1751 
1752 	return 0;
1753 
1754  err:
1755 	assert ( payload == NULL );
1756 	return rc;
1757 }
1758 
1759 /**
1760  * Handle received chunked data
1761  *
1762  * @v http		HTTP transaction
1763  * @v iobuf		I/O buffer (may be claimed)
1764  * @ret rc		Return status code
1765  */
http_rx_transfer_chunked(struct http_transaction * http,struct io_buffer ** iobuf)1766 static int http_rx_transfer_chunked ( struct http_transaction *http,
1767 				      struct io_buffer **iobuf ) {
1768 
1769 	/* Handle as chunk length or chunk data as appropriate */
1770 	if ( http->remaining ) {
1771 		return http_rx_chunk_data ( http, iobuf );
1772 	} else {
1773 		return http_rx_chunk_len ( http, iobuf );
1774 	}
1775 }
1776 
1777 /** Chunked transfer encoding */
1778 struct http_transfer_encoding http_transfer_chunked __http_transfer_encoding = {
1779 	.name = "chunked",
1780 	.init = http_init_transfer_chunked,
1781 	.state = {
1782 		.rx = http_rx_transfer_chunked,
1783 		.close = http_close_error,
1784 	},
1785 };
1786 
1787 /******************************************************************************
1788  *
1789  * Response trailers
1790  *
1791  ******************************************************************************
1792  */
1793 
1794 /**
1795  * Handle received HTTP trailer
1796  *
1797  * @v http		HTTP transaction
1798  * @v iobuf		I/O buffer (may be claimed)
1799  * @ret rc		Return status code
1800  */
http_rx_trailers(struct http_transaction * http,struct io_buffer ** iobuf)1801 static int http_rx_trailers ( struct http_transaction *http,
1802 			      struct io_buffer **iobuf ) {
1803 	char *line;
1804 	int rc;
1805 
1806 	/* Buffer trailer line */
1807 	if ( ( rc = http_rx_linebuf ( http, *iobuf, &http->linebuf ) ) != 0 )
1808 		return rc;
1809 
1810 	/* Wait until we see the empty line marking end of trailers */
1811 	line = buffered_line ( &http->linebuf );
1812 	if ( ( line == NULL ) || ( line[0] != '\0' ) )
1813 		return 0;
1814 
1815 	/* Empty line buffer */
1816 	empty_line_buffer ( &http->linebuf );
1817 
1818 	/* Transfer is complete */
1819 	if ( ( rc = http_transfer_complete ( http ) ) != 0 )
1820 		return rc;
1821 
1822 	return 0;
1823 }
1824 
1825 /** HTTP response trailers state */
1826 static struct http_state http_trailers = {
1827 	.rx = http_rx_trailers,
1828 	.close = http_close_error,
1829 };
1830 
1831 /******************************************************************************
1832  *
1833  * Simple URI openers
1834  *
1835  ******************************************************************************
1836  */
1837 
1838 /**
1839  * Construct HTTP parameter list
1840  *
1841  * @v params		Parameter list
1842  * @v buf		Buffer to contain HTTP POST parameters
1843  * @v len		Length of buffer
1844  * @ret len		Length of parameter list (excluding terminating NUL)
1845  */
http_params(struct parameters * params,char * buf,size_t len)1846 static size_t http_params ( struct parameters *params, char *buf, size_t len ) {
1847 	struct parameter *param;
1848 	ssize_t remaining = len;
1849 	size_t frag_len;
1850 
1851 	/* Add each parameter in the form "key=value", joined with "&" */
1852 	len = 0;
1853 	for_each_param ( param, params ) {
1854 
1855 		/* Add the "&", if applicable */
1856 		if ( len ) {
1857 			if ( remaining > 0 )
1858 				*buf = '&';
1859 			buf++;
1860 			len++;
1861 			remaining--;
1862 		}
1863 
1864 		/* URI-encode the key */
1865 		frag_len = uri_encode_string ( 0, param->key, buf, remaining );
1866 		buf += frag_len;
1867 		len += frag_len;
1868 		remaining -= frag_len;
1869 
1870 		/* Add the "=" */
1871 		if ( remaining > 0 )
1872 			*buf = '=';
1873 		buf++;
1874 		len++;
1875 		remaining--;
1876 
1877 		/* URI-encode the value */
1878 		frag_len = uri_encode_string ( 0, param->value, buf, remaining);
1879 		buf += frag_len;
1880 		len += frag_len;
1881 		remaining -= frag_len;
1882 	}
1883 
1884 	/* Ensure string is NUL-terminated even if no parameters are present */
1885 	if ( remaining > 0 )
1886 		*buf = '\0';
1887 
1888 	return len;
1889 }
1890 
1891 /**
1892  * Open HTTP transaction for simple GET URI
1893  *
1894  * @v xfer		Data transfer interface
1895  * @v uri		Request URI
1896  * @ret rc		Return status code
1897  */
http_open_get_uri(struct interface * xfer,struct uri * uri)1898 static int http_open_get_uri ( struct interface *xfer, struct uri *uri ) {
1899 
1900 	return http_open ( xfer, &http_get, uri, NULL, NULL );
1901 }
1902 
1903 /**
1904  * Open HTTP transaction for simple POST URI
1905  *
1906  * @v xfer		Data transfer interface
1907  * @v uri		Request URI
1908  * @ret rc		Return status code
1909  */
http_open_post_uri(struct interface * xfer,struct uri * uri)1910 static int http_open_post_uri ( struct interface *xfer, struct uri *uri ) {
1911 	struct parameters *params = uri->params;
1912 	struct http_request_content content;
1913 	void *data;
1914 	size_t len;
1915 	size_t check_len;
1916 	int rc;
1917 
1918 	/* Calculate length of parameter list */
1919 	len = http_params ( params, NULL, 0 );
1920 
1921 	/* Allocate temporary parameter list */
1922 	data = zalloc ( len + 1 /* NUL */ );
1923 	if ( ! data ) {
1924 		rc = -ENOMEM;
1925 		goto err_alloc;
1926 	}
1927 
1928 	/* Construct temporary parameter list */
1929 	check_len = http_params ( params, data, ( len + 1 /* NUL */ ) );
1930 	assert ( check_len == len );
1931 
1932 	/* Construct request content */
1933 	content.type = "application/x-www-form-urlencoded";
1934 	content.data = data;
1935 	content.len = len;
1936 
1937 	/* Open HTTP transaction */
1938 	if ( ( rc = http_open ( xfer, &http_post, uri, NULL, &content ) ) != 0 )
1939 		goto err_open;
1940 
1941  err_open:
1942 	free ( data );
1943  err_alloc:
1944 	return rc;
1945 }
1946 
1947 /**
1948  * Open HTTP transaction for simple URI
1949  *
1950  * @v xfer		Data transfer interface
1951  * @v uri		Request URI
1952  * @ret rc		Return status code
1953  */
http_open_uri(struct interface * xfer,struct uri * uri)1954 int http_open_uri ( struct interface *xfer, struct uri *uri ) {
1955 
1956 	/* Open GET/POST URI as applicable */
1957 	if ( uri->params ) {
1958 		return http_open_post_uri ( xfer, uri );
1959 	} else {
1960 		return http_open_get_uri ( xfer, uri );
1961 	}
1962 }
1963 
1964 /* Drag in HTTP extensions */
1965 REQUIRING_SYMBOL ( http_open );
1966 REQUIRE_OBJECT ( config_http );
1967