|
@@ -37,6 +37,8 @@
|
37
|
37
|
#include <gpxe/download.h>
|
38
|
38
|
#include <gpxe/http.h>
|
39
|
39
|
|
|
40
|
+static struct async_operations http_async_operations;
|
|
41
|
+
|
40
|
42
|
static inline struct http_request *
|
41
|
43
|
tcp_to_http ( struct tcp_application *app ) {
|
42
|
44
|
return container_of ( app, struct http_request, tcp );
|
|
@@ -357,15 +359,45 @@ static struct tcp_operations http_tcp_operations = {
|
357
|
359
|
};
|
358
|
360
|
|
359
|
361
|
/**
|
360
|
|
- * Reap asynchronous operation
|
|
362
|
+ * Initiate a HTTP connection
|
361
|
363
|
*
|
362
|
|
- * @v async Asynchronous operation
|
|
364
|
+ * @v uri Uniform Resource Identifier
|
|
365
|
+ * @v buffer Buffer into which to download file
|
|
366
|
+ * @v parent Parent asynchronous operation
|
|
367
|
+ * @ret rc Return status code
|
363
|
368
|
*/
|
364
|
|
-static void http_reap ( struct async *async ) {
|
365
|
|
- struct http_request *http =
|
366
|
|
- container_of ( async, struct http_request, async );
|
|
369
|
+int http_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) {
|
|
370
|
+ struct http_request *http = NULL;
|
|
371
|
+ int rc;
|
|
372
|
+
|
|
373
|
+ /* Allocate and populate HTTP structure */
|
|
374
|
+ http = malloc ( sizeof ( *http ) );
|
|
375
|
+ if ( ! http )
|
|
376
|
+ return -ENOMEM;
|
|
377
|
+ memset ( http, 0, sizeof ( *http ) );
|
|
378
|
+ http->uri = uri;
|
|
379
|
+ http->buffer = buffer;
|
|
380
|
+ async_init ( &http->async, &http_async_operations, parent );
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+#warning "Quick name resolution hack"
|
|
384
|
+ extern int dns_resolv ( const char *name,
|
|
385
|
+ struct sockaddr *sa,
|
|
386
|
+ struct async *parent );
|
|
387
|
+
|
|
388
|
+ if ( ( rc = dns_resolv ( uri->host, &http->server,
|
|
389
|
+ &http->async ) ) != 0 )
|
|
390
|
+ goto err;
|
|
391
|
+
|
367
|
392
|
|
|
393
|
+ return 0;
|
|
394
|
+
|
|
395
|
+ err:
|
|
396
|
+ DBGC ( http, "HTTP %p could not create request: %s\n",
|
|
397
|
+ http, strerror ( rc ) );
|
|
398
|
+ async_uninit ( &http->async );
|
368
|
399
|
free ( http );
|
|
400
|
+ return rc;
|
369
|
401
|
}
|
370
|
402
|
|
371
|
403
|
/**
|
|
@@ -380,10 +412,8 @@ static void http_sigchld ( struct async *async, enum signal signal __unused ) {
|
380
|
412
|
struct sockaddr_tcpip *st = ( struct sockaddr_tcpip * ) &http->server;
|
381
|
413
|
int rc;
|
382
|
414
|
|
383
|
|
- /* Reap child */
|
384
|
|
- async_wait ( async, &rc, 1 );
|
385
|
|
-
|
386
|
415
|
/* If name resolution failed, abort now */
|
|
416
|
+ async_wait ( async, &rc, 1 );
|
387
|
417
|
if ( rc != 0 ) {
|
388
|
418
|
http_done ( http, rc );
|
389
|
419
|
return;
|
|
@@ -400,6 +430,15 @@ static void http_sigchld ( struct async *async, enum signal signal __unused ) {
|
400
|
430
|
}
|
401
|
431
|
}
|
402
|
432
|
|
|
433
|
+/**
|
|
434
|
+ * Free HTTP connection
|
|
435
|
+ *
|
|
436
|
+ * @v async Asynchronous operation
|
|
437
|
+ */
|
|
438
|
+static void http_reap ( struct async *async ) {
|
|
439
|
+ free ( container_of ( async, struct http_request, async ) );
|
|
440
|
+}
|
|
441
|
+
|
403
|
442
|
/** HTTP asynchronous operations */
|
404
|
443
|
static struct async_operations http_async_operations = {
|
405
|
444
|
.reap = http_reap,
|
|
@@ -408,54 +447,6 @@ static struct async_operations http_async_operations = {
|
408
|
447
|
},
|
409
|
448
|
};
|
410
|
449
|
|
411
|
|
-/**
|
412
|
|
- * Initiate a HTTP connection
|
413
|
|
- *
|
414
|
|
- * @v uri Uniform Resource Identifier
|
415
|
|
- * @v buffer Buffer into which to download file
|
416
|
|
- * @v parent Parent asynchronous operation
|
417
|
|
- * @ret rc Return status code
|
418
|
|
- */
|
419
|
|
-int http_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) {
|
420
|
|
- struct http_request *http = NULL;
|
421
|
|
- int rc;
|
422
|
|
-
|
423
|
|
- /* Sanity check */
|
424
|
|
- if ( ! uri->host ) {
|
425
|
|
- rc = -EINVAL;
|
426
|
|
- goto err;
|
427
|
|
- }
|
428
|
|
-
|
429
|
|
- /* Allocate and populate HTTP structure */
|
430
|
|
- http = malloc ( sizeof ( *http ) );
|
431
|
|
- if ( ! http )
|
432
|
|
- return -ENOMEM;
|
433
|
|
- memset ( http, 0, sizeof ( *http ) );
|
434
|
|
- http->uri = uri;
|
435
|
|
- http->buffer = buffer;
|
436
|
|
- async_init ( &http->async, &http_async_operations, parent );
|
437
|
|
-
|
438
|
|
-
|
439
|
|
-#warning "Quick name resolution hack"
|
440
|
|
- extern int dns_resolv ( const char *name,
|
441
|
|
- struct sockaddr *sa,
|
442
|
|
- struct async *parent );
|
443
|
|
-
|
444
|
|
- if ( ( rc = dns_resolv ( uri->host, &http->server,
|
445
|
|
- &http->async ) ) != 0 )
|
446
|
|
- goto err;
|
447
|
|
-
|
448
|
|
-
|
449
|
|
- return 0;
|
450
|
|
-
|
451
|
|
- err:
|
452
|
|
- DBGC ( http, "HTTP %p could not create request: %s\n",
|
453
|
|
- http, strerror ( rc ) );
|
454
|
|
- async_uninit ( &http->async );
|
455
|
|
- free ( http );
|
456
|
|
- return rc;
|
457
|
|
-}
|
458
|
|
-
|
459
|
450
|
/** HTTP download protocol */
|
460
|
451
|
struct download_protocol http_download_protocol __download_protocol = {
|
461
|
452
|
.name = "http",
|