#include <ipxe/acpi.h>
#include <ipxe/http.h>
+/* Disambiguate the various error causes */
+#define EACCES_401 __einfo_error ( EINFO_EACCES_401 )
+#define EINFO_EACCES_401 \
+ __einfo_uniqify ( EINFO_EACCES, 0x01, "HTTP 401 Unauthorized" )
+#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 EINVAL_RESPONSE __einfo_error ( EINFO_EINVAL_RESPONSE )
+#define EINFO_EINVAL_RESPONSE \
+ __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid content length" )
+#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 ENOENT_404 __einfo_error ( EINFO_ENOENT_404 )
+#define EINFO_ENOENT_404 \
+ __einfo_uniqify ( EINFO_ENOENT, 0x01, "HTTP 404 Not Found" )
+#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" )
+
/** Block size used for HTTP block device request */
#define HTTP_BLKSIZE 512
DBGC ( http, "HTTP %p incorrect length %zd, should be %zd\n",
http, http->rx_len, ( http->rx_len + http->remaining ) );
if ( rc == 0 )
- rc = -EIO;
+ rc = -EIO_CONTENT_LENGTH;
}
/* Remove process */
* isn't correct, force an error
*/
if ( http->remaining != 0 ) {
- http_close ( http, -EIO );
+ http_close ( http, -EIO_CONTENT_LENGTH );
return;
}
case 303:
return 0;
case 404:
- return -ENOENT;
+ return -ENOENT_404;
case 403:
- return -EPERM;
+ return -EPERM_403;
case 401:
- return -EACCES;
+ return -EACCES_401;
default:
- return -EIO;
+ return -EIO_OTHER;
}
}
/* Check response starts with "HTTP/" */
if ( strncmp ( response, "HTTP/", 5 ) != 0 )
- return -EIO;
+ return -EINVAL_RESPONSE;
/* Locate and check response code */
spc = strchr ( response, ' ' );
if ( ! spc )
- return -EIO;
+ return -EINVAL_RESPONSE;
code = strtoul ( spc, NULL, 10 );
if ( ( rc = http_response_to_rc ( code ) ) != 0 )
return rc;
if ( *endp != '\0' ) {
DBGC ( http, "HTTP %p invalid Content-Length \"%s\"\n",
http, value );
- return -EIO;
+ return -EINVAL_CONTENT_LENGTH;
}
/* If we already have an expected content length, and this
if ( http->remaining && ( http->remaining != content_len ) ) {
DBGC ( http, "HTTP %p incorrect Content-Length %zd (expected "
"%zd)\n", http, content_len, http->remaining );
- return -EIO;
+ return -EIO_CONTENT_LENGTH;
}
if ( ! ( http->flags & HTTP_HEAD_ONLY ) )
http->remaining = content_len;
separator = strstr ( header, ": " );
if ( ! separator ) {
DBGC ( http, "HTTP %p malformed header\n", http );
- return -EIO;
+ return -EINVAL_HEADER;
}
*separator = '\0';
value = ( separator + 2 );
if ( *endp != '\0' ) {
DBGC ( http, "HTTP %p invalid chunk length \"%s\"\n",
http, length );
- return -EIO;
+ return -EINVAL_CHUNK_LENGTH;
}
/* Terminate chunked encoding if applicable */
http, iob_len ( iobuf ),
( ( http->rx_state == HTTP_RX_IDLE ) ?
"idle" : "dead" ) );
- rc = -EPROTO;
+ rc = -EPROTO_UNSOLICITED;
goto done;
case HTTP_RX_DEAD:
/* Do no further processing */