소스 검색

HTTP/DNS now working fully asynchronously. HTTP/IP addresses and any

other protocol won't work at the moment.
tags/v0.9.3
Michael Brown 18 년 전
부모
커밋
dd6d94004f
6개의 변경된 파일72개의 추가작업 그리고 164개의 파일을 삭제
  1. 2
    0
      src/include/gpxe/http.h
  2. 0
    16
      src/include/usr/fetch.h
  3. 7
    0
      src/net/tcp/ftp.c
  4. 55
    34
      src/net/tcp/http.c
  5. 0
    109
      src/usr/fetch.c
  6. 8
    5
      src/usr/imgmgmt.c

+ 2
- 0
src/include/gpxe/http.h 파일 보기

@@ -41,6 +41,8 @@ struct http_request {
41 41
 	/** HTTP Content-Length */
42 42
 	size_t content_length;
43 43
 
44
+	/** Server address */
45
+	struct sockaddr server;
44 46
 	/** TCP application for this request */
45 47
 	struct tcp_application tcp;
46 48
 	/** Number of bytes already sent */

+ 0
- 16
src/include/usr/fetch.h 파일 보기

@@ -1,16 +0,0 @@
1
-#ifndef _USR_FETCH_H
2
-#define _USR_FETCH_H
3
-
4
-/**
5
- * @file
6
- *
7
- * Fetch file
8
- *
9
- */
10
-
11
-#include <stdint.h>
12
-#include <gpxe/uaccess.h>
13
-
14
-extern int fetch ( const char *uri_string, userptr_t *data, size_t *len );
15
-
16
-#endif /* _USR_FETCH_H */

+ 7
- 0
src/net/tcp/ftp.c 파일 보기

@@ -7,6 +7,7 @@
7 7
 #include <gpxe/async.h>
8 8
 #include <gpxe/buffer.h>
9 9
 #include <gpxe/uri.h>
10
+#include <gpxe/download.h>
10 11
 #include <gpxe/ftp.h>
11 12
 
12 13
 /** @file
@@ -415,3 +416,9 @@ int ftp_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) {
415 416
 	free ( ftp );
416 417
 	return rc;
417 418
 }
419
+
420
+/** HTTP download protocol */
421
+struct download_protocol ftp_download_protocol __download_protocol = {
422
+	.name = "ftp",
423
+	.start_download = ftp_get,
424
+};

+ 55
- 34
src/net/tcp/http.c 파일 보기

@@ -27,12 +27,14 @@
27 27
 #include <stdlib.h>
28 28
 #include <string.h>
29 29
 #include <strings.h>
30
+#include <byteswap.h>
30 31
 #include <errno.h>
31 32
 #include <assert.h>
32 33
 #include <vsprintf.h>
33 34
 #include <gpxe/async.h>
34 35
 #include <gpxe/uri.h>
35 36
 #include <gpxe/buffer.h>
37
+#include <gpxe/download.h>
36 38
 #include <gpxe/http.h>
37 39
 
38 40
 static inline struct http_request *
@@ -366,14 +368,46 @@ static void http_reap ( struct async *async ) {
366 368
 	free ( http );
367 369
 }
368 370
 
371
+/**
372
+ * Handle name resolution completion
373
+ *
374
+ * @v async		HTTP asynchronous operation
375
+ * @v signal		SIGCHLD
376
+ */
377
+static void http_sigchld ( struct async *async, enum signal signal __unused ) {
378
+	struct http_request *http =
379
+		container_of ( async, struct http_request, async );
380
+	struct sockaddr_tcpip *st = ( struct sockaddr_tcpip * ) &http->server;
381
+	int rc;
382
+
383
+	/* Reap child */
384
+	async_wait ( async, &rc, 1 );
385
+
386
+	/* If name resolution failed, abort now */
387
+	if ( rc != 0 ) {
388
+		http_done ( http, rc );
389
+		return;
390
+	}
391
+
392
+	/* Otherwise, start the HTTP connection */
393
+	http->tcp.tcp_op = &http_tcp_operations;
394
+	st->st_port = htons ( uri_port ( http->uri, HTTP_PORT ) );
395
+	if ( ( rc = tcp_connect ( &http->tcp, st, 0 ) ) != 0 ) {
396
+		DBGC ( http, "HTTP %p could not open TCP connection: %s\n",
397
+		       http, strerror ( rc ) );
398
+		http_done ( http, rc );
399
+		return;
400
+	}
401
+}
402
+
369 403
 /** HTTP asynchronous operations */
370 404
 static struct async_operations http_async_operations = {
371
-	.reap			= http_reap,
405
+	.reap = http_reap,
406
+	.signal = {
407
+		[SIGCHLD] = http_sigchld,
408
+	},
372 409
 };
373 410
 
374
-#warning "Quick name resolution hack"
375
-#include <byteswap.h>
376
-
377 411
 /**
378 412
  * Initiate a HTTP connection
379 413
  *
@@ -394,49 +428,36 @@ int http_get ( struct uri *uri, struct buffer *buffer, struct async *parent ) {
394 428
 
395 429
 	/* Allocate and populate HTTP structure */
396 430
 	http = malloc ( sizeof ( *http ) );
397
-	if ( ! http ) {
398
-		rc = -ENOMEM;
399
-		goto err;
400
-	}
431
+	if ( ! http )
432
+		return -ENOMEM;
401 433
 	memset ( http, 0, sizeof ( *http ) );
402 434
 	http->uri = uri;
403 435
 	http->buffer = buffer;
404
-	http->tcp.tcp_op = &http_tcp_operations;
436
+	async_init ( &http->async, &http_async_operations, parent );
437
+
405 438
 
406 439
 #warning "Quick name resolution hack"
407
-	union {
408
-		struct sockaddr_tcpip st;
409
-		struct sockaddr_in sin;
410
-	} server;
411
-	server.sin.sin_port = htons ( HTTP_PORT );
412
-	server.sin.sin_family = AF_INET;
413
-	if ( inet_aton ( uri->host, &server.sin.sin_addr ) == 0 ) {
414
-		/* Try DNS */
415
-		struct async async;
416
-		
417
-		extern int dns_resolv ( const char *name,
418
-					struct sockaddr_tcpip *st,
419
-					struct async *parent );
440
+	extern int dns_resolv ( const char *name,
441
+				struct sockaddr *sa,
442
+				struct async *parent );
420 443
 		
421
-		async_init_orphan ( &async );
422
-		if ( ( rc = dns_resolv ( uri->host, &server.st,
423
-					 &async ) ) != 0 )
424
-			goto err;
425
-		async_wait ( &async, &rc, 1 );
426
-		if ( rc != 0 )
427
-			goto err;
428
-	}
429
-	
430
-
431
-	if ( ( rc = tcp_connect ( &http->tcp, &server.st, 0 ) ) != 0 )
444
+	if ( ( rc = dns_resolv ( uri->host, &http->server,
445
+				 &http->async ) ) != 0 )
432 446
 		goto err;
433 447
 
434
-	async_init ( &http->async, &http_async_operations, parent );
448
+
435 449
 	return 0;
436 450
 
437 451
  err:
438 452
 	DBGC ( http, "HTTP %p could not create request: %s\n", 
439 453
 	       http, strerror ( rc ) );
454
+	async_uninit ( &http->async );
440 455
 	free ( http );
441 456
 	return rc;
442 457
 }
458
+
459
+/** HTTP download protocol */
460
+struct download_protocol http_download_protocol __download_protocol = {
461
+	.name = "http",
462
+	.start_download = http_get,
463
+};

+ 0
- 109
src/usr/fetch.c 파일 보기

@@ -1,109 +0,0 @@
1
-/*
2
- * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License as
6
- * published by the Free Software Foundation; either version 2 of the
7
- * License, or any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful, but
10
- * WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
- * General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, write to the Free Software
16
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
- */
18
-
19
-/**
20
- * @file
21
- *
22
- * Fetch file as executable/loadable image
23
- *
24
- */
25
-
26
-#include <errno.h>
27
-#include <vsprintf.h>
28
-#include <gpxe/umalloc.h>
29
-#include <gpxe/ebuffer.h>
30
-#include <gpxe/image.h>
31
-#include <gpxe/uri.h>
32
-#include <usr/fetch.h>
33
-
34
-#include <byteswap.h>
35
-#include <gpxe/dhcp.h>
36
-#include <gpxe/tftp.h>
37
-#include <gpxe/http.h>
38
-#include <gpxe/ftp.h>
39
-
40
-/**
41
- * Fetch file
42
- *
43
- * @v filename		Filename to fetch
44
- * @ret data		Loaded file
45
- * @ret len		Length of loaded file
46
- * @ret rc		Return status code
47
- *
48
- * Fetch file to an external buffer allocated with umalloc().  The
49
- * caller is responsible for eventually freeing the buffer with
50
- * ufree().
51
- */
52
-int fetch ( const char *uri_string, userptr_t *data, size_t *len ) {
53
-	struct uri *uri;
54
-	struct buffer buffer;
55
-	int rc;
56
-
57
-	/* Parse the URI */
58
-	uri = parse_uri ( uri_string );
59
-	if ( ! uri ) {
60
-		rc = -ENOMEM;
61
-		goto err_parse_uri;
62
-	}
63
-
64
-	/* Allocate an expandable buffer to hold the file */
65
-	if ( ( rc = ebuffer_alloc ( &buffer, 0 ) ) != 0 ) {
66
-		goto err_ebuffer_alloc;
67
-	}
68
-
69
-#warning "Temporary pseudo-URL parsing code"
70
-
71
-	/* Retrieve the file */
72
-	struct async async;
73
-
74
-	int ( * download ) ( struct uri *uri, struct buffer *buffer,
75
-			     struct async *parent );
76
-
77
-	if ( ! uri->scheme ) {
78
-		download = tftp_get;
79
-	} else {
80
-		if ( strcmp ( uri->scheme, "http" ) == 0 ) {
81
-			download = http_get;
82
-		} else if ( strcmp ( uri->scheme, "ftp" ) == 0 ) {
83
-			download = ftp_get;
84
-		} else {
85
-			download = tftp_get;
86
-		}
87
-	}
88
-
89
-	if ( ( rc = async_block ( &async,
90
-				  download ( uri, &buffer, &async ) ) )  != 0 )
91
-		goto err;
92
-
93
-	/* Fill in buffer address and length */
94
-	*data = buffer.addr;
95
-	*len = buffer.fill;
96
-
97
-	/* Release temporary resources.  The ebuffer storage is now
98
-	 * owned by our caller, so we don't free it.
99
-	 */
100
-	free_uri ( uri );
101
-	return 0;
102
-
103
- err:
104
-	ufree ( buffer.addr );
105
- err_ebuffer_alloc:
106
-	free_uri ( uri );
107
- err_parse_uri:
108
-	return rc;
109
-}

+ 8
- 5
src/usr/imgmgmt.c 파일 보기

@@ -22,7 +22,7 @@
22 22
 #include <vsprintf.h>
23 23
 #include <gpxe/image.h>
24 24
 #include <gpxe/umalloc.h>
25
-#include <usr/fetch.h>
25
+#include <gpxe/download.h>
26 26
 #include <usr/imgmgmt.h>
27 27
 
28 28
 /** @file
@@ -34,14 +34,15 @@
34 34
 /**
35 35
  * Fetch an image
36 36
  *
37
- * @v filename		Filename for image
37
+ * @v uri_string	URI as a string (e.g. "http://www.nowhere.com/vmlinuz")
38 38
  * @v name		Name for image, or NULL
39 39
  * @ret new_image	Newly created image
40 40
  * @ret rc		Return status code
41 41
  */
42
-int imgfetch ( const char *filename, const char *name,
42
+int imgfetch ( const char *uri_string, const char *name,
43 43
 	       struct image **new_image ) {
44 44
 	struct image *image;
45
+	struct async async;
45 46
 	int rc;
46 47
 
47 48
 	/* Allocate new image */
@@ -54,8 +55,10 @@ int imgfetch ( const char *filename, const char *name,
54 55
 	if ( name )
55 56
 		strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
56 57
 
57
-	/* Fetch the file */
58
-	if ( ( rc = fetch ( filename, &image->data, &image->len ) ) != 0 )
58
+	/* Download the file */
59
+	if ( ( rc = async_block ( &async, start_download ( uri_string, &async,
60
+							   &image->data,
61
+							   &image->len ))) !=0)
59 62
 		goto err;
60 63
 
61 64
 	/* Register the image */

Loading…
취소
저장