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