iPXE
Macros | Functions | Variables
httpconn.c File Reference

Hyper Text Transfer Protocol (HTTP) connection management. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/tcpip.h>
#include <ipxe/uri.h>
#include <ipxe/timer.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/pool.h>
#include <ipxe/http.h>

Go to the source code of this file.

Macros

#define HTTP_CONN_EXPIRY   ( 10 * TICKS_PER_SEC )
 HTTP pooled connection expiry time. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static LIST_HEAD (http_connection_pool)
 HTTP connection pool. More...
 
static struct http_schemehttp_scheme (struct uri *uri)
 Identify HTTP scheme. More...
 
static void http_conn_free (struct refcnt *refcnt)
 Free HTTP connection. More...
 
static void http_conn_close (struct http_connection *conn, int rc)
 Close HTTP connection. More...
 
static void http_conn_expired (struct pooled_connection *pool)
 Disconnect idle HTTP connection. More...
 
static int http_conn_socket_deliver (struct http_connection *conn, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive data from transport layer interface. More...
 
static void http_conn_socket_close (struct http_connection *conn, int rc)
 Close HTTP connection transport layer interface. More...
 
static void http_conn_xfer_recycle (struct http_connection *conn)
 Recycle this connection after closing. More...
 
static void http_conn_xfer_close (struct http_connection *conn, int rc)
 Close HTTP connection data transfer interface. More...
 
int http_connect (struct interface *xfer, struct uri *uri)
 Connect to an HTTP server. More...
 

Variables

static struct interface_operation http_conn_socket_operations []
 HTTP connection socket interface operations. More...
 
static struct interface_descriptor http_conn_socket_desc
 HTTP connection socket interface descriptor. More...
 
static struct interface_operation http_conn_xfer_operations []
 HTTP connection data transfer interface operations. More...
 
static struct interface_descriptor http_conn_xfer_desc
 HTTP connection data transfer interface descriptor. More...
 

Detailed Description

Hyper Text Transfer Protocol (HTTP) connection management.

Definition in file httpconn.c.

Macro Definition Documentation

◆ HTTP_CONN_EXPIRY

#define HTTP_CONN_EXPIRY   ( 10 * TICKS_PER_SEC )

HTTP pooled connection expiry time.

Definition at line 46 of file httpconn.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ LIST_HEAD()

static LIST_HEAD ( http_connection_pool  )
static

HTTP connection pool.

◆ http_scheme()

static struct http_scheme* http_scheme ( struct uri uri)
static

Identify HTTP scheme.

Parameters
uriURI
Return values
schemeHTTP scheme, or NULL

Definition at line 57 of file httpconn.c.

57  {
58  struct http_scheme *scheme;
59 
60  /* Sanity check */
61  if ( ! uri->scheme )
62  return NULL;
63 
64  /* Identify scheme */
66  if ( strcmp ( uri->scheme, scheme->name ) == 0 )
67  return scheme;
68  }
69 
70  return NULL;
71 }
const char * scheme
Scheme.
Definition: uri.h:54
const char * name
Scheme name (e.g.
Definition: http.h:41
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
#define HTTP_SCHEMES
HTTP scheme table.
Definition: http.h:56
An HTTP URI scheme.
Definition: http.h:39
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:157
A Uniform Resource Identifier.
Definition: uri.h:50
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References for_each_table_entry, HTTP_SCHEMES, http_scheme::name, NULL, uri::scheme, and strcmp().

Referenced by http_connect().

◆ http_conn_free()

static void http_conn_free ( struct refcnt refcnt)
static

Free HTTP connection.

Parameters
refcntReference count

Definition at line 78 of file httpconn.c.

78  {
79  struct http_connection *conn =
81 
82  /* Free connection */
83  uri_put ( conn->uri );
84  free ( conn );
85 }
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:188
A reference counter.
Definition: refcnt.h:26
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct uri * uri
Connection URI.
Definition: http.h:82
An HTTP connection.
Definition: http.h:73

References container_of, free, http_connection::uri, and uri_put().

Referenced by http_connect().

◆ http_conn_close()

static void http_conn_close ( struct http_connection conn,
int  rc 
)
static

Close HTTP connection.

Parameters
connHTTP connection
rcReason for close

Definition at line 93 of file httpconn.c.

93  {
94 
95  /* Remove from connection pool, if applicable */
96  pool_del ( &conn->pool );
97 
98  /* Shut down interfaces */
99  intf_shutdown ( &conn->socket, rc );
100  intf_shutdown ( &conn->xfer, rc );
101  if ( rc == 0 ) {
102  DBGC2 ( conn, "HTTPCONN %p closed %s://%s\n",
103  conn, conn->scheme->name, conn->uri->host );
104  } else {
105  DBGC ( conn, "HTTPCONN %p closed %s://%s: %s\n",
106  conn, conn->scheme->name, conn->uri->host,
107  strerror ( rc ) );
108  }
109 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
#define DBGC(...)
Definition: compiler.h:505
struct interface socket
Transport layer interface.
Definition: http.h:86
void pool_del(struct pooled_connection *pool)
Remove connection from pool.
Definition: pool.c:82
struct interface xfer
Data transfer interface.
Definition: http.h:88
const char * name
Scheme name (e.g.
Definition: http.h:41
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
const char * host
Host name.
Definition: uri.h:62
struct http_scheme * scheme
HTTP scheme.
Definition: http.h:84
#define DBGC2(...)
Definition: compiler.h:522
struct uri * uri
Connection URI.
Definition: http.h:82
struct pooled_connection pool
Pooled connection.
Definition: http.h:90

References DBGC, DBGC2, uri::host, intf_shutdown(), http_scheme::name, http_connection::pool, pool_del(), rc, http_connection::scheme, http_connection::socket, strerror(), http_connection::uri, and http_connection::xfer.

Referenced by http_conn_expired(), http_conn_socket_close(), http_conn_xfer_close(), and http_connect().

◆ http_conn_expired()

static void http_conn_expired ( struct pooled_connection pool)
static

Disconnect idle HTTP connection.

Parameters
poolPooled connection

Definition at line 116 of file httpconn.c.

116  {
117  struct http_connection *conn =
118  container_of ( pool, struct http_connection, pool );
119 
120  /* Close connection */
121  http_conn_close ( conn, 0 /* Not an error to close idle connection */ );
122 }
timer_init & pool
Definition: pool.h:65
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void http_conn_close(struct http_connection *conn, int rc)
Close HTTP connection.
Definition: httpconn.c:93
An HTTP connection.
Definition: http.h:73

References container_of, http_conn_close(), and pool.

Referenced by http_connect().

◆ http_conn_socket_deliver()

static int http_conn_socket_deliver ( struct http_connection conn,
struct io_buffer iobuf,
struct xfer_metadata meta 
)
static

Receive data from transport layer interface.

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

Definition at line 132 of file httpconn.c.

134  {
135 
136  /* Mark connection as alive */
137  pool_alive ( &conn->pool );
138 
139  /* Pass on to data transfer interface */
140  return xfer_deliver ( &conn->xfer, iobuf, meta );
141 }
struct interface xfer
Data transfer interface.
Definition: http.h:88
int meta(WINDOW *, bool)
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
struct pooled_connection pool
Pooled connection.
Definition: http.h:90

References meta(), http_connection::pool, http_connection::xfer, and xfer_deliver().

◆ http_conn_socket_close()

static void http_conn_socket_close ( struct http_connection conn,
int  rc 
)
static

Close HTTP connection transport layer interface.

Parameters
httpHTTP connection
rcReason for close

Definition at line 149 of file httpconn.c.

149  {
150 
151  /* If we are reopenable (i.e. we are a recycled connection
152  * from the connection pool, and we have received no data from
153  * the underlying socket since we were pooled), then suggest
154  * that the client should reopen the connection.
155  */
156  if ( pool_is_reopenable ( &conn->pool ) )
157  pool_reopen ( &conn->xfer );
158 
159  /* Close the connection */
160  http_conn_close ( conn, rc );
161 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct interface xfer
Data transfer interface.
Definition: http.h:88
void pool_reopen(struct interface *intf)
Reopen a defunct connection.
Definition: pool.c:51
static void http_conn_close(struct http_connection *conn, int rc)
Close HTTP connection.
Definition: httpconn.c:93
struct pooled_connection pool
Pooled connection.
Definition: http.h:90

References http_conn_close(), http_connection::pool, pool_reopen(), rc, and http_connection::xfer.

◆ http_conn_xfer_recycle()

static void http_conn_xfer_recycle ( struct http_connection conn)
static

Recycle this connection after closing.

Parameters
httpHTTP connection

Definition at line 168 of file httpconn.c.

168  {
169 
170  /* Mark connection as recyclable */
171  pool_recyclable ( &conn->pool );
172  DBGC2 ( conn, "HTTPCONN %p keepalive enabled\n", conn );
173 }
#define DBGC2(...)
Definition: compiler.h:522
struct pooled_connection pool
Pooled connection.
Definition: http.h:90

References DBGC2, and http_connection::pool.

◆ http_conn_xfer_close()

static void http_conn_xfer_close ( struct http_connection conn,
int  rc 
)
static

Close HTTP connection data transfer interface.

Parameters
connHTTP connection
rcReason for close

Definition at line 181 of file httpconn.c.

181  {
182 
183  /* Add to the connection pool if keepalive is enabled and no
184  * error occurred.
185  */
186  if ( ( rc == 0 ) && pool_is_recyclable ( &conn->pool ) ) {
187  intf_restart ( &conn->xfer, rc );
188  pool_add ( &conn->pool, &http_connection_pool,
190  DBGC2 ( conn, "HTTPCONN %p pooled %s://%s\n",
191  conn, conn->scheme->name, conn->uri->host );
192  return;
193  }
194 
195  /* Otherwise, close the connection */
196  http_conn_close ( conn, rc );
197 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void pool_add(struct pooled_connection *pool, struct list_head *list, unsigned long expiry)
Add connection to pool.
Definition: pool.c:63
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
struct interface xfer
Data transfer interface.
Definition: http.h:88
const char * name
Scheme name (e.g.
Definition: http.h:41
static void http_conn_close(struct http_connection *conn, int rc)
Close HTTP connection.
Definition: httpconn.c:93
const char * host
Host name.
Definition: uri.h:62
struct http_scheme * scheme
HTTP scheme.
Definition: http.h:84
#define HTTP_CONN_EXPIRY
HTTP pooled connection expiry time.
Definition: httpconn.c:46
#define DBGC2(...)
Definition: compiler.h:522
struct uri * uri
Connection URI.
Definition: http.h:82
struct pooled_connection pool
Pooled connection.
Definition: http.h:90

References DBGC2, uri::host, http_conn_close(), HTTP_CONN_EXPIRY, intf_restart(), http_scheme::name, http_connection::pool, pool_add(), rc, http_connection::scheme, http_connection::uri, and http_connection::xfer.

◆ http_connect()

int http_connect ( struct interface xfer,
struct uri uri 
)

Connect to an HTTP server.

Parameters
xferData transfer interface
uriConnection URI
Return values
rcReturn status code

HTTP connections are pooled. The caller should be prepared to receive a pool_reopen() message.

Definition at line 235 of file httpconn.c.

235  {
236  struct http_connection *conn;
237  struct http_scheme *scheme;
238  struct sockaddr_tcpip server;
239  struct interface *socket;
240  unsigned int port;
241  int rc;
242 
243  /* Identify scheme */
244  scheme = http_scheme ( uri );
245  if ( ! scheme )
246  return -ENOTSUP;
247 
248  /* Sanity check */
249  if ( ! uri->host )
250  return -EINVAL;
251 
252  /* Identify port */
253  port = uri_port ( uri, scheme->port );
254 
255  /* Look for a reusable connection in the pool. Reuse the most
256  * recent connection in order to accommodate authentication
257  * schemes that break the stateless nature of HTTP and rely on
258  * the same connection being reused for authentication
259  * responses.
260  */
261  list_for_each_entry_reverse ( conn, &http_connection_pool, pool.list ) {
262 
263  /* Sanity checks */
264  assert ( conn->uri != NULL );
265  assert ( conn->uri->host != NULL );
266 
267  /* Reuse connection, if possible */
268  if ( ( scheme == conn->scheme ) &&
269  ( strcmp ( uri->host, conn->uri->host ) == 0 ) &&
270  ( port == uri_port ( conn->uri, scheme->port ) ) ) {
271 
272  /* Remove from connection pool, stop timer,
273  * attach to parent interface, and return.
274  */
275  pool_del ( &conn->pool );
276  intf_plug_plug ( &conn->xfer, xfer );
277  DBGC2 ( conn, "HTTPCONN %p reused %s://%s:%d\n", conn,
278  conn->scheme->name, conn->uri->host, port );
279  return 0;
280  }
281  }
282 
283  /* Allocate and initialise structure */
284  conn = zalloc ( sizeof ( *conn ) );
285  if ( ! conn ) {
286  rc = -ENOMEM;
287  goto err_alloc;
288  }
289  ref_init ( &conn->refcnt, http_conn_free );
290  conn->uri = uri_get ( uri );
291  conn->scheme = scheme;
292  intf_init ( &conn->socket, &http_conn_socket_desc, &conn->refcnt );
293  intf_init ( &conn->xfer, &http_conn_xfer_desc, &conn->refcnt );
294  pool_init ( &conn->pool, http_conn_expired, &conn->refcnt );
295 
296  /* Open socket */
297  memset ( &server, 0, sizeof ( server ) );
298  server.st_port = htons ( port );
299  socket = &conn->socket;
300  if ( scheme->filter &&
301  ( ( rc = scheme->filter ( socket, uri->host, &socket ) ) != 0 ) )
302  goto err_filter;
303  if ( ( rc = xfer_open_named_socket ( socket, SOCK_STREAM,
304  ( struct sockaddr * ) &server,
305  uri->host, NULL ) ) != 0 )
306  goto err_open;
307 
308  /* Attach to parent interface, mortalise self, and return */
309  intf_plug_plug ( &conn->xfer, xfer );
310  ref_put ( &conn->refcnt );
311 
312  DBGC2 ( conn, "HTTPCONN %p created %s://%s:%d\n", conn,
313  conn->scheme->name, conn->uri->host, port );
314  return 0;
315 
316  err_open:
317  err_filter:
318  DBGC2 ( conn, "HTTPCONN %p could not create %s://%s:%d: %s\n", conn,
319  conn->scheme->name, conn->uri->host, port, strerror ( rc ) );
320  http_conn_close ( conn, rc );
321  ref_put ( &conn->refcnt );
322  err_alloc:
323  return rc;
324 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
TCP/IP socket address.
Definition: tcpip.h:75
struct refcnt refcnt
Reference count.
Definition: http.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:177
static struct interface_descriptor http_conn_socket_desc
HTTP connection socket interface descriptor.
Definition: httpconn.c:208
timer_init & pool
Definition: pool.h:65
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
unsigned int port
Default port.
Definition: http.h:43
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
struct interface socket
Transport layer interface.
Definition: http.h:86
void pool_del(struct pooled_connection *pool)
Remove connection from pool.
Definition: pool.c:82
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
struct interface xfer
Data transfer interface.
Definition: http.h:88
#define ENOMEM
Not enough space.
Definition: errno.h:534
u8 port
Port number.
Definition: CIB_PRM.h:31
static struct http_scheme * http_scheme(struct uri *uri)
Identify HTTP scheme.
Definition: httpconn.c:57
int(* filter)(struct interface *xfer, const char *name, struct interface **next)
Transport-layer filter (if any)
Definition: http.h:51
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
An object interface.
Definition: interface.h:109
#define list_for_each_entry_reverse(pos, head, member)
Iterate over entries in a list in reverse order.
Definition: list.h:433
const char * name
Scheme name (e.g.
Definition: http.h:41
Generalized socket address structure.
Definition: socket.h:96
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static void http_conn_close(struct http_connection *conn, int rc)
Close HTTP connection.
Definition: httpconn.c:93
#define SOCK_STREAM
Definition: socket.h:24
const char * host
Host name.
Definition: uri.h:62
struct http_scheme * scheme
HTTP scheme.
Definition: http.h:84
An HTTP URI scheme.
Definition: http.h:39
#define DBGC2(...)
Definition: compiler.h:522
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:157
struct uri * uri
Connection URI.
Definition: http.h:82
static void http_conn_free(struct refcnt *refcnt)
Free HTTP connection.
Definition: httpconn.c:78
unsigned int uri_port(const struct uri *uri, unsigned int default_port)
Get port from URI.
Definition: uri.c:441
A Uniform Resource Identifier.
Definition: uri.h:50
static void http_conn_expired(struct pooled_connection *pool)
Disconnect idle HTTP connection.
Definition: httpconn.c:116
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
struct pooled_connection pool
Pooled connection.
Definition: http.h:90
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
An HTTP connection.
Definition: http.h:73
#define htons(value)
Definition: byteswap.h:135
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
Definition: resolv.c:402
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
void * memset(void *dest, int character, size_t len) __nonnull
static struct interface_descriptor http_conn_xfer_desc
HTTP connection data transfer interface descriptor.
Definition: httpconn.c:221

References assert(), DBGC2, EINVAL, ENOMEM, ENOTSUP, http_scheme::filter, uri::host, htons, http_conn_close(), http_conn_expired(), http_conn_free(), http_conn_socket_desc, http_conn_xfer_desc, http_scheme(), intf_init(), intf_plug_plug(), list_for_each_entry_reverse, memset(), http_scheme::name, NULL, pool, http_connection::pool, pool_del(), port, http_scheme::port, rc, ref_init, ref_put, http_connection::refcnt, http_connection::scheme, SOCK_STREAM, http_connection::socket, sockaddr_tcpip::st_port, strcmp(), strerror(), http_connection::uri, uri_get(), uri_port(), http_connection::xfer, xfer_open_named_socket(), and zalloc().

Referenced by http_open(), and http_reopen().

Variable Documentation

◆ http_conn_socket_operations

struct interface_operation http_conn_socket_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
static int http_conn_socket_deliver(struct http_connection *conn, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive data from transport layer interface.
Definition: httpconn.c:132
static void http_conn_socket_close(struct http_connection *conn, int rc)
Close HTTP connection transport layer interface.
Definition: httpconn.c:149
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
An HTTP connection.
Definition: http.h:73

HTTP connection socket interface operations.

Definition at line 200 of file httpconn.c.

◆ http_conn_socket_desc

struct interface_descriptor http_conn_socket_desc
static
Initial value:
=
static struct interface_operation http_conn_socket_operations[]
HTTP connection socket interface operations.
Definition: httpconn.c:200
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:82
An HTTP connection.
Definition: http.h:73

HTTP connection socket interface descriptor.

Definition at line 208 of file httpconn.c.

Referenced by http_connect().

◆ http_conn_xfer_operations

struct interface_operation http_conn_xfer_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
static void http_conn_xfer_close(struct http_connection *conn, int rc)
Close HTTP connection data transfer interface.
Definition: httpconn.c:181
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
void pool_recycle(struct interface *intf)
Recycle this connection after closing.
Definition: pool.c:41
static void http_conn_xfer_recycle(struct http_connection *conn)
Recycle this connection after closing.
Definition: httpconn.c:168
An HTTP connection.
Definition: http.h:73

HTTP connection data transfer interface operations.

Definition at line 213 of file httpconn.c.

◆ http_conn_xfer_desc

struct interface_descriptor http_conn_xfer_desc
static
Initial value:
=
static struct interface_operation http_conn_xfer_operations[]
HTTP connection data transfer interface operations.
Definition: httpconn.c:213
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:82
An HTTP connection.
Definition: http.h:73

HTTP connection data transfer interface descriptor.

Definition at line 221 of file httpconn.c.

Referenced by http_connect().