iPXE
httpcore.c File Reference

Hyper Text Transfer Protocol (HTTP) core functionality. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <byteswap.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <ipxe/uri.h>
#include <ipxe/refcnt.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/process.h>
#include <ipxe/retry.h>
#include <ipxe/timer.h>
#include <ipxe/linebuf.h>
#include <ipxe/xferbuf.h>
#include <ipxe/blockdev.h>
#include <ipxe/acpi.h>
#include <ipxe/version.h>
#include <ipxe/params.h>
#include <ipxe/profile.h>
#include <ipxe/vsprintf.h>
#include <ipxe/errortab.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/http.h>

Go to the source code of this file.

Macros

#define EACCES_401   __einfo_error ( EINFO_EACCES_401 )
#define EINFO_EACCES_401   __einfo_uniqify ( EINFO_EACCES, 0x01, "HTTP 401 Unauthorized" )
#define EINVAL_STATUS   __einfo_error ( EINFO_EINVAL_STATUS )
#define EINFO_EINVAL_STATUS   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid status line" )
#define EINVAL_HEADER   __einfo_error ( EINFO_EINVAL_HEADER )
#define EINFO_EINVAL_HEADER   __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid header" )
#define EINVAL_CONTENT_LENGTH   __einfo_error ( EINFO_EINVAL_CONTENT_LENGTH )
#define EINFO_EINVAL_CONTENT_LENGTH   __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid content length" )
#define EINVAL_CHUNK_LENGTH   __einfo_error ( EINFO_EINVAL_CHUNK_LENGTH )
#define EINFO_EINVAL_CHUNK_LENGTH   __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid chunk length" )
#define EIO_OTHER   __einfo_error ( EINFO_EIO_OTHER )
#define EINFO_EIO_OTHER   __einfo_uniqify ( EINFO_EIO, 0x01, "Unrecognised HTTP response code" )
#define EIO_CONTENT_LENGTH   __einfo_error ( EINFO_EIO_CONTENT_LENGTH )
#define EINFO_EIO_CONTENT_LENGTH   __einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )
#define EIO_4XX   __einfo_error ( EINFO_EIO_4XX )
#define EINFO_EIO_4XX   __einfo_uniqify ( EINFO_EIO, 0x04, "HTTP 4xx Client Error" )
#define EIO_5XX   __einfo_error ( EINFO_EIO_5XX )
#define EINFO_EIO_5XX   __einfo_uniqify ( EINFO_EIO, 0x05, "HTTP 5xx Server Error" )
#define ENOENT_404   __einfo_error ( EINFO_ENOENT_404 )
#define EINFO_ENOENT_404   __einfo_uniqify ( EINFO_ENOENT, 0x01, "Not found" )
#define ENOTSUP_CONNECTION   __einfo_error ( EINFO_ENOTSUP_CONNECTION )
#define EINFO_ENOTSUP_CONNECTION   __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported connection header" )
#define ENOTSUP_TRANSFER   __einfo_error ( EINFO_ENOTSUP_TRANSFER )
#define EINFO_ENOTSUP_TRANSFER   __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported transfer encoding" )
#define EPERM_403   __einfo_error ( EINFO_EPERM_403 )
#define EINFO_EPERM_403   __einfo_uniqify ( EINFO_EPERM, 0x01, "HTTP 403 Forbidden" )
#define EPROTO_UNSOLICITED   __einfo_error ( EINFO_EPROTO_UNSOLICITED )
#define EINFO_EPROTO_UNSOLICITED   __einfo_uniqify ( EINFO_EPROTO, 0x01, "Unsolicited data" )
#define HTTP_RETRY_SECONDS   5
 Retry delay used when we cannot understand the Retry-After header.
#define HTTP_WATCHDOG_SECONDS   120
 Idle connection watchdog timeout.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static struct http_method * http_method (const char *name)
 Identify HTTP method.
static int http_rx_linebuf (struct http_transaction *http, struct io_buffer *iobuf, struct line_buffer *linebuf)
 Handle received HTTP line-buffered data.
char * http_token (char **line, char **value)
 Get HTTP response token.
static void http_free (struct refcnt *refcnt)
 Free HTTP transaction.
static void http_close (struct http_transaction *http, int rc)
 Close HTTP transaction.
static void http_close_error (struct http_transaction *http, int rc)
 Close HTTP transaction with error (even if none specified).
static void http_watchdog (struct http_transaction *http)
 Hold off HTTP idle connection watchdog timer.
static void http_reopen (struct http_transaction *http)
 Reopen stale HTTP connection.
static void http_retry_expired (struct retry_timer *retry, int over __unused)
 Handle connection retry timer expiry.
static void http_watchdog_expired (struct retry_timer *watchdog, int over __unused)
 Handle idle connection watchdog timer expiry.
static void http_step (struct http_transaction *http)
 HTTP transmit process.
static int http_conn_deliver (struct http_transaction *http, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Handle received HTTP data.
static void http_conn_close (struct http_transaction *http, int rc)
 Handle server connection close.
static int http_content_deliver (struct http_transaction *http, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Handle received content-decoded data.
static struct xfer_bufferhttp_content_buffer (struct http_transaction *http)
 Get underlying data transfer buffer.
__weak int http_block_read (struct http_transaction *http __unused, struct interface *data __unused, uint64_t lba __unused, unsigned int count __unused, void *buffer __unused, size_t len __unused)
 Read from block device (when HTTP block device support is not present).
__weak int http_block_read_capacity (struct http_transaction *http __unused, struct interface *data __unused)
 Read block device capacity (when HTTP block device support is not present).
static EFI_DEVICE_PATH_PROTOCOLhttp_efi_describe (struct http_transaction *http)
 Describe as an EFI device path.
int http_open (struct interface *xfer, struct http_method *method, struct uri *uri, struct http_request_range *range, struct http_request_content *content)
 Open HTTP transaction.
static int http_redirect (struct http_transaction *http, const char *location)
 Redirect HTTP transaction.
static int http_transfer_complete (struct http_transaction *http)
 Handle successful transfer completion.
static int http_format_headers (struct http_transaction *http, char *buf, size_t len)
 Construct HTTP request headers.
static int http_format_host (struct http_transaction *http, char *buf, size_t len)
 Construct HTTP "Host" header.
static int http_format_user_agent (struct http_transaction *http __unused, char *buf, size_t len)
 Construct HTTP "User-Agent" header.
static int http_format_connection (struct http_transaction *http __unused, char *buf, size_t len)
 Construct HTTP "Connection" header.
static int http_format_range (struct http_transaction *http, char *buf, size_t len)
 Construct HTTP "Range" header.
static int http_format_content_type (struct http_transaction *http, char *buf, size_t len)
 Construct HTTP "Content-Type" header.
static int http_format_content_length (struct http_transaction *http, char *buf, size_t len)
 Construct HTTP "Content-Length" header.
static int http_format_accept_encoding (struct http_transaction *http, char *buf, size_t len)
 Construct HTTP "Accept-Encoding" header.
static int http_tx_request (struct http_transaction *http)
 Transmit request.
static int http_parse_status (struct http_transaction *http, char *line)
 Parse HTTP status line.
static int http_parse_header (struct http_transaction *http, char *line)
 Parse HTTP header.
static int http_parse_headers (struct http_transaction *http)
 Parse HTTP response headers.
static int http_parse_location (struct http_transaction *http, char *line)
 Parse HTTP "Location" header.
static int http_parse_transfer_encoding (struct http_transaction *http, char *line)
 Parse HTTP "Transfer-Encoding" header.
static int http_parse_connection (struct http_transaction *http, char *line)
 Parse HTTP "Connection" header.
static int http_parse_content_length (struct http_transaction *http, char *line)
 Parse HTTP "Content-Length" header.
static int http_parse_content_encoding (struct http_transaction *http, char *line)
 Parse HTTP "Content-Encoding" header.
static int http_parse_retry_after (struct http_transaction *http, char *line)
 Parse HTTP "Retry-After" header.
static int http_rx_headers (struct http_transaction *http, struct io_buffer **iobuf)
 Handle received HTTP headers.
static int http_init_transfer_identity (struct http_transaction *http)
 Initialise transfer encoding.
static int http_rx_transfer_identity (struct http_transaction *http, struct io_buffer **iobuf)
 Handle received data.
static void http_close_transfer_identity (struct http_transaction *http, int rc)
 Handle server connection close.
static int http_init_transfer_chunked (struct http_transaction *http)
 Initialise transfer encoding.
static int http_rx_chunk_len (struct http_transaction *http, struct io_buffer **iobuf)
 Handle received chunk length.
static int http_rx_chunk_data (struct http_transaction *http, struct io_buffer **iobuf)
 Handle received chunk data.
static int http_rx_transfer_chunked (struct http_transaction *http, struct io_buffer **iobuf)
 Handle received chunked data.
static int http_rx_trailers (struct http_transaction *http, struct io_buffer **iobuf)
 Handle received HTTP trailer.
static size_t http_form_params (struct parameters *params, char *buf, size_t len)
 Construct HTTP form parameter list.
int http_open_uri (struct interface *xfer, struct uri *uri)
 Open HTTP transaction for simple URI.
 REQUIRING_SYMBOL (http_open)
 REQUIRE_OBJECT (config_http)

Variables

static struct profiler http_rx_profiler __profiler = { .name = "http.rx" }
 Receive profiler.
struct errortab http_errors[] __errortab
 Human-readable error messages.
static struct http_state http_request
 HTTP request state.
static struct http_state http_headers
 HTTP response headers state.
static struct http_state http_trailers
 HTTP response trailers state.
static struct http_transfer_encoding http_transfer_identity
 Identity transfer encoding.
struct http_method http_head __http_method
 HTTP HEAD method.
static struct interface_operation http_xfer_operations []
 HTTP data transfer interface operations.
static struct interface_descriptor http_xfer_desc
 HTTP data transfer interface descriptor.
static struct interface_operation http_content_operations []
 HTTP content-decoded interface operations.
static struct interface_descriptor http_content_desc
 HTTP content-decoded interface descriptor.
static struct interface_operation http_transfer_operations []
 HTTP transfer-decoded interface operations.
static struct interface_descriptor http_transfer_desc
 HTTP transfer-decoded interface descriptor.
static struct interface_operation http_conn_operations []
 HTTP server connection interface operations.
static struct interface_descriptor http_conn_desc
 HTTP server connection interface descriptor.
static struct process_descriptor http_process_desc
 HTTP process descriptor.
struct http_request_header http_request_host __http_request_header
 HTTP "Host" header ".
struct http_response_header http_response_location __http_response_header
 HTTP "Location" header.
struct http_transfer_encoding http_transfer_chunked __http_transfer_encoding
 Chunked transfer encoding.

Detailed Description

Hyper Text Transfer Protocol (HTTP) core functionality.

Definition in file httpcore.c.

Macro Definition Documentation

◆ EACCES_401

#define EACCES_401   __einfo_error ( EINFO_EACCES_401 )

Definition at line 64 of file httpcore.c.

Referenced by http_parse_status().

◆ EINFO_EACCES_401

#define EINFO_EACCES_401   __einfo_uniqify ( EINFO_EACCES, 0x01, "HTTP 401 Unauthorized" )

Definition at line 65 of file httpcore.c.

65#define EINFO_EACCES_401 \
66 __einfo_uniqify ( EINFO_EACCES, 0x01, "HTTP 401 Unauthorized" )

◆ EINVAL_STATUS

#define EINVAL_STATUS   __einfo_error ( EINFO_EINVAL_STATUS )

Definition at line 67 of file httpcore.c.

Referenced by http_parse_status().

◆ EINFO_EINVAL_STATUS

#define EINFO_EINVAL_STATUS   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid status line" )

Definition at line 68 of file httpcore.c.

68#define EINFO_EINVAL_STATUS \
69 __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid status line" )

◆ EINVAL_HEADER

#define EINVAL_HEADER   __einfo_error ( EINFO_EINVAL_HEADER )

Definition at line 70 of file httpcore.c.

Referenced by http_parse_header().

◆ EINFO_EINVAL_HEADER

#define EINFO_EINVAL_HEADER   __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid header" )

Definition at line 71 of file httpcore.c.

71#define EINFO_EINVAL_HEADER \
72 __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid header" )

◆ EINVAL_CONTENT_LENGTH

#define EINVAL_CONTENT_LENGTH   __einfo_error ( EINFO_EINVAL_CONTENT_LENGTH )

Definition at line 73 of file httpcore.c.

Referenced by http_parse_content_length().

◆ EINFO_EINVAL_CONTENT_LENGTH

#define EINFO_EINVAL_CONTENT_LENGTH   __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid content length" )

Definition at line 74 of file httpcore.c.

74#define EINFO_EINVAL_CONTENT_LENGTH \
75 __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid content length" )

◆ EINVAL_CHUNK_LENGTH

#define EINVAL_CHUNK_LENGTH   __einfo_error ( EINFO_EINVAL_CHUNK_LENGTH )

Definition at line 76 of file httpcore.c.

Referenced by http_rx_chunk_len().

◆ EINFO_EINVAL_CHUNK_LENGTH

#define EINFO_EINVAL_CHUNK_LENGTH   __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid chunk length" )

Definition at line 77 of file httpcore.c.

77#define EINFO_EINVAL_CHUNK_LENGTH \
78 __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid chunk length" )

◆ EIO_OTHER

#define EIO_OTHER   __einfo_error ( EINFO_EIO_OTHER )

Definition at line 79 of file httpcore.c.

Referenced by http_parse_status().

◆ EINFO_EIO_OTHER

#define EINFO_EIO_OTHER   __einfo_uniqify ( EINFO_EIO, 0x01, "Unrecognised HTTP response code" )

Definition at line 80 of file httpcore.c.

80#define EINFO_EIO_OTHER \
81 __einfo_uniqify ( EINFO_EIO, 0x01, "Unrecognised HTTP response code" )

◆ EIO_CONTENT_LENGTH

#define EIO_CONTENT_LENGTH   __einfo_error ( EINFO_EIO_CONTENT_LENGTH )

Definition at line 82 of file httpcore.c.

Referenced by http_close_transfer_identity(), and http_rx_transfer_identity().

◆ EINFO_EIO_CONTENT_LENGTH

#define EINFO_EIO_CONTENT_LENGTH   __einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )

Definition at line 83 of file httpcore.c.

83#define EINFO_EIO_CONTENT_LENGTH \
84 __einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )

◆ EIO_4XX

#define EIO_4XX   __einfo_error ( EINFO_EIO_4XX )

Definition at line 85 of file httpcore.c.

Referenced by http_parse_status().

◆ EINFO_EIO_4XX

#define EINFO_EIO_4XX   __einfo_uniqify ( EINFO_EIO, 0x04, "HTTP 4xx Client Error" )

Definition at line 86 of file httpcore.c.

86#define EINFO_EIO_4XX \
87 __einfo_uniqify ( EINFO_EIO, 0x04, "HTTP 4xx Client Error" )

◆ EIO_5XX

#define EIO_5XX   __einfo_error ( EINFO_EIO_5XX )

Definition at line 88 of file httpcore.c.

Referenced by http_parse_status().

◆ EINFO_EIO_5XX

#define EINFO_EIO_5XX   __einfo_uniqify ( EINFO_EIO, 0x05, "HTTP 5xx Server Error" )

Definition at line 89 of file httpcore.c.

89#define EINFO_EIO_5XX \
90 __einfo_uniqify ( EINFO_EIO, 0x05, "HTTP 5xx Server Error" )

◆ ENOENT_404

#define ENOENT_404   __einfo_error ( EINFO_ENOENT_404 )

Definition at line 91 of file httpcore.c.

Referenced by http_parse_status().

◆ EINFO_ENOENT_404

#define EINFO_ENOENT_404   __einfo_uniqify ( EINFO_ENOENT, 0x01, "Not found" )

Definition at line 92 of file httpcore.c.

92#define EINFO_ENOENT_404 \
93 __einfo_uniqify ( EINFO_ENOENT, 0x01, "Not found" )

◆ ENOTSUP_CONNECTION

#define ENOTSUP_CONNECTION   __einfo_error ( EINFO_ENOTSUP_CONNECTION )

Definition at line 94 of file httpcore.c.

◆ EINFO_ENOTSUP_CONNECTION

#define EINFO_ENOTSUP_CONNECTION   __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported connection header" )

Definition at line 95 of file httpcore.c.

95#define EINFO_ENOTSUP_CONNECTION \
96 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported connection header" )

◆ ENOTSUP_TRANSFER

#define ENOTSUP_TRANSFER   __einfo_error ( EINFO_ENOTSUP_TRANSFER )

Definition at line 97 of file httpcore.c.

Referenced by http_parse_transfer_encoding().

◆ EINFO_ENOTSUP_TRANSFER

#define EINFO_ENOTSUP_TRANSFER   __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported transfer encoding" )

Definition at line 98 of file httpcore.c.

98#define EINFO_ENOTSUP_TRANSFER \
99 __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported transfer encoding" )

◆ EPERM_403

#define EPERM_403   __einfo_error ( EINFO_EPERM_403 )

Definition at line 100 of file httpcore.c.

Referenced by http_parse_status().

◆ EINFO_EPERM_403

#define EINFO_EPERM_403   __einfo_uniqify ( EINFO_EPERM, 0x01, "HTTP 403 Forbidden" )

Definition at line 101 of file httpcore.c.

101#define EINFO_EPERM_403 \
102 __einfo_uniqify ( EINFO_EPERM, 0x01, "HTTP 403 Forbidden" )

◆ EPROTO_UNSOLICITED

#define EPROTO_UNSOLICITED   __einfo_error ( EINFO_EPROTO_UNSOLICITED )

Definition at line 103 of file httpcore.c.

Referenced by http_conn_deliver().

◆ EINFO_EPROTO_UNSOLICITED

#define EINFO_EPROTO_UNSOLICITED   __einfo_uniqify ( EINFO_EPROTO, 0x01, "Unsolicited data" )

Definition at line 104 of file httpcore.c.

104#define EINFO_EPROTO_UNSOLICITED \
105 __einfo_uniqify ( EINFO_EPROTO, 0x01, "Unsolicited data" )

◆ HTTP_RETRY_SECONDS

#define HTTP_RETRY_SECONDS   5

Retry delay used when we cannot understand the Retry-After header.

Definition at line 108 of file httpcore.c.

Referenced by http_parse_retry_after().

◆ HTTP_WATCHDOG_SECONDS

#define HTTP_WATCHDOG_SECONDS   120

Idle connection watchdog timeout.

Definition at line 111 of file httpcore.c.

Referenced by http_watchdog().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ http_method()

struct http_method * http_method ( const char * name)
static

Identify HTTP method.

Parameters
nameMethod name
Return values
methodHTTP method, or NULL if not known

Definition at line 164 of file httpcore.c.

164 {
165 struct http_method *method;
166
167 /* Identify method */
169 if ( strcasecmp ( name, method->name ) == 0 )
170 return method;
171 }
172
173 return NULL;
174}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
const char * name
Definition ath9k_hw.c:1986
#define HTTP_METHODS
HTTP method table.
Definition http.h:106
uint8_t method
Definition ib_mad.h:3
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition string.c:209
An HTTP method.
Definition http.h:100
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386

References for_each_table_entry, HTTP_METHODS, method, name, NULL, and strcasecmp().

Referenced by http_open_uri().

◆ http_rx_linebuf()

int http_rx_linebuf ( struct http_transaction * http,
struct io_buffer * iobuf,
struct line_buffer * linebuf )
static

Handle received HTTP line-buffered data.

Parameters
httpHTTP transaction
iobufI/O buffer
linebufLine buffer
Return values
rcReturn status code

Definition at line 191 of file httpcore.c.

193 {
194 int consumed;
195 int rc;
196
197 /* Buffer received line */
198 consumed = line_buffer ( linebuf, iobuf->data, iob_len ( iobuf ) );
199 if ( consumed < 0 ) {
200 rc = consumed;
201 DBGC ( http, "HTTP %p could not buffer line: %s\n",
202 http, strerror ( rc ) );
203 return rc;
204 }
205
206 /* Consume line */
207 iob_pull ( iobuf, consumed );
208
209 return 0;
210}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC(...)
Definition compiler.h:530
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
int line_buffer(struct line_buffer *linebuf, const char *data, size_t len)
Buffer up received data by lines.
Definition linebuf.c:92
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
void * data
Start of data.
Definition iobuf.h:53

References io_buffer::data, DBGC, iob_len(), iob_pull, line_buffer(), rc, and strerror().

Referenced by http_rx_chunk_len(), http_rx_headers(), and http_rx_trailers().

◆ http_token()

char * http_token ( char ** line,
char ** value )

Get HTTP response token.

Parameters
lineLine position
valueToken value to fill in (if any)
Return values
tokenToken, or NULL

Definition at line 219 of file httpcore.c.

219 {
220 char *token;
221 char quote = '\0';
222 char c;
223
224 /* Avoid returning uninitialised data */
225 if ( value )
226 *value = NULL;
227
228 /* Skip any initial whitespace or commas */
229 while ( ( isspace ( **line ) ) || ( **line == ',' ) )
230 (*line)++;
231
232 /* Check for end of line and record token position */
233 if ( ! **line )
234 return NULL;
235 token = *line;
236
237 /* Scan for end of token */
238 while ( ( c = **line ) ) {
239
240 /* Terminate if we hit an unquoted whitespace or comma */
241 if ( ( isspace ( c ) || ( c == ',' ) ) && ! quote )
242 break;
243
244 /* Terminate if we hit a closing quote */
245 if ( c == quote )
246 break;
247
248 /* Check for value separator */
249 if ( value && ( ! *value ) && ( c == '=' ) ) {
250
251 /* Terminate key portion of token */
252 *((*line)++) = '\0';
253
254 /* Check for quote character */
255 c = **line;
256 if ( ( c == '"' ) || ( c == '\'' ) ) {
257 quote = c;
258 (*line)++;
259 }
260
261 /* Record value portion of token */
262 *value = *line;
263
264 } else {
265
266 /* Move to next character */
267 (*line)++;
268 }
269 }
270
271 /* Terminate token, if applicable */
272 if ( c )
273 *((*line)++) = '\0';
274
275 return token;
276}
u8 token
Definition CIB_PRM.h:14
pseudo_bit_t value[0x00020]
Definition arbel.h:2
int isspace(int character)
Check to see if character is a space.
Definition ctype.c:42

References isspace(), NULL, token, and value.

Referenced by http_parse_connection(), http_parse_digest_auth(), http_parse_status(), and http_parse_www_authenticate().

◆ http_free()

void http_free ( struct refcnt * refcnt)
static

Free HTTP transaction.

Parameters
refcntReference count

Definition at line 290 of file httpcore.c.

290 {
291 struct http_transaction *http =
293
295 empty_line_buffer ( &http->linebuf );
296 uri_put ( http->uri );
297 free ( http );
298}
void empty_line_buffer(struct line_buffer *linebuf)
Discard line buffer contents.
Definition linebuf.c:66
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
struct line_buffer headers
Raw response header lines.
Definition http.h:335
An HTTP transaction.
Definition http.h:423
struct http_response response
Response.
Definition http.h:446
struct uri * uri
Request URI.
Definition http.h:442
struct line_buffer linebuf
Temporary line buffer.
Definition http.h:448
A reference counter.
Definition refcnt.h:27
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition uri.h:206

References container_of, empty_line_buffer(), free, http_response::headers, http_transaction::linebuf, http_transaction::response, http_transaction::uri, and uri_put().

Referenced by http_open().

◆ http_close()

void http_close ( struct http_transaction * http,
int rc )
static

Close HTTP transaction.

Parameters
httpHTTP transaction
rcReason for close

Definition at line 306 of file httpcore.c.

306 {
307
308 /* Stop process */
309 process_del ( &http->process );
310
311 /* Stop timers */
312 stop_timer ( &http->retry );
313 stop_timer ( &http->watchdog );
314
315 /* Close all interfaces */
316 intfs_shutdown ( rc, &http->conn, &http->transfer, &http->content,
317 &http->xfer, NULL );
318}
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
Definition interface.c:327
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition retry.c:118
struct retry_timer watchdog
Idle connection watchdog timer.
Definition http.h:439
struct process process
Transmit process.
Definition http.h:435
struct retry_timer retry
Reconnection timer.
Definition http.h:437
struct interface conn
Server connection.
Definition http.h:433
struct interface transfer
Transfer-decoded interface.
Definition http.h:431
struct interface content
Content-decoded interface.
Definition http.h:429
struct interface xfer
Data transfer interface.
Definition http.h:427

References http_transaction::conn, http_transaction::content, intfs_shutdown(), NULL, http_transaction::process, process_del(), rc, http_transaction::retry, stop_timer(), http_transaction::transfer, http_transaction::watchdog, and http_transaction::xfer.

Referenced by http_close_error(), http_close_transfer_identity(), http_conn_deliver(), http_open(), http_reopen(), http_step(), http_transfer_complete(), and http_watchdog_expired().

◆ http_close_error()

void http_close_error ( struct http_transaction * http,
int rc )
static

Close HTTP transaction with error (even if none specified).

Parameters
httpHTTP transaction
rcReason for close

Definition at line 326 of file httpcore.c.

326 {
327
328 /* Treat any close as an error */
329 http_close ( http, ( rc ? rc : -EPIPE ) );
330}
#define EPIPE
Broken pipe.
Definition errno.h:620
static void http_close(struct http_transaction *http, int rc)
Close HTTP transaction.
Definition httpcore.c:306

References EPIPE, http_close(), and rc.

◆ http_watchdog()

void http_watchdog ( struct http_transaction * http)
inlinestatic

Hold off HTTP idle connection watchdog timer.

Parameters
httpHTTP transaction

Definition at line 337 of file httpcore.c.

337 {
338
339 /* (Re)start watchdog timer */
342}
#define HTTP_WATCHDOG_SECONDS
Idle connection watchdog timeout.
Definition httpcore.c:111
#define TICKS_PER_SEC
Number of ticks per second.
Definition timer.h:16
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition retry.c:65

References HTTP_WATCHDOG_SECONDS, start_timer_fixed(), TICKS_PER_SEC, and http_transaction::watchdog.

Referenced by http_content_deliver(), http_open(), and http_reopen().

◆ http_reopen()

void http_reopen ( struct http_transaction * http)
static

Reopen stale HTTP connection.

Parameters
httpHTTP transaction

Definition at line 349 of file httpcore.c.

349 {
350 int rc;
351
352 /* Close existing connection */
353 intf_restart ( &http->conn, -ECANCELED );
354
355 /* Reopen connection */
356 if ( ( rc = http_connect ( &http->conn, http->uri ) ) != 0 ) {
357 DBGC ( http, "HTTP %p could not reconnect: %s\n",
358 http, strerror ( rc ) );
359 goto err_connect;
360 }
361
362 /* Reset state */
363 http->state = &http_request;
364
365 /* Restart idle connection watchdog timer */
366 http_watchdog ( http );
367
368 /* Reschedule transmission process */
369 process_add ( &http->process );
370
371 return;
372
373 err_connect:
374 http_close ( http, rc );
375}
#define ECANCELED
Operation canceled.
Definition errno.h:344
int http_connect(struct interface *xfer, struct uri *uri)
Connect to an HTTP server.
Definition httpconn.c:237
static void http_watchdog(struct http_transaction *http)
Hold off HTTP idle connection watchdog timer.
Definition httpcore.c:337
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
An HTTP request.
Definition http.h:218
struct http_state * state
Transaction state.
Definition http.h:451

References http_transaction::conn, DBGC, ECANCELED, http_close(), http_connect(), http_watchdog(), intf_restart(), http_transaction::process, process_add(), rc, http_transaction::state, strerror(), and http_transaction::uri.

Referenced by http_retry_expired(), and http_transfer_complete().

◆ http_retry_expired()

void http_retry_expired ( struct retry_timer * retry,
int over __unused )
static

Handle connection retry timer expiry.

Parameters
retryRetry timer
overFailure indicator

Definition at line 383 of file httpcore.c.

384 {
385 struct http_transaction *http =
387
388 /* Reopen connection */
389 http_reopen ( http );
390}
static void http_reopen(struct http_transaction *http)
Reopen stale HTTP connection.
Definition httpcore.c:349

References __unused, container_of, http_reopen(), and http_transaction::retry.

Referenced by http_open().

◆ http_watchdog_expired()

void http_watchdog_expired ( struct retry_timer * watchdog,
int over __unused )
static

Handle idle connection watchdog timer expiry.

Parameters
watchdogIdle connection watchdog timer
overFailure indicator

Definition at line 398 of file httpcore.c.

399 {
400 struct http_transaction *http =
402
403 /* Abort connection */
404 DBGC ( http, "HTTP %p aborting idle connection\n", http );
405 http_close ( http, -ETIMEDOUT );
406}
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670

References __unused, container_of, DBGC, ETIMEDOUT, http_close(), and http_transaction::watchdog.

Referenced by http_open().

◆ http_step()

void http_step ( struct http_transaction * http)
static

HTTP transmit process.

Parameters
httpHTTP transaction

Definition at line 413 of file httpcore.c.

413 {
414 int rc;
415
416 /* Do nothing if we have nothing to transmit */
417 if ( ! http->state->tx )
418 return;
419
420 /* Do nothing until connection is ready */
421 if ( ! xfer_window ( &http->conn ) )
422 return;
423
424 /* Notify data transfer interface that window may have changed */
425 xfer_window_changed ( &http->xfer );
426
427 /* Do nothing until data transfer interface is ready */
428 if ( ! xfer_window ( &http->xfer ) )
429 return;
430
431 /* Transmit data */
432 if ( ( rc = http->state->tx ( http ) ) != 0 )
433 goto err;
434
435 return;
436
437 err:
438 http_close ( http, rc );
439}
int(* tx)(struct http_transaction *http)
Transmit data.
Definition http.h:405
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

References http_transaction::conn, http_close(), rc, http_transaction::state, http_state::tx, http_transaction::xfer, xfer_window(), and xfer_window_changed().

◆ http_conn_deliver()

int http_conn_deliver ( struct http_transaction * http,
struct io_buffer * iobuf,
struct xfer_metadata *meta __unused )
static

Handle received HTTP data.

Parameters
httpHTTP transaction
iobufI/O buffer
metaTransfer metadata
Return values
rcReturn status code

This function takes ownership of the I/O buffer.

Definition at line 451 of file httpcore.c.

453 {
454 int rc;
455
456 /* Handle received data */
457 profile_start ( &http_rx_profiler );
458 while ( iobuf && iob_len ( iobuf ) ) {
459
460 /* Sanity check */
461 if ( ( ! http->state ) || ( ! http->state->rx ) ) {
462 DBGC ( http, "HTTP %p unexpected data\n", http );
464 goto err;
465 }
466
467 /* Receive (some) data */
468 if ( ( rc = http->state->rx ( http, &iobuf ) ) != 0 )
469 goto err;
470 }
471
472 /* Free I/O buffer, if applicable */
473 free_iob ( iobuf );
474
475 profile_stop ( &http_rx_profiler );
476 return 0;
477
478 err:
479 free_iob ( iobuf );
480 http_close ( http, rc );
481 return rc;
482}
#define EPROTO_UNSOLICITED
Definition httpcore.c:103
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition profile.h:174
static void profile_start(struct profiler *profiler)
Start profiling.
Definition profile.h:161
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
int(* rx)(struct http_transaction *http, struct io_buffer **iobuf)
Receive data.
Definition http.h:412

References __unused, DBGC, EPROTO_UNSOLICITED, free_iob(), http_close(), iob_len(), meta, profile_start(), profile_stop(), rc, http_state::rx, and http_transaction::state.

◆ http_conn_close()

void http_conn_close ( struct http_transaction * http,
int rc )
static

Handle server connection close.

Parameters
httpHTTP transaction
rcReason for close

Definition at line 490 of file httpcore.c.

490 {
491
492 /* Sanity checks */
493 assert ( http->state != NULL );
494 assert ( http->state->close != NULL );
495
496 /* Restart server connection interface */
497 intf_restart ( &http->conn, rc );
498
499 /* Hand off to state-specific method */
500 http->state->close ( http, rc );
501}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
void(* close)(struct http_transaction *http, int rc)
Server connection closed.
Definition http.h:419

References assert, http_state::close, http_transaction::conn, intf_restart(), NULL, rc, and http_transaction::state.

◆ http_content_deliver()

int http_content_deliver ( struct http_transaction * http,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Handle received content-decoded data.

Parameters
httpHTTP transaction
iobufI/O buffer
metaData transfer metadata

Definition at line 510 of file httpcore.c.

512 {
513 int rc;
514
515 /* Ignore content if this is anything other than a successful
516 * transfer.
517 */
518 if ( http->response.rc != 0 ) {
519 free_iob ( iobuf );
520 return 0;
521 }
522
523 /* Hold off idle connection watchdog timer */
524 http_watchdog ( http );
525
526 /* Deliver to data transfer interface */
527 profile_start ( &http_xfer_profiler );
528 if ( ( rc = xfer_deliver ( &http->xfer, iob_disown ( iobuf ),
529 meta ) ) != 0 )
530 return rc;
531 profile_stop ( &http_xfer_profiler );
532
533 return 0;
534}
uint8_t meta
Metadata flags.
Definition ena.h:3
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
int rc
Return status code.
Definition http.h:346
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195

References free_iob(), http_watchdog(), iob_disown, meta, profile_start(), profile_stop(), http_response::rc, rc, http_transaction::response, http_transaction::xfer, and xfer_deliver().

◆ http_content_buffer()

struct xfer_buffer * http_content_buffer ( struct http_transaction * http)
static

Get underlying data transfer buffer.

Parameters
httpHTTP transaction
Return values
xferbufData transfer buffer, or NULL on error

Definition at line 543 of file httpcore.c.

543 {
544
545 /* Deny access to the data transfer buffer if this is anything
546 * other than a successful transfer.
547 */
548 if ( http->response.rc != 0 )
549 return NULL;
550
551 /* Hand off to data transfer interface */
552 return xfer_buffer ( &http->xfer );
553}
struct xfer_buffer * xfer_buffer(struct interface *intf)
Get underlying data transfer buffer.
Definition xferbuf.c:352

References NULL, http_response::rc, http_transaction::response, http_transaction::xfer, and xfer_buffer().

◆ http_block_read()

__weak int http_block_read ( struct http_transaction *http __unused,
struct interface *data __unused,
uint64_t lba __unused,
unsigned int count __unused,
void *buffer __unused,
size_t len __unused )

Read from block device (when HTTP block device support is not present).

Parameters
httpHTTP transaction
dataData interface
lbaStarting logical block address
countNumber of logical blocks
bufferData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 566 of file httpcore.c.

569 {
570
571 return -ENOTSUP;
572}
#define ENOTSUP
Operation not supported.
Definition errno.h:590

References __unused, __weak, buffer, count, data, ENOTSUP, lba, and len.

◆ http_block_read_capacity()

__weak int http_block_read_capacity ( struct http_transaction *http __unused,
struct interface *data __unused )

Read block device capacity (when HTTP block device support is not present).

Parameters
controlControl interface
dataData interface
Return values
rcReturn status code

Definition at line 581 of file httpcore.c.

582 {
583
584 return -ENOTSUP;
585}

References __unused, __weak, data, and ENOTSUP.

◆ http_efi_describe()

EFI_DEVICE_PATH_PROTOCOL * http_efi_describe ( struct http_transaction * http)
static

Describe as an EFI device path.

Parameters
httpHTTP transaction
Return values
pathEFI device path, or NULL on error

Definition at line 594 of file httpcore.c.

594 {
595
596 return efi_uri_path ( http->uri );
597}
EFI_DEVICE_PATH_PROTOCOL * efi_uri_path(struct uri *uri)
Construct EFI device path for URI.
Definition efi_path.c:494

References efi_uri_path(), and http_transaction::uri.

◆ http_open()

int http_open ( struct interface * xfer,
struct http_method * method,
struct uri * uri,
struct http_request_range * range,
struct http_request_content * content )

Open HTTP transaction.

Parameters
xferData transfer interface
methodRequest method
uriRequest URI
rangeContent range (if any)
contentRequest content (if any)
Return values
rcReturn status code

Definition at line 665 of file httpcore.c.

667 {
668 struct http_transaction *http;
669 struct uri request_uri;
670 struct uri request_host;
671 size_t request_uri_len;
672 size_t request_host_len;
673 size_t content_len;
674 char *request_uri_string;
675 char *request_host_string;
676 void *content_data;
677 int rc;
678
679 /* Calculate request URI length */
680 memset ( &request_uri, 0, sizeof ( request_uri ) );
681 request_uri.epath = ( uri->epath ? uri->epath : "/" );
682 request_uri.equery = uri->equery;
683 request_uri_len =
684 ( format_uri ( &request_uri, NULL, 0 ) + 1 /* NUL */);
685
686 /* Calculate host name length */
687 memset ( &request_host, 0, sizeof ( request_host ) );
688 request_host.host = uri->host;
689 request_host.port = uri->port;
690 request_host_len =
691 ( format_uri ( &request_host, NULL, 0 ) + 1 /* NUL */ );
692
693 /* Calculate request content length */
694 content_len = ( content ? content->len : 0 );
695
696 /* Allocate and initialise structure */
697 http = zalloc ( sizeof ( *http ) + request_uri_len + request_host_len +
698 content_len );
699 if ( ! http ) {
700 rc = -ENOMEM;
701 goto err_alloc;
702 }
703 request_uri_string = ( ( ( void * ) http ) + sizeof ( *http ) );
704 request_host_string = ( request_uri_string + request_uri_len );
705 content_data = ( request_host_string + request_host_len );
706 format_uri ( &request_uri, request_uri_string, request_uri_len );
707 format_uri ( &request_host, request_host_string, request_host_len );
708 ref_init ( &http->refcnt, http_free );
709 intf_init ( &http->xfer, &http_xfer_desc, &http->refcnt );
710 intf_init ( &http->content, &http_content_desc, &http->refcnt );
711 intf_init ( &http->transfer, &http_transfer_desc, &http->refcnt );
712 intf_init ( &http->conn, &http_conn_desc, &http->refcnt );
713 intf_plug_plug ( &http->transfer, &http->content );
714 process_init ( &http->process, &http_process_desc, &http->refcnt );
715 timer_init ( &http->retry, http_retry_expired, &http->refcnt );
716 timer_init ( &http->watchdog, http_watchdog_expired, &http->refcnt );
717 http->uri = uri_get ( uri );
718 http->request.method = method;
719 http->request.uri = request_uri_string;
720 http->request.host = request_host_string;
721 if ( range ) {
722 memcpy ( &http->request.range, range,
723 sizeof ( http->request.range ) );
724 }
725 if ( content ) {
726 http->request.content.type = content->type;
727 http->request.content.data = content_data;
728 http->request.content.len = content_len;
729 memcpy ( content_data, content->data, content_len );
730 }
731 http->state = &http_request;
732 DBGC2 ( http, "HTTP %p %s://%s%s\n", http, http->uri->scheme,
733 http->request.host, http->request.uri );
734
735 /* Open connection */
736 if ( ( rc = http_connect ( &http->conn, uri ) ) != 0 ) {
737 DBGC ( http, "HTTP %p could not connect: %s\n",
738 http, strerror ( rc ) );
739 goto err_connect;
740 }
741
742 /* Start watchdog timer */
743 http_watchdog ( http );
744
745 /* Attach to parent interface, mortalise self, and return */
746 intf_plug_plug ( &http->xfer, xfer );
747 ref_put ( &http->refcnt );
748 return 0;
749
750 err_connect:
751 http_close ( http, rc );
752 ref_put ( &http->refcnt );
753 err_alloc:
754 return rc;
755}
#define DBGC2(...)
Definition compiler.h:547
#define ENOMEM
Not enough space.
Definition errno.h:535
static struct interface_descriptor http_xfer_desc
HTTP data transfer interface descriptor.
Definition httpcore.c:611
static struct process_descriptor http_process_desc
HTTP process descriptor.
Definition httpcore.c:652
static void http_watchdog_expired(struct retry_timer *watchdog, int over __unused)
Handle idle connection watchdog timer expiry.
Definition httpcore.c:398
static void http_free(struct refcnt *refcnt)
Free HTTP transaction.
Definition httpcore.c:290
static struct interface_descriptor http_conn_desc
HTTP server connection interface descriptor.
Definition httpcore.c:647
static struct interface_descriptor http_content_desc
HTTP content-decoded interface descriptor.
Definition httpcore.c:624
static void http_retry_expired(struct retry_timer *retry, int over __unused)
Handle connection retry timer expiry.
Definition httpcore.c:383
static struct interface_descriptor http_transfer_desc
HTTP transfer-decoded interface descriptor.
Definition httpcore.c:634
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
struct pci_range range
PCI bus:dev.fn address range.
Definition pcicloud.c:40
static void process_init(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process and add to process list.
Definition process.h:162
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
size_t len
Content length.
Definition http.h:157
const void * data
Content data (if any).
Definition http.h:155
const char * type
Content type (if any).
Definition http.h:153
struct http_request_range range
Range descriptor.
Definition http.h:226
const char * host
Server host name.
Definition http.h:224
struct http_method * method
Method.
Definition http.h:220
const char * uri
Request URI string.
Definition http.h:222
struct http_request_content content
Content descriptor.
Definition http.h:228
struct refcnt refcnt
Reference count.
Definition http.h:425
struct http_request request
Request.
Definition http.h:444
A Uniform Resource Identifier.
Definition uri.h:65
const char * epath
Path (with original URI encoding).
Definition uri.h:83
const char * host
Host name.
Definition uri.h:77
const char * scheme
Scheme.
Definition uri.h:69
const char * equery
Query (with original URI encoding).
Definition uri.h:85
const char * port
Port number.
Definition uri.h:79
size_t format_uri(const struct uri *uri, char *buf, size_t len)
Format URI.
Definition uri.c:473
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition uri.h:195

References http_transaction::conn, http_request::content, http_transaction::content, http_request_content::data, DBGC, DBGC2, ENOMEM, uri::epath, uri::equery, format_uri(), http_request::host, uri::host, http_close(), http_conn_desc, http_connect(), http_content_desc, http_free(), http_process_desc, http_retry_expired(), http_transfer_desc, http_watchdog(), http_watchdog_expired(), http_xfer_desc, intf_init(), intf_plug_plug(), http_request_content::len, memcpy(), memset(), http_request::method, method, NULL, uri::port, http_transaction::process, process_init(), http_request::range, range, rc, ref_init, ref_put, http_transaction::refcnt, http_transaction::request, http_transaction::retry, uri::scheme, http_transaction::state, strerror(), http_transaction::transfer, http_request_content::type, http_request::uri, http_transaction::uri, uri_get(), http_transaction::watchdog, http_transaction::xfer, and zalloc().

Referenced by http_block_read(), http_block_read_capacity(), http_open_uri(), peerblk_raw_open(), peerblk_retrieval_open(), and REQUIRING_SYMBOL().

◆ http_redirect()

int http_redirect ( struct http_transaction * http,
const char * location )
static

Redirect HTTP transaction.

Parameters
httpHTTP transaction
locationNew location
Return values
rcReturn status code

Definition at line 764 of file httpcore.c.

765 {
766 struct uri *location_uri;
767 struct uri *resolved_uri;
768 int rc;
769
770 DBGC2 ( http, "HTTP %p redirecting to \"%s\"\n", http, location );
771
772 /* Parse location URI */
773 location_uri = parse_uri ( location );
774 if ( ! location_uri ) {
775 rc = -ENOMEM;
776 goto err_parse_uri;
777 }
778
779 /* Resolve as relative to original URI */
780 resolved_uri = resolve_uri ( http->uri, location_uri );
781 if ( ! resolved_uri ) {
782 rc = -ENOMEM;
783 goto err_resolve_uri;
784 }
785
786 /* Redirect to new URI */
787 if ( ( rc = xfer_redirect ( &http->xfer, LOCATION_URI,
788 resolved_uri ) ) != 0 ) {
789 DBGC ( http, "HTTP %p could not redirect: %s\n",
790 http, strerror ( rc ) );
791 goto err_redirect;
792 }
793
794 err_redirect:
795 uri_put ( resolved_uri );
796 err_resolve_uri:
797 uri_put ( location_uri );
798 err_parse_uri:
799 return rc;
800}
@ LOCATION_URI
Location is a URI.
Definition open.h:28
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition uri.c:297
struct uri * resolve_uri(const struct uri *base_uri, struct uri *relative_uri)
Resolve base+relative URI.
Definition uri.c:696
int xfer_redirect(struct interface *intf, int type,...)
Send redirection event.
Definition xfer.c:239

References DBGC, DBGC2, ENOMEM, LOCATION_URI, parse_uri(), rc, resolve_uri(), strerror(), http_transaction::uri, uri_put(), http_transaction::xfer, and xfer_redirect().

Referenced by http_transfer_complete().

◆ http_transfer_complete()

int http_transfer_complete ( struct http_transaction * http)
static

Handle successful transfer completion.

Parameters
httpHTTP transaction
Return values
rcReturn status code

Definition at line 808 of file httpcore.c.

808 {
809 struct http_authentication *auth;
810 const char *location;
811 int rc;
812
813 /* Keep connection alive if applicable */
815 pool_recycle ( &http->conn );
816
817 /* Restart server connection interface */
818 intf_restart ( &http->conn, 0 );
819
820 /* No more data is expected */
821 http->state = NULL;
822
823 /* If transaction is successful, then close the
824 * transfer-decoded interface. The content encoding may
825 * choose whether or not to immediately terminate the
826 * transaction.
827 */
828 if ( http->response.rc == 0 ) {
829 intf_shutdown ( &http->transfer, 0 );
830 return 0;
831 }
832
833 /* Perform redirection, if applicable */
834 if ( ( location = http->response.location ) ) {
835 if ( ( rc = http_redirect ( http, location ) ) != 0 )
836 return rc;
837 http_close ( http, 0 );
838 return 0;
839 }
840
841 /* Fail unless a retry is permitted */
842 if ( ! ( http->response.flags & HTTP_RESPONSE_RETRY ) )
843 return http->response.rc;
844
845 /* Perform authentication, if applicable */
846 if ( ( auth = http->response.auth.auth ) ) {
847 http->request.auth.auth = auth;
848 DBGC2 ( http, "HTTP %p performing %s authentication\n",
849 http, auth->name );
850 if ( ( rc = auth->authenticate ( http ) ) != 0 ) {
851 DBGC ( http, "HTTP %p could not authenticate: %s\n",
852 http, strerror ( rc ) );
853 return rc;
854 }
855 }
856
857 /* Restart content decoding interfaces */
858 intfs_restart ( http->response.rc, &http->content, &http->transfer,
859 NULL );
860 intf_plug_plug ( &http->transfer, &http->content );
861 http->len = 0;
862 assert ( http->remaining == 0 );
863
864 /* Retry immediately if applicable. We cannot rely on an
865 * immediate timer expiry, since certain Microsoft-designed
866 * HTTP extensions such as NTLM break the fundamentally
867 * stateless nature of HTTP and rely on the same connection
868 * being reused for authentication. See RFC7230 section 2.3
869 * for further details.
870 */
871 if ( ! http->response.retry_after ) {
872 http_reopen ( http );
873 return 0;
874 }
875
876 /* Start timer to initiate retry */
877 DBGC2 ( http, "HTTP %p retrying after %d seconds\n",
878 http, http->response.retry_after );
879 start_timer_fixed ( &http->retry,
880 ( http->response.retry_after * TICKS_PER_SEC ) );
881 stop_timer ( &http->watchdog );
882 return 0;
883}
@ HTTP_RESPONSE_KEEPALIVE
Keep connection alive after close.
Definition http.h:364
@ HTTP_RESPONSE_RETRY
Transaction may be retried on failure.
Definition http.h:368
static int http_redirect(struct http_transaction *http, const char *location)
Redirect HTTP transaction.
Definition httpcore.c:764
void intfs_restart(int rc,...)
Shut down and restart multiple object interfaces.
Definition interface.c:387
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
void pool_recycle(struct interface *intf)
Recycle this connection after closing.
Definition pool.c:42
An HTTP authentication scheme.
Definition http.h:526
int(* authenticate)(struct http_transaction *http)
Perform authentication.
Definition http.h:541
const char * name
Name (e.g.
Definition http.h:528
struct http_authentication * auth
Authentication scheme (if any).
Definition http.h:197
struct http_request_auth auth
Authentication descriptor.
Definition http.h:230
struct http_authentication * auth
Authentication scheme (if any).
Definition http.h:305
unsigned int flags
Flags.
Definition http.h:358
struct http_response_auth auth
Authorization descriptor.
Definition http.h:354
unsigned int retry_after
Retry delay (in seconds).
Definition http.h:356
const char * location
Redirection location.
Definition http.h:348
size_t remaining
Chunk length remaining.
Definition http.h:455
size_t len
Accumulated transfer-decoded length.
Definition http.h:453

References assert, http_request::auth, http_request_auth::auth, http_response::auth, http_response_auth::auth, http_authentication::authenticate, http_transaction::conn, http_transaction::content, DBGC, DBGC2, http_response::flags, http_close(), http_redirect(), http_reopen(), HTTP_RESPONSE_KEEPALIVE, HTTP_RESPONSE_RETRY, intf_plug_plug(), intf_restart(), intf_shutdown(), intfs_restart(), http_transaction::len, http_response::location, http_authentication::name, NULL, pool_recycle(), http_response::rc, rc, http_transaction::remaining, http_transaction::request, http_transaction::response, http_transaction::retry, http_response::retry_after, start_timer_fixed(), http_transaction::state, stop_timer(), strerror(), TICKS_PER_SEC, http_transaction::transfer, and http_transaction::watchdog.

Referenced by http_close_transfer_identity(), http_init_transfer_identity(), http_rx_headers(), http_rx_trailers(), and http_rx_transfer_identity().

◆ http_format_headers()

int http_format_headers ( struct http_transaction * http,
char * buf,
size_t len )
static

Construct HTTP request headers.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength, or negative error

Definition at line 900 of file httpcore.c.

901 {
902 struct parameters *params = http->uri->params;
904 struct parameter *param;
905 size_t used;
906 size_t remaining;
907 char *line;
908 int value_len;
909 int rc;
910
911 /* Construct request line */
912 used = ssnprintf ( buf, len, "%s %s HTTP/1.1",
913 http->request.method->name, http->request.uri );
914 if ( used < len )
915 DBGC2 ( http, "HTTP %p TX %s\n", http, buf );
916 used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
917
918 /* Construct all fixed headers */
920
921 /* Determine header value length */
922 value_len = header->format ( http, NULL, 0 );
923 if ( value_len < 0 ) {
924 rc = value_len;
925 return rc;
926 }
927
928 /* Skip zero-length headers */
929 if ( ! value_len )
930 continue;
931
932 /* Construct header */
933 line = ( buf + used );
934 used += ssnprintf ( ( buf + used ), ( len - used ), "%s: ",
935 header->name );
936 remaining = ( ( used < len ) ? ( len - used ) : 0 );
937 used += header->format ( http, ( buf + used ), remaining );
938 if ( used < len )
939 DBGC2 ( http, "HTTP %p TX %s\n", http, line );
940 used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
941 }
942
943 /* Construct parameter headers, if any */
944 if ( params ) {
945
946 /* Construct all parameter headers */
947 for_each_param ( param, params ) {
948
949 /* Skip non-header parameters */
950 if ( ! ( param->flags & PARAMETER_HEADER ) )
951 continue;
952
953 /* Add parameter */
954 used += ssnprintf ( ( buf + used ), ( len - used ),
955 "%s: %s\r\n", param->key,
956 param->value );
957 if ( used < len ) {
958 DBGC2 ( http, "HTTP %p TX %s: %s\n",
959 http, param->key, param->value );
960 }
961 }
962 }
963
964 /* Construct terminating newline */
965 used += ssnprintf ( ( buf + used ), ( len - used ), "\r\n" );
966
967 return used;
968}
ring len
Length.
Definition dwmac.h:226
struct ena_llq_option header
Header locations.
Definition ena.h:5
#define HTTP_REQUEST_HEADERS
HTTP request header table.
Definition http.h:249
struct hv_monitor_parameter param[4][32]
Parameters.
Definition hyperv.h:13
#define for_each_param(param, params)
Iterate over all request parameters in a list.
Definition params.h:86
#define PARAMETER_HEADER
Request parameter is a header parameter.
Definition params.h:46
const char * name
Method name (e.g.
Definition http.h:102
An HTTP request header.
Definition http.h:234
A request parameter.
Definition params.h:31
A request parameter list.
Definition params.h:17
struct parameters * params
Request parameters.
Definition uri.h:89
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition vsprintf.c:421

References DBGC2, for_each_param, for_each_table_entry, header, HTTP_REQUEST_HEADERS, len, http_request::method, http_method::name, NULL, param, PARAMETER_HEADER, uri::params, rc, http_transaction::request, ssnprintf(), http_request::uri, and http_transaction::uri.

Referenced by http_tx_request().

◆ http_format_host()

int http_format_host ( struct http_transaction * http,
char * buf,
size_t len )
static

Construct HTTP "Host" header.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength of header value, or negative error

Definition at line 978 of file httpcore.c.

979 {
980
981 /* Construct host URI */
982 return snprintf ( buf, len, "%s", http->request.host );
983}
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References http_request::host, len, http_transaction::request, and snprintf().

◆ http_format_user_agent()

int http_format_user_agent ( struct http_transaction *http __unused,
char * buf,
size_t len )
static

Construct HTTP "User-Agent" header.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength of header value, or negative error

Definition at line 999 of file httpcore.c.

1000 {
1001
1002 /* Construct user agent */
1003 return snprintf ( buf, len, "iPXE/%s", product_version );
1004}
const char product_version[]
Product version string.
Definition version.c:72

References __unused, len, product_version, and snprintf().

◆ http_format_connection()

int http_format_connection ( struct http_transaction *http __unused,
char * buf,
size_t len )
static

Construct HTTP "Connection" header.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength of header value, or negative error

Definition at line 1020 of file httpcore.c.

1021 {
1022
1023 /* Always request keep-alive */
1024 return snprintf ( buf, len, "keep-alive" );
1025}

References __unused, len, and snprintf().

◆ http_format_range()

int http_format_range ( struct http_transaction * http,
char * buf,
size_t len )
static

Construct HTTP "Range" header.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength of header value, or negative error

Definition at line 1041 of file httpcore.c.

1042 {
1043
1044 /* Construct range, if applicable */
1045 if ( http->request.range.len ) {
1046 return snprintf ( buf, len, "bytes=%zd-%zd",
1047 http->request.range.start,
1048 ( http->request.range.start +
1049 http->request.range.len - 1 ) );
1050 } else {
1051 return 0;
1052 }
1053}
size_t start
Range start.
Definition http.h:145
size_t len
Range length, or zero for no range request.
Definition http.h:147

References http_request_range::len, len, http_request::range, http_transaction::request, snprintf(), and http_request_range::start.

◆ http_format_content_type()

int http_format_content_type ( struct http_transaction * http,
char * buf,
size_t len )
static

Construct HTTP "Content-Type" header.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength of header value, or negative error

Definition at line 1069 of file httpcore.c.

1070 {
1071
1072 /* Construct content type, if applicable */
1073 if ( http->request.content.type ) {
1074 return snprintf ( buf, len, "%s", http->request.content.type );
1075 } else {
1076 return 0;
1077 }
1078}

References http_request::content, len, http_transaction::request, snprintf(), and http_request_content::type.

◆ http_format_content_length()

int http_format_content_length ( struct http_transaction * http,
char * buf,
size_t len )
static

Construct HTTP "Content-Length" header.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength of header value, or negative error

Definition at line 1094 of file httpcore.c.

1095 {
1096
1097 /* Construct content length, if applicable */
1098 if ( http->request.content.len ) {
1099 return snprintf ( buf, len, "%zd", http->request.content.len );
1100 } else {
1101 return 0;
1102 }
1103}

References http_request::content, http_request_content::len, len, http_transaction::request, and snprintf().

◆ http_format_accept_encoding()

int http_format_accept_encoding ( struct http_transaction * http,
char * buf,
size_t len )
static

Construct HTTP "Accept-Encoding" header.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength of header value, or negative error

Definition at line 1119 of file httpcore.c.

1120 {
1121 struct http_content_encoding *encoding;
1122 const char *sep = "";
1123 size_t used = 0;
1124
1125 /* Construct list of content encodings */
1127 if ( encoding->supported && ( ! encoding->supported ( http ) ) )
1128 continue;
1129 used += ssnprintf ( ( buf + used ), ( len - used ),
1130 "%s%s", sep, encoding->name );
1131 sep = ", ";
1132 }
1133
1134 return used;
1135}
#define HTTP_CONTENT_ENCODINGS
HTTP content encoding table.
Definition http.h:512
An HTTP content encoding.
Definition http.h:494
int(* supported)(struct http_transaction *http)
Check if content encoding is supported for this request.
Definition http.h:502
const char * name
Name.
Definition http.h:496

References for_each_table_entry, HTTP_CONTENT_ENCODINGS, len, http_content_encoding::name, ssnprintf(), and http_content_encoding::supported.

◆ http_tx_request()

int http_tx_request ( struct http_transaction * http)
static

Transmit request.

Parameters
httpHTTP transaction
Return values
rcReturn status code

Definition at line 1149 of file httpcore.c.

1149 {
1150 struct io_buffer *iobuf;
1151 int len;
1152 int check_len;
1153 int rc;
1154
1155 /* Calculate request length */
1156 len = http_format_headers ( http, NULL, 0 );
1157 if ( len < 0 ) {
1158 rc = len;
1159 DBGC ( http, "HTTP %p could not construct request: %s\n",
1160 http, strerror ( rc ) );
1161 goto err_len;
1162 }
1163
1164 /* Allocate I/O buffer */
1165 iobuf = xfer_alloc_iob ( &http->conn, ( len + 1 /* NUL */ +
1166 http->request.content.len ) );
1167 if ( ! iobuf ) {
1168 rc = -ENOMEM;
1169 goto err_alloc;
1170 }
1171
1172 /* Construct request */
1173 check_len = http_format_headers ( http, iob_put ( iobuf, len ),
1174 ( len + 1 /* NUL */ ) );
1175 assert ( check_len == len );
1176 memcpy ( iob_put ( iobuf, http->request.content.len ),
1177 http->request.content.data, http->request.content.len );
1178
1179 /* Deliver request */
1180 if ( ( rc = xfer_deliver_iob ( &http->conn,
1181 iob_disown ( iobuf ) ) ) != 0 ) {
1182 DBGC ( http, "HTTP %p could not deliver request: %s\n",
1183 http, strerror ( rc ) );
1184 goto err_deliver;
1185 }
1186
1187 /* Clear any previous response */
1189 memset ( &http->response, 0, sizeof ( http->response ) );
1190
1191 /* Move to response headers state */
1192 http->state = &http_headers;
1193
1194 return 0;
1195
1196 err_deliver:
1197 free_iob ( iobuf );
1198 err_alloc:
1199 err_len:
1200 return rc;
1201}
static int http_format_headers(struct http_transaction *http, char *buf, size_t len)
Construct HTTP request headers.
Definition httpcore.c:900
static struct http_state http_headers
HTTP response headers state.
Definition httpcore.c:127
#define iob_put(iobuf, len)
Definition iobuf.h:125
A persistent I/O buffer.
Definition iobuf.h:38
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256

References assert, http_transaction::conn, http_request::content, http_request_content::data, DBGC, empty_line_buffer(), ENOMEM, free_iob(), http_response::headers, http_format_headers(), http_headers, iob_disown, iob_put, http_request_content::len, len, memcpy(), memset(), NULL, rc, http_transaction::request, http_transaction::response, http_transaction::state, strerror(), xfer_alloc_iob(), and xfer_deliver_iob().

◆ http_parse_status()

int http_parse_status ( struct http_transaction * http,
char * line )
static

Parse HTTP status line.

Parameters
httpHTTP transaction
lineStatus line
Return values
rcReturn status code

Definition at line 1223 of file httpcore.c.

1223 {
1224 char *endp;
1225 char *version;
1226 char *vernum;
1227 char *status;
1228 int response_rc;
1229
1230 DBGC2 ( http, "HTTP %p RX %s\n", http, line );
1231
1232 /* Parse HTTP version */
1233 version = http_token ( &line, NULL );
1234 if ( ( ! version ) || ( strncmp ( version, "HTTP/", 5 ) != 0 ) ) {
1235 DBGC ( http, "HTTP %p malformed version \"%s\"\n", http, line );
1236 return -EINVAL_STATUS;
1237 }
1238
1239 /* Keepalive is enabled by default for anything newer than HTTP/1.0 */
1240 vernum = ( version + 5 /* "HTTP/" (presence already checked) */ );
1241 if ( vernum[0] == '0' ) {
1242 /* HTTP/0.x : keepalive not enabled by default */
1243 } else if ( strncmp ( vernum, "1.0", 3 ) == 0 ) {
1244 /* HTTP/1.0 : keepalive not enabled by default */
1245 } else {
1246 /* HTTP/1.1 or newer: keepalive enabled by default */
1248 }
1249
1250 /* Parse status code */
1251 status = line;
1252 http->response.status = strtoul ( status, &endp, 10 );
1253 if ( *endp != ' ' ) {
1254 DBGC ( http, "HTTP %p malformed status code \"%s\"\n",
1255 http, status );
1256 return -EINVAL_STATUS;
1257 }
1258
1259 /* Convert HTTP status code to iPXE return status code */
1260 if ( status[0] == '2' ) {
1261 /* 2xx Success */
1262 response_rc = 0;
1263 } else if ( status[0] == '3' ) {
1264 /* 3xx Redirection */
1265 response_rc = -EXDEV;
1266 } else if ( http->response.status == 401 ) {
1267 /* 401 Unauthorized */
1268 response_rc = -EACCES_401;
1269 } else if ( http->response.status == 403 ) {
1270 /* 403 Forbidden */
1271 response_rc = -EPERM_403;
1272 } else if ( http->response.status == 404 ) {
1273 /* 404 Not Found */
1274 response_rc = -ENOENT_404;
1275 } else if ( status[0] == '4' ) {
1276 /* 4xx Client Error (not already specified) */
1277 response_rc = -EIO_4XX;
1278 } else if ( status[0] == '5' ) {
1279 /* 5xx Server Error */
1280 response_rc = -EIO_5XX;
1281 } else {
1282 /* Unrecognised */
1283 response_rc = -EIO_OTHER;
1284 }
1285 http->response.rc = response_rc;
1286 if ( response_rc )
1287 DBGC ( http, "HTTP %p status %s\n", http, status );
1288
1289 return 0;
1290}
u32 version
Driver version.
Definition ath9k_hw.c:1985
uint8_t status
Status.
Definition ena.h:5
#define EXDEV
Improper link.
Definition errno.h:685
#define EIO_4XX
Definition httpcore.c:85
#define EACCES_401
Definition httpcore.c:64
char * http_token(char **line, char **value)
Get HTTP response token.
Definition httpcore.c:219
#define EINVAL_STATUS
Definition httpcore.c:67
#define ENOENT_404
Definition httpcore.c:91
#define EPERM_403
Definition httpcore.c:100
#define EIO_OTHER
Definition httpcore.c:79
#define EIO_5XX
Definition httpcore.c:88
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:516
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Definition string.c:187
unsigned int status
Status code.
Definition http.h:340

References DBGC, DBGC2, EACCES_401, EINVAL_STATUS, EIO_4XX, EIO_5XX, EIO_OTHER, ENOENT_404, EPERM_403, EXDEV, http_response::flags, HTTP_RESPONSE_KEEPALIVE, http_token(), NULL, http_response::rc, http_transaction::response, http_response::status, status, strncmp(), strtoul(), and version.

Referenced by http_parse_headers().

◆ http_parse_header()

int http_parse_header ( struct http_transaction * http,
char * line )
static

Parse HTTP header.

Parameters
httpHTTP transaction
lineHeader line
Return values
rcReturn status code

Definition at line 1299 of file httpcore.c.

1299 {
1301 char *name = line;
1302 char *sep;
1303
1304 DBGC2 ( http, "HTTP %p RX %s\n", http, line );
1305
1306 /* Extract header name */
1307 sep = strchr ( line, ':' );
1308 if ( ! sep ) {
1309 DBGC ( http, "HTTP %p malformed header \"%s\"\n", http, line );
1310 return -EINVAL_HEADER;
1311 }
1312 *sep = '\0';
1313
1314 /* Extract remainder of line */
1315 line = ( sep + 1 );
1316 while ( isspace ( *line ) )
1317 line++;
1318
1319 /* Process header, if recognised */
1321 if ( strcasecmp ( name, header->name ) == 0 )
1322 return header->parse ( http, line );
1323 }
1324
1325 /* Unrecognised headers should be ignored */
1326 return 0;
1327}
#define HTTP_RESPONSE_HEADERS
HTTP response header table.
Definition http.h:385
#define EINVAL_HEADER
Definition httpcore.c:70
char * strchr(const char *src, int character)
Find character within a string.
Definition string.c:288
An HTTP response header.
Definition http.h:372

References DBGC, DBGC2, EINVAL_HEADER, for_each_table_entry, header, HTTP_RESPONSE_HEADERS, isspace(), name, strcasecmp(), and strchr().

Referenced by http_parse_headers().

◆ http_parse_headers()

int http_parse_headers ( struct http_transaction * http)
static

Parse HTTP response headers.

Parameters
httpHTTP transaction
Return values
rcReturn status code

Definition at line 1335 of file httpcore.c.

1335 {
1336 char *line;
1337 char *next;
1338 int rc;
1339
1340 /* Get status line */
1341 line = http->response.headers.data;
1342 assert ( line != NULL );
1343 next = ( line + strlen ( line ) + 1 /* NUL */ );
1344
1345 /* Parse status line */
1346 if ( ( rc = http_parse_status ( http, line ) ) != 0 )
1347 return rc;
1348
1349 /* Process header lines */
1350 while ( 1 ) {
1351
1352 /* Move to next line */
1353 line = next;
1354 next = ( line + strlen ( line ) + 1 /* NUL */ );
1355
1356 /* Stop on terminating blank line */
1357 if ( ! line[0] )
1358 return 0;
1359
1360 /* Process header line */
1361 if ( ( rc = http_parse_header ( http, line ) ) != 0 )
1362 return rc;
1363 }
1364}
uint32_t next
Next descriptor address.
Definition dwmac.h:11
static int http_parse_status(struct http_transaction *http, char *line)
Parse HTTP status line.
Definition httpcore.c:1223
static int http_parse_header(struct http_transaction *http, char *line)
Parse HTTP header.
Definition httpcore.c:1299
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
char * data
Data buffer.
Definition linebuf.h:19

References assert, line_buffer::data, http_response::headers, http_parse_header(), http_parse_status(), next, NULL, rc, http_transaction::response, and strlen().

Referenced by http_rx_headers().

◆ http_parse_location()

int http_parse_location ( struct http_transaction * http,
char * line )
static

Parse HTTP "Location" header.

Parameters
httpHTTP transaction
lineRemaining header line
Return values
rcReturn status code

Definition at line 1373 of file httpcore.c.

1373 {
1374
1375 /* Store location */
1376 http->response.location = line;
1377 return 0;
1378}

References http_response::location, and http_transaction::response.

◆ http_parse_transfer_encoding()

int http_parse_transfer_encoding ( struct http_transaction * http,
char * line )
static

Parse HTTP "Transfer-Encoding" header.

Parameters
httpHTTP transaction
lineRemaining header line
Return values
rcReturn status code

Definition at line 1393 of file httpcore.c.

1394 {
1395 struct http_transfer_encoding *encoding;
1396
1397 /* Check for known transfer encodings */
1399 if ( strcasecmp ( line, encoding->name ) == 0 ) {
1400 http->response.transfer.encoding = encoding;
1401 return 0;
1402 }
1403 }
1404
1405 DBGC ( http, "HTTP %p unrecognised Transfer-Encoding \"%s\"\n",
1406 http, line );
1407 return -ENOTSUP_TRANSFER;
1408}
#define HTTP_TRANSFER_ENCODINGS
HTTP transfer encoding table.
Definition http.h:480
#define ENOTSUP_TRANSFER
Definition httpcore.c:97
struct http_transfer_encoding * encoding
Transfer encoding.
Definition http.h:265
struct http_response_transfer transfer
Transfer descriptor.
Definition http.h:350
An HTTP transfer encoding.
Definition http.h:466
const char * name
Name.
Definition http.h:468

References DBGC, http_response_transfer::encoding, ENOTSUP_TRANSFER, for_each_table_entry, HTTP_TRANSFER_ENCODINGS, http_transfer_encoding::name, http_transaction::response, strcasecmp(), and http_response::transfer.

◆ http_parse_connection()

int http_parse_connection ( struct http_transaction * http,
char * line )
static

Parse HTTP "Connection" header.

Parameters
httpHTTP transaction
lineRemaining header line
Return values
rcReturn status code

Definition at line 1424 of file httpcore.c.

1424 {
1425 char *token;
1426
1427 /* Check for known connection intentions */
1428 while ( ( token = http_token ( &line, NULL ) ) ) {
1429 if ( strcasecmp ( token, "keep-alive" ) == 0 )
1431 if ( strcasecmp ( token, "close" ) == 0 )
1433 }
1434
1435 return 0;
1436}

References http_response::flags, HTTP_RESPONSE_KEEPALIVE, http_token(), NULL, http_transaction::response, strcasecmp(), and token.

◆ http_parse_content_length()

int http_parse_content_length ( struct http_transaction * http,
char * line )
static

Parse HTTP "Content-Length" header.

Parameters
httpHTTP transaction
lineRemaining header line
Return values
rcReturn status code

Definition at line 1451 of file httpcore.c.

1452 {
1453 char *endp;
1454
1455 /* Parse length */
1456 http->response.content.len = strtoul ( line, &endp, 10 );
1457 if ( *endp != '\0' ) {
1458 DBGC ( http, "HTTP %p invalid Content-Length \"%s\"\n",
1459 http, line );
1460 return -EINVAL_CONTENT_LENGTH;
1461 }
1462
1463 /* Record that we have a content length (since it may be zero) */
1465
1466 return 0;
1467}
@ HTTP_RESPONSE_CONTENT_LEN
Content length specified.
Definition http.h:366
#define EINVAL_CONTENT_LENGTH
Definition httpcore.c:73
size_t len
Content length (may be zero).
Definition http.h:271
struct http_response_content content
Content descriptor.
Definition http.h:352

References http_response::content, DBGC, EINVAL_CONTENT_LENGTH, http_response::flags, HTTP_RESPONSE_CONTENT_LEN, http_response_content::len, http_transaction::response, and strtoul().

◆ http_parse_content_encoding()

int http_parse_content_encoding ( struct http_transaction * http,
char * line )
static

Parse HTTP "Content-Encoding" header.

Parameters
httpHTTP transaction
lineRemaining header line
Return values
rcReturn status code

Definition at line 1483 of file httpcore.c.

1484 {
1485 struct http_content_encoding *encoding;
1486
1487 /* Check for known content encodings */
1489 if ( encoding->supported && ( ! encoding->supported ( http ) ) )
1490 continue;
1491 if ( strcasecmp ( line, encoding->name ) == 0 ) {
1492 http->response.content.encoding = encoding;
1493 return 0;
1494 }
1495 }
1496
1497 /* Some servers (e.g. Apache) have a habit of specifying
1498 * unwarranted content encodings. For example, if Apache
1499 * detects (via /etc/httpd/conf/magic) that a file's contents
1500 * are gzip-compressed, it will set "Content-Encoding: x-gzip"
1501 * regardless of the client's Accept-Encoding header. The
1502 * only viable way to handle such servers is to treat unknown
1503 * content encodings as equivalent to "identity".
1504 */
1505 DBGC ( http, "HTTP %p unrecognised Content-Encoding \"%s\"\n",
1506 http, line );
1507 return 0;
1508}
struct http_content_encoding * encoding
Content encoding.
Definition http.h:273

References http_response::content, DBGC, http_response_content::encoding, for_each_table_entry, HTTP_CONTENT_ENCODINGS, http_content_encoding::name, http_transaction::response, strcasecmp(), and http_content_encoding::supported.

◆ http_parse_retry_after()

int http_parse_retry_after ( struct http_transaction * http,
char * line )
static

Parse HTTP "Retry-After" header.

Parameters
httpHTTP transaction
lineRemaining header line
Return values
rcReturn status code

Definition at line 1524 of file httpcore.c.

1525 {
1526 char *endp;
1527
1528 /* Try to parse value as a simple number of seconds */
1529 http->response.retry_after = strtoul ( line, &endp, 10 );
1530 if ( *endp != '\0' ) {
1531 /* For any value which is not a simple number of
1532 * seconds (e.g. a full HTTP date), just retry after a
1533 * fixed delay, since we don't have code able to parse
1534 * full HTTP dates.
1535 */
1537 DBGC ( http, "HTTP %p cannot understand Retry-After \"%s\"; "
1538 "using %d seconds\n", http, line, HTTP_RETRY_SECONDS );
1539 }
1540
1541 /* Allow HTTP request to be retried after specified delay */
1543
1544 return 0;
1545}
#define HTTP_RETRY_SECONDS
Retry delay used when we cannot understand the Retry-After header.
Definition httpcore.c:108

References DBGC, http_response::flags, HTTP_RESPONSE_RETRY, HTTP_RETRY_SECONDS, http_transaction::response, http_response::retry_after, and strtoul().

◆ http_rx_headers()

int http_rx_headers ( struct http_transaction * http,
struct io_buffer ** iobuf )
static

Handle received HTTP headers.

Parameters
httpHTTP transaction
iobufI/O buffer (may be claimed)
Return values
rcReturn status code

Definition at line 1560 of file httpcore.c.

1561 {
1562 struct http_transfer_encoding *transfer;
1563 struct http_content_encoding *content;
1564 char *line;
1565 int rc;
1566
1567 /* Buffer header line */
1568 if ( ( rc = http_rx_linebuf ( http, *iobuf,
1569 &http->response.headers ) ) != 0 )
1570 return rc;
1571
1572 /* Wait until we see the empty line marking end of headers */
1573 line = buffered_line ( &http->response.headers );
1574 if ( ( line == NULL ) || ( line[0] != '\0' ) )
1575 return 0;
1576
1577 /* Process headers */
1578 if ( ( rc = http_parse_headers ( http ) ) != 0 )
1579 return rc;
1580
1581 /* Initialise content encoding, if applicable */
1582 if ( ( content = http->response.content.encoding ) &&
1583 ( ( rc = content->init ( http ) ) != 0 ) ) {
1584 DBGC ( http, "HTTP %p could not initialise %s content "
1585 "encoding: %s\n", http, content->name, strerror ( rc ) );
1586 return rc;
1587 }
1588
1589 /* Presize receive buffer, if we have a content length */
1590 if ( http->response.content.len ) {
1591 xfer_seek ( &http->transfer, http->response.content.len );
1592 xfer_seek ( &http->transfer, 0 );
1593 }
1594
1595 /* Complete transfer if this is a HEAD request */
1596 if ( http->request.method == &http_head ) {
1597 if ( ( rc = http_transfer_complete ( http ) ) != 0 )
1598 return rc;
1599 return 0;
1600 }
1601
1602 /* Default to identity transfer encoding, if none specified */
1603 if ( ! http->response.transfer.encoding )
1605
1606 /* Move to transfer encoding-specific data state */
1607 transfer = http->response.transfer.encoding;
1608 http->state = &transfer->state;
1609
1610 /* Initialise transfer encoding */
1611 if ( ( rc = transfer->init ( http ) ) != 0 ) {
1612 DBGC ( http, "HTTP %p could not initialise %s transfer "
1613 "encoding: %s\n", http, transfer->name, strerror ( rc ));
1614 return rc;
1615 }
1616
1617 return 0;
1618}
static int http_parse_headers(struct http_transaction *http)
Parse HTTP response headers.
Definition httpcore.c:1335
static int http_transfer_complete(struct http_transaction *http)
Handle successful transfer completion.
Definition httpcore.c:808
static struct http_transfer_encoding http_transfer_identity
Identity transfer encoding.
Definition httpcore.c:129
static int http_rx_linebuf(struct http_transaction *http, struct io_buffer *iobuf, struct line_buffer *linebuf)
Handle received HTTP line-buffered data.
Definition httpcore.c:191
char * buffered_line(struct line_buffer *linebuf)
Retrieve buffered-up line.
Definition linebuf.c:46
int(* init)(struct http_transaction *http)
Initialise content encoding.
Definition http.h:508
struct http_state state
Receive data state.
Definition http.h:476
int(* init)(struct http_transaction *http)
Initialise transfer encoding.
Definition http.h:474
int xfer_seek(struct interface *intf, off_t offset)
Seek to position.
Definition xfer.c:352

References buffered_line(), http_response::content, DBGC, http_response_content::encoding, http_response_transfer::encoding, http_response::headers, http_parse_headers(), http_rx_linebuf(), http_transfer_complete(), http_transfer_identity, http_content_encoding::init, http_transfer_encoding::init, http_response_content::len, http_request::method, http_content_encoding::name, http_transfer_encoding::name, NULL, rc, http_transaction::request, http_transaction::response, http_transaction::state, http_transfer_encoding::state, strerror(), http_response::transfer, http_transaction::transfer, and xfer_seek().

◆ http_init_transfer_identity()

int http_init_transfer_identity ( struct http_transaction * http)
static

Initialise transfer encoding.

Parameters
httpHTTP transaction
Return values
rcReturn status code

Definition at line 1639 of file httpcore.c.

1639 {
1640 int rc;
1641
1642 /* Complete transfer immediately if we have a zero content length */
1643 if ( ( http->response.flags & HTTP_RESPONSE_CONTENT_LEN ) &&
1644 ( http->response.content.len == 0 ) &&
1645 ( ( rc = http_transfer_complete ( http ) ) != 0 ) )
1646 return rc;
1647
1648 return 0;
1649}

References http_response::content, http_response::flags, HTTP_RESPONSE_CONTENT_LEN, http_transfer_complete(), http_response_content::len, rc, and http_transaction::response.

◆ http_rx_transfer_identity()

int http_rx_transfer_identity ( struct http_transaction * http,
struct io_buffer ** iobuf )
static

Handle received data.

Parameters
httpHTTP transaction
iobufI/O buffer (may be claimed)
Return values
rcReturn status code

Definition at line 1658 of file httpcore.c.

1659 {
1660 size_t len = iob_len ( *iobuf );
1661 int rc;
1662
1663 /* Update lengths */
1664 http->len += len;
1665
1666 /* Fail if this transfer would overrun the expected content
1667 * length (if any).
1668 */
1669 if ( ( http->response.flags & HTTP_RESPONSE_CONTENT_LEN ) &&
1670 ( http->len > http->response.content.len ) ) {
1671 DBGC ( http, "HTTP %p content length overrun\n", http );
1672 return -EIO_CONTENT_LENGTH;
1673 }
1674
1675 /* Hand off to content encoding */
1676 if ( ( rc = xfer_deliver_iob ( &http->transfer,
1677 iob_disown ( *iobuf ) ) ) != 0 )
1678 return rc;
1679
1680 /* Complete transfer if we have received the expected content
1681 * length (if any).
1682 */
1683 if ( ( http->response.flags & HTTP_RESPONSE_CONTENT_LEN ) &&
1684 ( http->len == http->response.content.len ) &&
1685 ( ( rc = http_transfer_complete ( http ) ) != 0 ) )
1686 return rc;
1687
1688 return 0;
1689}
#define EIO_CONTENT_LENGTH
Definition httpcore.c:82

References http_response::content, DBGC, EIO_CONTENT_LENGTH, http_response::flags, HTTP_RESPONSE_CONTENT_LEN, http_transfer_complete(), iob_disown, iob_len(), http_response_content::len, http_transaction::len, len, rc, http_transaction::response, http_transaction::transfer, and xfer_deliver_iob().

◆ http_close_transfer_identity()

void http_close_transfer_identity ( struct http_transaction * http,
int rc )
static

Handle server connection close.

Parameters
httpHTTP transaction
rcReason for close

Definition at line 1697 of file httpcore.c.

1698 {
1699
1700 /* Fail if any error occurred */
1701 if ( rc != 0 )
1702 goto err;
1703
1704 /* Fail if we have a content length (since we would have
1705 * already closed the connection if we had received the
1706 * correct content length).
1707 */
1709 DBGC ( http, "HTTP %p content length underrun\n", http );
1711 goto err;
1712 }
1713
1714 /* Indicate that transfer is complete */
1715 if ( ( rc = http_transfer_complete ( http ) ) != 0 )
1716 goto err;
1717
1718 return;
1719
1720 err:
1721 http_close ( http, rc );
1722}

References DBGC, EIO_CONTENT_LENGTH, http_response::flags, http_close(), HTTP_RESPONSE_CONTENT_LEN, http_transfer_complete(), rc, and http_transaction::response.

◆ http_init_transfer_chunked()

int http_init_transfer_chunked ( struct http_transaction * http)
static

Initialise transfer encoding.

Parameters
httpHTTP transaction
Return values
rcReturn status code

Definition at line 1747 of file httpcore.c.

1747 {
1748
1749 /* Sanity checks */
1750 assert ( http->remaining == 0 );
1751 assert ( http->linebuf.len == 0 );
1752
1753 return 0;
1754}
size_t len
Length of buffered data.
Definition linebuf.h:21

References assert, line_buffer::len, http_transaction::linebuf, and http_transaction::remaining.

◆ http_rx_chunk_len()

int http_rx_chunk_len ( struct http_transaction * http,
struct io_buffer ** iobuf )
static

Handle received chunk length.

Parameters
httpHTTP transaction
iobufI/O buffer (may be claimed)
Return values
rcReturn status code

Definition at line 1763 of file httpcore.c.

1764 {
1765 char *line;
1766 char *endp;
1767 size_t len;
1768 int rc;
1769
1770 /* Receive into temporary line buffer */
1771 if ( ( rc = http_rx_linebuf ( http, *iobuf, &http->linebuf ) ) != 0 )
1772 return rc;
1773
1774 /* Wait until we receive a non-empty line */
1775 line = buffered_line ( &http->linebuf );
1776 if ( ( line == NULL ) || ( line[0] == '\0' ) )
1777 return 0;
1778
1779 /* Parse chunk length */
1780 http->remaining = strtoul ( line, &endp, 16 );
1781 if ( *endp != '\0' ) {
1782 DBGC ( http, "HTTP %p invalid chunk length \"%s\"\n",
1783 http, line );
1784 return -EINVAL_CHUNK_LENGTH;
1785 }
1786
1787 /* Empty line buffer */
1788 empty_line_buffer ( &http->linebuf );
1789
1790 /* Update expected length */
1791 len = ( http->len + http->remaining );
1792 xfer_seek ( &http->transfer, len );
1793 xfer_seek ( &http->transfer, http->len );
1794
1795 /* If chunk length is zero, then move to response trailers state */
1796 if ( ! http->remaining )
1797 http->state = &http_trailers;
1798
1799 return 0;
1800}
#define EINVAL_CHUNK_LENGTH
Definition httpcore.c:76
static struct http_state http_trailers
HTTP response trailers state.
Definition httpcore.c:128

References buffered_line(), DBGC, EINVAL_CHUNK_LENGTH, empty_line_buffer(), http_rx_linebuf(), http_trailers, http_transaction::len, len, http_transaction::linebuf, NULL, rc, http_transaction::remaining, http_transaction::state, strtoul(), http_transaction::transfer, and xfer_seek().

Referenced by http_rx_transfer_chunked().

◆ http_rx_chunk_data()

int http_rx_chunk_data ( struct http_transaction * http,
struct io_buffer ** iobuf )
static

Handle received chunk data.

Parameters
httpHTTP transaction
iobufI/O buffer (may be claimed)
Return values
rcReturn status code

Definition at line 1809 of file httpcore.c.

1810 {
1811 struct {
1812 uint8_t cr;
1813 uint8_t lf;
1814 } __attribute__ (( packed )) *crlf;
1815 struct io_buffer *payload;
1816 size_t len;
1817 int rc;
1818
1819 /* In the common case of a final chunk in a packet which also
1820 * includes the terminating CRLF, strip the terminating CRLF
1821 * (which we would ignore anyway) and hence avoid
1822 * unnecessarily copying the data.
1823 */
1824 len = iob_len ( *iobuf );
1825 if ( ( len >= sizeof ( *crlf ) ) &&
1826 ( ( len - sizeof ( *crlf ) ) == http->remaining ) ) {
1827 crlf = ( (*iobuf)->data + http->remaining );
1828 if ( ( crlf->cr == '\r' ) && ( crlf->lf == '\n' ) ) {
1829 iob_unput ( *iobuf, sizeof ( *crlf ) );
1830 len -= sizeof ( *crlf );
1831 }
1832 }
1833 assert ( len == iob_len ( *iobuf ) );
1834
1835 /* Use whole/partial buffer as applicable */
1836 if ( len <= http->remaining ) {
1837
1838 /* Whole buffer is to be consumed: decrease remaining
1839 * length and use original I/O buffer as payload.
1840 */
1841 payload = iob_disown ( *iobuf );
1842 http->len += len;
1843 http->remaining -= len;
1844
1845 } else {
1846
1847 /* Partial buffer is to be consumed: copy data to a
1848 * temporary I/O buffer.
1849 */
1850 payload = alloc_iob ( http->remaining );
1851 if ( ! payload ) {
1852 rc = -ENOMEM;
1853 goto err;
1854 }
1855 memcpy ( iob_put ( payload, http->remaining ), (*iobuf)->data,
1856 http->remaining );
1857 iob_pull ( *iobuf, http->remaining );
1858 http->len += http->remaining;
1859 http->remaining = 0;
1860 }
1861
1862 /* Hand off to content encoding */
1863 if ( ( rc = xfer_deliver_iob ( &http->transfer,
1864 iob_disown ( payload ) ) ) != 0 )
1865 goto err;
1866
1867 return 0;
1868
1869 err:
1870 assert ( payload == NULL );
1871 return rc;
1872}
unsigned char uint8_t
Definition stdint.h:10
#define __attribute__(x)
Definition compiler.h:10
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_unput(iobuf, len)
Definition iobuf.h:140
@ cr
Definition sis900.h:22

References __attribute__, alloc_iob(), assert, cr, ENOMEM, iob_disown, iob_len(), iob_pull, iob_put, iob_unput, http_transaction::len, len, memcpy(), NULL, rc, http_transaction::remaining, http_transaction::transfer, and xfer_deliver_iob().

Referenced by http_rx_transfer_chunked().

◆ http_rx_transfer_chunked()

int http_rx_transfer_chunked ( struct http_transaction * http,
struct io_buffer ** iobuf )
static

Handle received chunked data.

Parameters
httpHTTP transaction
iobufI/O buffer (may be claimed)
Return values
rcReturn status code

Definition at line 1881 of file httpcore.c.

1882 {
1883
1884 /* Handle as chunk length or chunk data as appropriate */
1885 if ( http->remaining ) {
1886 return http_rx_chunk_data ( http, iobuf );
1887 } else {
1888 return http_rx_chunk_len ( http, iobuf );
1889 }
1890}
static int http_rx_chunk_len(struct http_transaction *http, struct io_buffer **iobuf)
Handle received chunk length.
Definition httpcore.c:1763
static int http_rx_chunk_data(struct http_transaction *http, struct io_buffer **iobuf)
Handle received chunk data.
Definition httpcore.c:1809

References http_rx_chunk_data(), http_rx_chunk_len(), and http_transaction::remaining.

◆ http_rx_trailers()

int http_rx_trailers ( struct http_transaction * http,
struct io_buffer ** iobuf )
static

Handle received HTTP trailer.

Parameters
httpHTTP transaction
iobufI/O buffer (may be claimed)
Return values
rcReturn status code

Definition at line 1916 of file httpcore.c.

1917 {
1918 char *line;
1919 int rc;
1920
1921 /* Buffer trailer line */
1922 if ( ( rc = http_rx_linebuf ( http, *iobuf, &http->linebuf ) ) != 0 )
1923 return rc;
1924
1925 /* Wait until we see the empty line marking end of trailers */
1926 line = buffered_line ( &http->linebuf );
1927 if ( ( line == NULL ) || ( line[0] != '\0' ) )
1928 return 0;
1929
1930 /* Empty line buffer */
1931 empty_line_buffer ( &http->linebuf );
1932
1933 /* Transfer is complete */
1934 if ( ( rc = http_transfer_complete ( http ) ) != 0 )
1935 return rc;
1936
1937 return 0;
1938}

References buffered_line(), empty_line_buffer(), http_rx_linebuf(), http_transfer_complete(), http_transaction::linebuf, NULL, and rc.

◆ http_form_params()

size_t http_form_params ( struct parameters * params,
char * buf,
size_t len )
static

Construct HTTP form parameter list.

Parameters
paramsParameter list
bufBuffer to contain HTTP POST parameters
lenLength of buffer
Return values
lenLength of parameter list (excluding terminating NUL)

Definition at line 1961 of file httpcore.c.

1962 {
1963 struct parameter *param;
1964 ssize_t remaining = len;
1965 size_t frag_len;
1966
1967 /* Add each parameter in the form "key=value", joined with "&" */
1968 len = 0;
1969 for_each_param ( param, params ) {
1970
1971 /* Skip non-form parameters */
1972 if ( ! ( param->flags & PARAMETER_FORM ) )
1973 continue;
1974
1975 /* Add the "&", if applicable */
1976 if ( len ) {
1977 if ( remaining > 0 )
1978 *buf = '&';
1979 buf++;
1980 len++;
1981 remaining--;
1982 }
1983
1984 /* URI-encode the key */
1985 frag_len = uri_encode_string ( 0, param->key, buf, remaining );
1986 buf += frag_len;
1987 len += frag_len;
1988 remaining -= frag_len;
1989
1990 /* Add the "=" */
1991 if ( remaining > 0 )
1992 *buf = '=';
1993 buf++;
1994 len++;
1995 remaining--;
1996
1997 /* URI-encode the value */
1998 frag_len = uri_encode_string ( 0, param->value, buf, remaining);
1999 buf += frag_len;
2000 len += frag_len;
2001 remaining -= frag_len;
2002 }
2003
2004 /* Ensure string is NUL-terminated even if no parameters are present */
2005 if ( remaining > 0 )
2006 *buf = '\0';
2007
2008 return len;
2009}
signed long ssize_t
Definition stdint.h:7
#define PARAMETER_FORM
Request parameter is a form parameter.
Definition params.h:43
size_t uri_encode_string(unsigned int field, const char *string, char *buf, ssize_t len)
Encode URI field string.
Definition uri.c:236

References for_each_param, len, param, PARAMETER_FORM, and uri_encode_string().

Referenced by http_open_uri().

◆ http_open_uri()

int http_open_uri ( struct interface * xfer,
struct uri * uri )

Open HTTP transaction for simple URI.

Parameters
xferData transfer interface
uriRequest URI
Return values
rcReturn status code

Definition at line 2018 of file httpcore.c.

2018 {
2019 struct parameters *params = uri->params;
2020 struct http_request_content content;
2021 struct http_method *method;
2022 const char *type;
2023 void *data;
2024 size_t len;
2025 size_t check_len;
2026 int rc;
2027
2028 /* Calculate length of form parameter list, if any */
2029 len = ( params ? http_form_params ( params, NULL, 0 ) : 0 );
2030
2031 /* Use POST if and only if there are form parameters */
2032 if ( len ) {
2033
2034 /* Use POST */
2035 method = &http_post;
2036 type = "application/x-www-form-urlencoded";
2037
2038 /* Allocate temporary form parameter list */
2039 data = zalloc ( len + 1 /* NUL */ );
2040 if ( ! data ) {
2041 rc = -ENOMEM;
2042 goto err_alloc;
2043 }
2044
2045 /* Construct temporary form parameter list */
2046 check_len = http_form_params ( params, data,
2047 ( len + 1 /* NUL */ ) );
2048 assert ( check_len == len );
2049
2050 } else {
2051
2052 /* Use GET */
2053 method = &http_get;
2054 type = NULL;
2055 data = NULL;
2056 }
2057
2058 /* Use explicitly requested method name if applicable */
2059 if ( params && params->method ) {
2060 method = http_method ( params->method );
2061 if ( ! method ) {
2062 DBGC ( uri, "HTTP unsupported method \"%s\"\n",
2063 params->method );
2064 rc = -ENOTSUP;
2065 goto err_method;
2066 }
2067 }
2068
2069 /* Construct request content */
2070 content.type = type;
2071 content.data = data;
2072 content.len = len;
2073
2074 /* Open HTTP transaction */
2075 if ( ( rc = http_open ( xfer, method, uri, NULL, &content ) ) != 0 )
2076 goto err_open;
2077
2078 err_open:
2079 err_method:
2080 free ( data );
2081 err_alloc:
2082 return rc;
2083}
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
static size_t http_form_params(struct parameters *params, char *buf, size_t len)
Construct HTTP form parameter list.
Definition httpcore.c:1961
int http_open(struct interface *xfer, struct http_method *method, struct uri *uri, struct http_request_range *range, struct http_request_content *content)
Open HTTP transaction.
Definition httpcore.c:665
HTTP request content descriptor.
Definition http.h:151
const char * method
Request method.
Definition params.h:25

References assert, data, http_request_content::data, DBGC, ENOMEM, ENOTSUP, free, http_form_params(), http_method(), http_open(), http_request_content::len, len, method, parameters::method, NULL, uri::params, rc, http_request_content::type, type, and zalloc().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( http_open )

References http_open().

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_http )

Variable Documentation

◆ __profiler

struct profiler http_xfer_profiler __profiler = { .name = "http.rx" }
static

Receive profiler.

Data transfer profiler.

Definition at line 114 of file httpcore.c.

114{ .name = "http.rx" };

◆ __errortab

struct errortab http_errors [] __errortab
Initial value:
= {
}
#define __einfo_errortab(einfo)
Definition errortab.h:24
#define EINFO_ENOENT_404
Definition httpcore.c:92
#define EINFO_EIO_4XX
Definition httpcore.c:86
#define EINFO_EIO_5XX
Definition httpcore.c:89

Human-readable error messages.

Definition at line 120 of file httpcore.c.

◆ http_request

struct http_state http_request
static
Initial value:
= {
.close = http_close_error,
}
static void http_close_error(struct http_transaction *http, int rc)
Close HTTP transaction with error (even if none specified).
Definition httpcore.c:326
static int http_tx_request(struct http_transaction *http)
Transmit request.
Definition httpcore.c:1149

HTTP request state.

Definition at line 126 of file httpcore.c.

◆ http_headers

struct http_state http_headers
static
Initial value:
= {
.close = http_close_error,
}
static int http_rx_headers(struct http_transaction *http, struct io_buffer **iobuf)
Handle received HTTP headers.
Definition httpcore.c:1560

HTTP response headers state.

Definition at line 127 of file httpcore.c.

Referenced by http_tx_request().

◆ http_trailers

struct http_state http_trailers
static
Initial value:
= {
.close = http_close_error,
}
static int http_rx_trailers(struct http_transaction *http, struct io_buffer **iobuf)
Handle received HTTP trailer.
Definition httpcore.c:1916

HTTP response trailers state.

Definition at line 128 of file httpcore.c.

Referenced by http_rx_chunk_len().

◆ http_transfer_identity

struct http_transfer_encoding http_transfer_identity
static
Initial value:
= {
.name = "identity",
.state = {
},
}
static int http_rx_transfer_identity(struct http_transaction *http, struct io_buffer **iobuf)
Handle received data.
Definition httpcore.c:1658
static void http_close_transfer_identity(struct http_transaction *http, int rc)
Handle server connection close.
Definition httpcore.c:1697
static int http_init_transfer_identity(struct http_transaction *http)
Initialise transfer encoding.
Definition httpcore.c:1639

Identity transfer encoding.

Definition at line 129 of file httpcore.c.

Referenced by http_rx_headers().

◆ __http_method

struct http_method http_put __http_method
Initial value:
= {
.name = "HEAD",
}

HTTP HEAD method.

HTTP PUT method.

HTTP POST method.

HTTP GET method.

Definition at line 139 of file httpcore.c.

139 {
140 .name = "HEAD",
141};

◆ http_xfer_operations

struct interface_operation http_xfer_operations[]
static
Initial value:
= {
}
int block_read_capacity(struct interface *control, struct interface *data)
Read block device capacity.
Definition blockdev.c:106
int block_read(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
Read from block device.
Definition blockdev.c:48
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:945
int http_block_read_capacity(struct http_transaction *http, struct interface *data)
Read block device capacity.
Definition httpblock.c:95
int http_block_read(struct http_transaction *http, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
Read from block device.
Definition httpblock.c:55
static void http_step(struct http_transaction *http)
HTTP transmit process.
Definition httpcore.c:413
static EFI_DEVICE_PATH_PROTOCOL * http_efi_describe(struct http_transaction *http)
Describe as an EFI device path.
Definition httpcore.c:594
#define EFI_INTF_OP
Definition efi.h:381
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33

HTTP data transfer interface operations.

Definition at line 600 of file httpcore.c.

◆ http_xfer_desc

struct interface_descriptor http_xfer_desc
static
Initial value:
=
static struct interface_operation http_xfer_operations[]
HTTP data transfer interface operations.
Definition httpcore.c:600
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition interface.h:98

HTTP data transfer interface descriptor.

Definition at line 611 of file httpcore.c.

Referenced by http_open().

◆ http_content_operations

struct interface_operation http_content_operations[]
static
Initial value:
= {
}
static int http_content_deliver(struct http_transaction *http, struct io_buffer *iobuf, struct xfer_metadata *meta)
Handle received content-decoded data.
Definition httpcore.c:510
static struct xfer_buffer * http_content_buffer(struct http_transaction *http)
Get underlying data transfer buffer.
Definition httpcore.c:543
A data transfer buffer.
Definition xferbuf.h:21

HTTP content-decoded interface operations.

Definition at line 616 of file httpcore.c.

◆ http_content_desc

struct interface_descriptor http_content_desc
static
Initial value:
=
static struct interface_operation http_content_operations[]
HTTP content-decoded interface operations.
Definition httpcore.c:616

HTTP content-decoded interface descriptor.

Definition at line 624 of file httpcore.c.

Referenced by http_open().

◆ http_transfer_operations

struct interface_operation http_transfer_operations[]
static
Initial value:

HTTP transfer-decoded interface operations.

Definition at line 629 of file httpcore.c.

629 {
631};

◆ http_transfer_desc

struct interface_descriptor http_transfer_desc
static
Initial value:
=
static struct interface_operation http_transfer_operations[]
HTTP transfer-decoded interface operations.
Definition httpcore.c:629

HTTP transfer-decoded interface descriptor.

Definition at line 634 of file httpcore.c.

Referenced by http_open().

◆ http_conn_operations

struct interface_operation http_conn_operations[]
static
Initial value:
= {
}
static void http_conn_close(struct http_connection *conn, int rc)
Close HTTP connection.
Definition httpconn.c:95
static int http_conn_deliver(struct http_transaction *http, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle received HTTP data.
Definition httpcore.c:451
void pool_reopen(struct interface *intf)
Reopen a defunct connection.
Definition pool.c:52

HTTP server connection interface operations.

Definition at line 639 of file httpcore.c.

◆ http_conn_desc

struct interface_descriptor http_conn_desc
static
Initial value:
=
static struct interface_operation http_conn_operations[]
HTTP server connection interface operations.
Definition httpcore.c:639

HTTP server connection interface descriptor.

Definition at line 647 of file httpcore.c.

Referenced by http_open().

◆ http_process_desc

struct process_descriptor http_process_desc
static
Initial value:
=
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition process.h:98
A process.
Definition process.h:18

HTTP process descriptor.

Definition at line 652 of file httpcore.c.

Referenced by http_open().

◆ __http_request_header

struct http_request_header http_request_accept_encoding __http_request_header
Initial value:
= {
.name = "Host",
.format = http_format_host,
}
static int http_format_host(struct http_transaction *http, char *buf, size_t len)
Construct HTTP "Host" header.
Definition httpcore.c:978

HTTP "Host" header ".

HTTP "Accept-Encoding" header.

HTTP "Content-Length" header.

HTTP "Content-Type" header.

HTTP "Range" header.

HTTP "Connection" header.

HTTP "User-Agent" header.

Definition at line 986 of file httpcore.c.

986 {
987 .name = "Host",
988 .format = http_format_host,
989};

◆ __http_response_header

struct http_response_header http_response_retry_after __http_response_header
Initial value:
= {
.name = "Location",
}
static int http_parse_location(struct http_transaction *http, char *line)
Parse HTTP "Location" header.
Definition httpcore.c:1373

HTTP "Location" header.

HTTP "Retry-After" header.

HTTP "Content-Encoding" header.

HTTP "Content-Length" header.

HTTP "Connection" header.

HTTP "Transfer-Encoding" header.

Definition at line 1381 of file httpcore.c.

1381 {
1382 .name = "Location",
1383 .parse = http_parse_location,
1384};

◆ __http_transfer_encoding

struct http_transfer_encoding http_transfer_chunked __http_transfer_encoding
Initial value:
= {
.name = "chunked",
.state = {
.close = http_close_error,
},
}
static int http_rx_transfer_chunked(struct http_transaction *http, struct io_buffer **iobuf)
Handle received chunked data.
Definition httpcore.c:1881
static int http_init_transfer_chunked(struct http_transaction *http)
Initialise transfer encoding.
Definition httpcore.c:1747

Chunked transfer encoding.

Definition at line 1893 of file httpcore.c.

1893 {
1894 .name = "chunked",
1896 .state = {
1898 .close = http_close_error,
1899 },
1900};