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