summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/download.c97
-rw-r--r--src/net/tcp/http.c103
2 files changed, 97 insertions, 103 deletions
diff --git a/src/core/download.c b/src/core/download.c
index f748d0233..bc8901272 100644
--- a/src/core/download.c
+++ b/src/core/download.c
@@ -30,6 +30,8 @@
#include <gpxe/ebuffer.h>
#include <gpxe/download.h>
+static struct async_operations download_async_operations;
+
/** Registered download protocols */
static struct download_protocol download_protocols[0]
__table_start ( struct download_protocol, download_protocols );
@@ -53,53 +55,6 @@ static struct download_protocol * find_protocol ( const char *name ) {
return NULL;
}
-/** Free download resources */
-static void download_reap ( struct async *async ) {
- struct download *download =
- container_of ( async, struct download, async );
-
- free ( download );
-}
-
-/**
- * Handle download termination
- *
- * @v async Download asynchronous operation
- * @v signal SIGCHLD
- */
-static void download_sigchld ( struct async *async,
- enum signal signal __unused ) {
- struct download *download =
- container_of ( async, struct download, async );
- int rc;
-
- /* Reap child */
- async_wait ( async, &rc, 1 );
-
- /* Clean up */
- if ( rc == 0 ) {
- /* Transfer ownership of buffer to parent */
- *(download->data) = download->buffer.addr;
- *(download->len) = download->buffer.fill;
- } else {
- /* Discard the buffer */
- ufree ( download->buffer.addr );
- }
- free_uri ( download->uri );
- download->uri = NULL;
-
- /* Terminate ourselves */
- async_done ( async, rc );
-}
-
-/** Download asynchronous operations */
-static struct async_operations download_async_operations = {
- .reap = download_reap,
- .signal = {
- [SIGCHLD] = download_sigchld,
- },
-};
-
/**
* Start download
*
@@ -170,3 +125,51 @@ int start_download ( const char *uri_string, struct async *parent,
free ( download );
return rc;
}
+
+/**
+ * Handle download termination
+ *
+ * @v async Download asynchronous operation
+ * @v signal SIGCHLD
+ */
+static void download_sigchld ( struct async *async,
+ enum signal signal __unused ) {
+ struct download *download =
+ container_of ( async, struct download, async );
+ int rc;
+
+ /* Reap child */
+ async_wait ( async, &rc, 1 );
+
+ /* Clean up */
+ if ( rc == 0 ) {
+ /* Transfer ownership of buffer to parent */
+ *(download->data) = download->buffer.addr;
+ *(download->len) = download->buffer.fill;
+ } else {
+ /* Discard the buffer */
+ ufree ( download->buffer.addr );
+ }
+ free_uri ( download->uri );
+ download->uri = NULL;
+
+ /* Terminate ourselves */
+ async_done ( async, rc );
+}
+
+/**
+ * Free download resources
+ *
+ * @v async Download asynchronous operation
+ */
+static void download_reap ( struct async *async ) {
+ free ( container_of ( async, struct download, async ) );
+}
+
+/** Download asynchronous operations */
+static struct async_operations download_async_operations = {
+ .reap = download_reap,
+ .signal = {
+ [SIGCHLD] = download_sigchld,
+ },
+};
diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c
index 6ae664ad8..84b8e1664 100644
--- a/src/net/tcp/http.c
+++ b/src/net/tcp/http.c
@@ -37,6 +37,8 @@
#include <gpxe/download.h>
#include <gpxe/http.h>
+static struct async_operations http_async_operations;
+
static inline struct http_request *
tcp_to_http ( struct tcp_application *app ) {
return container_of ( app, struct http_request, tcp );
@@ -357,15 +359,45 @@ static struct tcp_operations http_tcp_operations = {
};
/**
- * Reap asynchronous operation
+ * Initiate a HTTP connection
*
- * @v async Asynchronous operation
+ * @v uri Uniform Resource Identifier
+ * @v buffer Buffer into which to download file
+ * @v parent Parent asynchronous operation
+ * @ret rc Return status code
*/
-static void http_reap ( struct async *async ) {
- struct http_request *http =
- container_of ( async, struct http_request, async );
+int http_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) {
+ struct http_request *http = NULL;
+ int rc;
+
+ /* Allocate and populate HTTP structure */
+ http = malloc ( sizeof ( *http ) );
+ if ( ! http )
+ return -ENOMEM;
+ memset ( http, 0, sizeof ( *http ) );
+ http->uri = uri;
+ http->buffer = buffer;
+ async_init ( &http->async, &http_async_operations, parent );
+
+
+#warning "Quick name resolution hack"
+ extern int dns_resolv ( const char *name,
+ struct sockaddr *sa,
+ struct async *parent );
+
+ if ( ( rc = dns_resolv ( uri->host, &http->server,
+ &http->async ) ) != 0 )
+ goto err;
+
+ return 0;
+
+ err:
+ DBGC ( http, "HTTP %p could not create request: %s\n",
+ http, strerror ( rc ) );
+ async_uninit ( &http->async );
free ( http );
+ return rc;
}
/**
@@ -380,10 +412,8 @@ static void http_sigchld ( struct async *async, enum signal signal __unused ) {
struct sockaddr_tcpip *st = ( struct sockaddr_tcpip * ) &http->server;
int rc;
- /* Reap child */
- async_wait ( async, &rc, 1 );
-
/* If name resolution failed, abort now */
+ async_wait ( async, &rc, 1 );
if ( rc != 0 ) {
http_done ( http, rc );
return;
@@ -400,6 +430,15 @@ static void http_sigchld ( struct async *async, enum signal signal __unused ) {
}
}
+/**
+ * Free HTTP connection
+ *
+ * @v async Asynchronous operation
+ */
+static void http_reap ( struct async *async ) {
+ free ( container_of ( async, struct http_request, async ) );
+}
+
/** HTTP asynchronous operations */
static struct async_operations http_async_operations = {
.reap = http_reap,
@@ -408,54 +447,6 @@ static struct async_operations http_async_operations = {
},
};
-/**
- * Initiate a HTTP connection
- *
- * @v uri Uniform Resource Identifier
- * @v buffer Buffer into which to download file
- * @v parent Parent asynchronous operation
- * @ret rc Return status code
- */
-int http_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) {
- struct http_request *http = NULL;
- int rc;
-
- /* Sanity check */
- if ( ! uri->host ) {
- rc = -EINVAL;
- goto err;
- }
-
- /* Allocate and populate HTTP structure */
- http = malloc ( sizeof ( *http ) );
- if ( ! http )
- return -ENOMEM;
- memset ( http, 0, sizeof ( *http ) );
- http->uri = uri;
- http->buffer = buffer;
- async_init ( &http->async, &http_async_operations, parent );
-
-
-#warning "Quick name resolution hack"
- extern int dns_resolv ( const char *name,
- struct sockaddr *sa,
- struct async *parent );
-
- if ( ( rc = dns_resolv ( uri->host, &http->server,
- &http->async ) ) != 0 )
- goto err;
-
-
- return 0;
-
- err:
- DBGC ( http, "HTTP %p could not create request: %s\n",
- http, strerror ( rc ) );
- async_uninit ( &http->async );
- free ( http );
- return rc;
-}
-
/** HTTP download protocol */
struct download_protocol http_download_protocol __download_protocol = {
.name = "http",