summaryrefslogtreecommitdiffstats
path: root/src/net/tcp/httpcore.c
diff options
context:
space:
mode:
authorMichael Brown2012-08-15 17:29:22 +0200
committerMichael Brown2012-08-15 17:29:22 +0200
commit501527daab88a2911f5309d5215decf7011a7fde (patch)
tree067bb5e8eea2e2f3762aefd12474306754eaa8bf /src/net/tcp/httpcore.c
parent[util] Fix up checksum in UNDI ROM header, if present (diff)
downloadipxe-501527daab88a2911f5309d5215decf7011a7fde.tar.gz
ipxe-501527daab88a2911f5309d5215decf7011a7fde.tar.xz
ipxe-501527daab88a2911f5309d5215decf7011a7fde.zip
[http] Treat any unexpected connection close as an error
iPXE currently checks that the server has not closed the connection mid-stream (i.e. in the middle of a chunked transfer, or before the specified Content-Length has been received), but does not check that the server got as far as starting to send data. Consequently, if the server closes the connection before any data is transferred (e.g. if the server gives up waiting while iPXE performs the validation steps for TLS), then iPXE will treat this as a successful transfer of a zero-length file. Fix by checking the RX connection state, and forcing an error if the server has closed the connection at an unexpected point. Originally-fixed-by: Marin Hannache <mareo@mareo.fr> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/tcp/httpcore.c')
-rw-r--r--src/net/tcp/httpcore.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/src/net/tcp/httpcore.c b/src/net/tcp/httpcore.c
index 432c30d5..534e5a78 100644
--- a/src/net/tcp/httpcore.c
+++ b/src/net/tcp/httpcore.c
@@ -60,9 +60,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
#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_CHUNK __einfo_error ( EINFO_EIO_CHUNK )
-#define EINFO_EIO_CHUNK \
- __einfo_uniqify ( EINFO_EIO, 0x03, "Terminated mid-chunk" )
#define EINVAL_RESPONSE __einfo_error ( EINFO_EINVAL_RESPONSE )
#define EINFO_EINVAL_RESPONSE \
__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid content length" )
@@ -111,7 +108,14 @@ enum http_rx_state {
HTTP_RX_RESPONSE = 0,
HTTP_RX_HEADER,
HTTP_RX_CHUNK_LEN,
+ /* In HTTP_RX_DATA, it is acceptable for the server to close
+ * the connection (unless we are in the middle of a chunked
+ * transfer).
+ */
HTTP_RX_DATA,
+ /* In the following states, it is acceptable for the server to
+ * close the connection.
+ */
HTTP_RX_TRAILER,
HTTP_RX_IDLE,
HTTP_RX_DEAD,
@@ -251,10 +255,14 @@ static int http_socket_open ( struct http_request *http ) {
static void http_done ( struct http_request *http ) {
int rc;
- /* If we are in the middle of a chunked transfer, force an error */
- if ( http->chunked ) {
- DBGC ( http, "HTTP %p terminated mid-chunk\n", http );
- http_close ( http, -EIO_CHUNK );
+ /* If we are not at an appropriate stage of the protocol
+ * (including being in the middle of a chunked transfer),
+ * force an error.
+ */
+ if ( ( http->rx_state < HTTP_RX_DATA ) || ( http->chunked != 0 ) ) {
+ DBGC ( http, "HTTP %p connection closed unexpectedly\n",
+ http );
+ http_close ( http, -ECONNRESET );
return;
}