|
@@ -47,6 +47,38 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
47
|
47
|
#include <ipxe/acpi.h>
|
48
|
48
|
#include <ipxe/http.h>
|
49
|
49
|
|
|
50
|
+/* Disambiguate the various error causes */
|
|
51
|
+#define EACCES_401 __einfo_error ( EINFO_EACCES_401 )
|
|
52
|
+#define EINFO_EACCES_401 \
|
|
53
|
+ __einfo_uniqify ( EINFO_EACCES, 0x01, "HTTP 401 Unauthorized" )
|
|
54
|
+#define EIO_OTHER __einfo_error ( EINFO_EIO_OTHER )
|
|
55
|
+#define EINFO_EIO_OTHER \
|
|
56
|
+ __einfo_uniqify ( EINFO_EIO, 0x01, "Unrecognised HTTP response code" )
|
|
57
|
+#define EIO_CONTENT_LENGTH __einfo_error ( EINFO_EIO_CONTENT_LENGTH )
|
|
58
|
+#define EINFO_EIO_CONTENT_LENGTH \
|
|
59
|
+ __einfo_uniqify ( EINFO_EIO, 0x02, "Content length mismatch" )
|
|
60
|
+#define EINVAL_RESPONSE __einfo_error ( EINFO_EINVAL_RESPONSE )
|
|
61
|
+#define EINFO_EINVAL_RESPONSE \
|
|
62
|
+ __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid content length" )
|
|
63
|
+#define EINVAL_HEADER __einfo_error ( EINFO_EINVAL_HEADER )
|
|
64
|
+#define EINFO_EINVAL_HEADER \
|
|
65
|
+ __einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid header" )
|
|
66
|
+#define EINVAL_CONTENT_LENGTH __einfo_error ( EINFO_EINVAL_CONTENT_LENGTH )
|
|
67
|
+#define EINFO_EINVAL_CONTENT_LENGTH \
|
|
68
|
+ __einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid content length" )
|
|
69
|
+#define EINVAL_CHUNK_LENGTH __einfo_error ( EINFO_EINVAL_CHUNK_LENGTH )
|
|
70
|
+#define EINFO_EINVAL_CHUNK_LENGTH \
|
|
71
|
+ __einfo_uniqify ( EINFO_EINVAL, 0x04, "Invalid chunk length" )
|
|
72
|
+#define ENOENT_404 __einfo_error ( EINFO_ENOENT_404 )
|
|
73
|
+#define EINFO_ENOENT_404 \
|
|
74
|
+ __einfo_uniqify ( EINFO_ENOENT, 0x01, "HTTP 404 Not Found" )
|
|
75
|
+#define EPERM_403 __einfo_error ( EINFO_EPERM_403 )
|
|
76
|
+#define EINFO_EPERM_403 \
|
|
77
|
+ __einfo_uniqify ( EINFO_EPERM, 0x01, "HTTP 403 Forbidden" )
|
|
78
|
+#define EPROTO_UNSOLICITED __einfo_error ( EINFO_EPROTO_UNSOLICITED )
|
|
79
|
+#define EINFO_EPROTO_UNSOLICITED \
|
|
80
|
+ __einfo_uniqify ( EINFO_EPROTO, 0x01, "Unsolicited data" )
|
|
81
|
+
|
50
|
82
|
/** Block size used for HTTP block device request */
|
51
|
83
|
#define HTTP_BLKSIZE 512
|
52
|
84
|
|
|
@@ -146,7 +178,7 @@ static void http_close ( struct http_request *http, int rc ) {
|
146
|
178
|
DBGC ( http, "HTTP %p incorrect length %zd, should be %zd\n",
|
147
|
179
|
http, http->rx_len, ( http->rx_len + http->remaining ) );
|
148
|
180
|
if ( rc == 0 )
|
149
|
|
- rc = -EIO;
|
|
181
|
+ rc = -EIO_CONTENT_LENGTH;
|
150
|
182
|
}
|
151
|
183
|
|
152
|
184
|
/* Remove process */
|
|
@@ -169,7 +201,7 @@ static void http_done ( struct http_request *http ) {
|
169
|
201
|
* isn't correct, force an error
|
170
|
202
|
*/
|
171
|
203
|
if ( http->remaining != 0 ) {
|
172
|
|
- http_close ( http, -EIO );
|
|
204
|
+ http_close ( http, -EIO_CONTENT_LENGTH );
|
173
|
205
|
return;
|
174
|
206
|
}
|
175
|
207
|
|
|
@@ -203,13 +235,13 @@ static int http_response_to_rc ( unsigned int response ) {
|
203
|
235
|
case 303:
|
204
|
236
|
return 0;
|
205
|
237
|
case 404:
|
206
|
|
- return -ENOENT;
|
|
238
|
+ return -ENOENT_404;
|
207
|
239
|
case 403:
|
208
|
|
- return -EPERM;
|
|
240
|
+ return -EPERM_403;
|
209
|
241
|
case 401:
|
210
|
|
- return -EACCES;
|
|
242
|
+ return -EACCES_401;
|
211
|
243
|
default:
|
212
|
|
- return -EIO;
|
|
244
|
+ return -EIO_OTHER;
|
213
|
245
|
}
|
214
|
246
|
}
|
215
|
247
|
|
|
@@ -229,12 +261,12 @@ static int http_rx_response ( struct http_request *http, char *response ) {
|
229
|
261
|
|
230
|
262
|
/* Check response starts with "HTTP/" */
|
231
|
263
|
if ( strncmp ( response, "HTTP/", 5 ) != 0 )
|
232
|
|
- return -EIO;
|
|
264
|
+ return -EINVAL_RESPONSE;
|
233
|
265
|
|
234
|
266
|
/* Locate and check response code */
|
235
|
267
|
spc = strchr ( response, ' ' );
|
236
|
268
|
if ( ! spc )
|
237
|
|
- return -EIO;
|
|
269
|
+ return -EINVAL_RESPONSE;
|
238
|
270
|
code = strtoul ( spc, NULL, 10 );
|
239
|
271
|
if ( ( rc = http_response_to_rc ( code ) ) != 0 )
|
240
|
272
|
return rc;
|
|
@@ -284,7 +316,7 @@ static int http_rx_content_length ( struct http_request *http,
|
284
|
316
|
if ( *endp != '\0' ) {
|
285
|
317
|
DBGC ( http, "HTTP %p invalid Content-Length \"%s\"\n",
|
286
|
318
|
http, value );
|
287
|
|
- return -EIO;
|
|
319
|
+ return -EINVAL_CONTENT_LENGTH;
|
288
|
320
|
}
|
289
|
321
|
|
290
|
322
|
/* If we already have an expected content length, and this
|
|
@@ -293,7 +325,7 @@ static int http_rx_content_length ( struct http_request *http,
|
293
|
325
|
if ( http->remaining && ( http->remaining != content_len ) ) {
|
294
|
326
|
DBGC ( http, "HTTP %p incorrect Content-Length %zd (expected "
|
295
|
327
|
"%zd)\n", http, content_len, http->remaining );
|
296
|
|
- return -EIO;
|
|
328
|
+ return -EIO_CONTENT_LENGTH;
|
297
|
329
|
}
|
298
|
330
|
if ( ! ( http->flags & HTTP_HEAD_ONLY ) )
|
299
|
331
|
http->remaining = content_len;
|
|
@@ -397,7 +429,7 @@ static int http_rx_header ( struct http_request *http, char *header ) {
|
397
|
429
|
separator = strstr ( header, ": " );
|
398
|
430
|
if ( ! separator ) {
|
399
|
431
|
DBGC ( http, "HTTP %p malformed header\n", http );
|
400
|
|
- return -EIO;
|
|
432
|
+ return -EINVAL_HEADER;
|
401
|
433
|
}
|
402
|
434
|
*separator = '\0';
|
403
|
435
|
value = ( separator + 2 );
|
|
@@ -432,7 +464,7 @@ static int http_rx_chunk_len ( struct http_request *http, char *length ) {
|
432
|
464
|
if ( *endp != '\0' ) {
|
433
|
465
|
DBGC ( http, "HTTP %p invalid chunk length \"%s\"\n",
|
434
|
466
|
http, length );
|
435
|
|
- return -EIO;
|
|
467
|
+ return -EINVAL_CHUNK_LENGTH;
|
436
|
468
|
}
|
437
|
469
|
|
438
|
470
|
/* Terminate chunked encoding if applicable */
|
|
@@ -500,7 +532,7 @@ static int http_socket_deliver ( struct http_request *http,
|
500
|
532
|
http, iob_len ( iobuf ),
|
501
|
533
|
( ( http->rx_state == HTTP_RX_IDLE ) ?
|
502
|
534
|
"idle" : "dead" ) );
|
503
|
|
- rc = -EPROTO;
|
|
535
|
+ rc = -EPROTO_UNSOLICITED;
|
504
|
536
|
goto done;
|
505
|
537
|
case HTTP_RX_DEAD:
|
506
|
538
|
/* Do no further processing */
|