Browse Source

Made parse_url do more of the processing, to avoid duplicating parts of

nic.c in http.c
tags/v0.9.3
Michael Brown 19 years ago
parent
commit
63482e4fe9
2 changed files with 62 additions and 54 deletions
  1. 58
    38
      src/core/url.c
  2. 4
    16
      src/include/url.h

+ 58
- 38
src/core/url.c View File

@@ -1,42 +1,51 @@
1 1
 #include "string.h"
2
+#include "resolv.h"
3
+#include "etherboot.h" /* for arptable */
2 4
 #include "url.h"
3 5
 
4 6
 /*
5
- * Parse a URL string into its constituent parts.
7
+ * Parse a URL and deduce a struct protocol *, a struct sockaddr_in
8
+ * and a char *filename.
6 9
  *
7 10
  * We accept URLs of the form
8 11
  *
9 12
  *   [protocol://[host][:port]/]path/to/file
10 13
  *
11
- * The URL string will be modified by having NULs inserted after
12
- * "protocol", "host" and "port".  The original URL can be
13
- * reconstructed by calling unparse_url.
14
+ * Returns 1 for success, 0 for failure (e.g. unknown protocol).
14 15
  *
15 16
  */
16
-void parse_url ( struct url_info *info, char *url ) {
17
+int parse_url ( char *url, struct protocol **proto,
18
+		struct sockaddr_in *server, char **filename ) {
17 19
 	char *p;
20
+	char *protocol = NULL;
21
+	char *host = NULL;
22
+	char *port = NULL;
23
+	int rc = 0;
18 24
 
19 25
 	DBG ( "URL parsing \"%s\"\n", url );
20 26
 
21
-	/* Zero the structure */
22
-	memset ( info, 0, sizeof ( *info ) );
27
+	/* If no protocol is present, the whole URL will be a filename */
28
+	*filename = url;
23 29
 
24
-	/* Search for a protocol delimiter */
30
+	/* Search for a protocol delimiter.  If found, parse out the
31
+	 * host and port parts of the URL, inserting NULs to terminate
32
+	 * the different sections.
33
+	 */
25 34
 	for ( p = url ; *p ; p++ ) {
26 35
 		if ( memcmp ( p, "://", 3 ) != 0 )
27 36
 			continue;
28 37
 
29 38
 		/* URL has an explicit protocol */
30
-		info->protocol = url;
31 39
 		*p = '\0';
32 40
 		p += 3;
33
-		info->host = p;
41
+		protocol = url;
42
+		host = p;
34 43
 
35
-		/* Search for port or file delimiter */
44
+		/* Search for port and file delimiters */
36 45
 		for ( ; *p ; p++ ) {
37 46
 			if ( *p == ':' ) {
38 47
 				*p = '\0';
39
-				info->port = p + 1;
48
+				port = p + 1;
40 49
 				continue;
41 50
 			}
42 51
 			if ( *p == '/' ) {
@@ -44,35 +53,46 @@ void parse_url ( struct url_info *info, char *url ) {
44 53
 				break;
45 54
 			}
46 55
 		}
47
-		info->file = p;
48
-		DBG ( "URL protocol \"%s\" host \"%s\" port \"%s\" "
49
-		      "file \"%s\"\n", info->protocol, info->host,
50
-		      info->port ? info->port : "(NONE)", info->file );
51
-		return;
56
+		*filename = p;
57
+
58
+		break;
52 59
 	}
60
+	DBG ( "URL protocol \"%s\" host \"%s\" port \"%s\" file \"%s\"\n",
61
+	      protocol ? protocol : "(default)", host ? host : "(default)",
62
+	      port ? port : "(default)", *filename );
53 63
 
54
-	/* URL has no explicit protocol; is just a filename */
55
-	info->file = url;
56
-	DBG ( "URL file \"%s\"\n", info->file );
57
-}
64
+	/* Identify the protocol */
65
+	*proto = identify_protocol ( protocol );
66
+	if ( ! *proto ) {
67
+		DBG ( "URL unknown protocol \"%s\"\n",
68
+		      protocol ? protocol : "(default)" );
69
+		goto out;
70
+	}
58 71
 
59
-/*
60
- * Restore a parsed URL to its original pristine form.
61
- *
62
- */
63
-char * unparse_url ( struct url_info *info ) {
64
-	if ( info->protocol ) {
65
-		/* URL had a protocol: fill in the deleted separators */
66
-		info->file[-1] = '/';
67
-		if ( info->port ) {
68
-			info->port[-1] = ':';
72
+	/* Identify the host */
73
+	server->sin_addr = arptable[ARP_SERVER].ipaddr;
74
+	if ( host && host[0] ) {
75
+		if ( ! resolv ( &server->sin_addr, host ) ) {
76
+			DBG ( "URL unknown host \"%s\"\n", host );
77
+			goto out;
69 78
 		}
70
-		info->host[-3] = ':';
71
-		DBG ( "URL reconstructed \"%s\"\n", info->protocol );
72
-		return info->protocol;
73
-	} else {
74
-		/* URL had no protocol; was just a filename */
75
-		DBG ( "URL reconstructed \"%s\"\n", info->file );
76
-		return info->file;
77 79
 	}
80
+
81
+	/* Identify the port */
82
+	server->sin_port = (*proto)->default_port;
83
+	if ( port && port[0] ) {
84
+		server->sin_port = strtoul ( port, NULL, 10 );
85
+	}
86
+
87
+	rc = 1;
88
+
89
+ out:
90
+	/* Fill back in the original URL */
91
+	if ( protocol ) {
92
+		(*filename)[-1] = '/';
93
+		if ( port )
94
+			port[-1] = ':';
95
+		host[-3] = ':';
96
+	}
97
+	return rc;
78 98
 }

+ 4
- 16
src/include/url.h View File

@@ -1,22 +1,10 @@
1 1
 #ifndef URL_H
2 2
 #define URL_H
3 3
 
4
-/*
5
- * Information parsed from a URL string.  "char *" pointers will point
6
- * to the start of the relevant portion of the original URL string,
7
- * which will have been modified by inserting terminating NULs at the
8
- * appropriate points.  Use unparse_url() if you want to get back the
9
- * original string.
10
- *
11
- */
12
-struct url_info {
13
-	char *protocol;
14
-	char *host;
15
-	char *port;
16
-	char *file;
17
-};
4
+#include "proto.h"
5
+#include "in.h"
18 6
 
19
-extern void parse_url ( struct url_info *info, char *url );
20
-extern char * unparse_url ( struct url_info *info );
7
+extern int parse_url ( char *url, struct protocol **proto,
8
+		       struct sockaddr_in *server, char **filename );
21 9
 
22 10
 #endif /* URL_H */

Loading…
Cancel
Save