mirror of
https://github.com/ipxe/ipxe
synced 2025-12-21 04:20:17 +03:00
[http] Rewrite HTTP core to support content encodings
Rewrite the HTTP core to allow for the addition of arbitrary content encoding mechanisms, such as PeerDist and gzip. The core now exposes http_open() which can be used to create requests with an explicitly selected HTTP method, an optional requested content range, and an optional request body. A simple wrapper provides the preexisting behaviour of creating either a GET request or an application/x-www-form-urlencoded POST request (if the URI includes parameters). The HTTP SAN interface is now implemented using the generic block device translator. Individual blocks are requested using http_open() to create a range request. Server connections are now managed via a connection pool; this allows for multiple requests to the same server (e.g. for SAN blocks) to be completely unaware of each other. Repeated HTTPS connections to the same server can reuse a pooled connection, avoiding the per-connection overhead of establishing a TLS session (which can take several seconds if using a client certificate). Support for HTTP SAN booting and for the Basic and Digest authentication schemes is now optional and can be controlled via the SANBOOT_PROTO_HTTP, HTTP_AUTH_BASIC, and HTTP_AUTH_DIGEST build configuration options in config/general.h. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
102
src/net/tcp/httpbasic.c
Normal file
102
src/net/tcp/httpbasic.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Hyper Text Transfer Protocol (HTTP) Basic authentication
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/uri.h>
|
||||
#include <ipxe/base64.h>
|
||||
#include <ipxe/http.h>
|
||||
|
||||
/* Disambiguate the various error causes */
|
||||
#define EACCES_USERNAME __einfo_error ( EINFO_EACCES_USERNAME )
|
||||
#define EINFO_EACCES_USERNAME \
|
||||
__einfo_uniqify ( EINFO_EACCES, 0x01, \
|
||||
"No username available for Basic authentication" )
|
||||
|
||||
/**
|
||||
* Perform HTTP Basic authentication
|
||||
*
|
||||
* @v http HTTP transaction
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int http_basic_authenticate ( struct http_transaction *http ) {
|
||||
struct http_request_auth *req = &http->request.auth;
|
||||
|
||||
/* Record username and password */
|
||||
if ( ! http->uri->user ) {
|
||||
DBGC ( http, "HTTP %p has no username for Basic "
|
||||
"authentication\n", http );
|
||||
return -EACCES_USERNAME;
|
||||
}
|
||||
req->username = http->uri->user;
|
||||
req->password = ( http->uri->password ? http->uri->password : "" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct HTTP "Authorization" header for Basic authentication
|
||||
*
|
||||
* @v http HTTP transaction
|
||||
* @v buf Buffer
|
||||
* @v len Length of buffer
|
||||
* @ret len Length of header value, or negative error
|
||||
*/
|
||||
static int http_format_basic_auth ( struct http_transaction *http,
|
||||
char *buf, size_t len ) {
|
||||
struct http_request_auth *req = &http->request.auth;
|
||||
size_t user_pw_len = ( strlen ( req->username ) + 1 /* ":" */ +
|
||||
strlen ( req->password ) );
|
||||
char user_pw[ user_pw_len + 1 /* NUL */ ];
|
||||
|
||||
/* Sanity checks */
|
||||
assert ( req->username != NULL );
|
||||
assert ( req->password != NULL );
|
||||
|
||||
/* Construct "user:password" string */
|
||||
snprintf ( user_pw, sizeof ( user_pw ), "%s:%s",
|
||||
req->username, req->password );
|
||||
|
||||
/* Construct response */
|
||||
return base64_encode ( user_pw, user_pw_len, buf, len );
|
||||
}
|
||||
|
||||
/** HTTP Basic authentication scheme */
|
||||
struct http_authentication http_basic_auth __http_authentication = {
|
||||
.name = "Basic",
|
||||
.authenticate = http_basic_authenticate,
|
||||
.format = http_format_basic_auth,
|
||||
};
|
||||
|
||||
/* Drag in HTTP authentication support */
|
||||
REQUIRING_SYMBOL ( http_basic_auth );
|
||||
REQUIRE_OBJECT ( httpauth );
|
||||
Reference in New Issue
Block a user