PERFORCE change 125737 for review

Alexey Tarasov taleks at FreeBSD.org
Mon Aug 27 02:49:26 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=125737

Change 125737 by taleks at taleks_th on 2007/08/27 09:49:22

	1. Added ability to use non keep-alive connection, if server doesn't support it . This is available if PXE_HTTP_AUTO_KEEPALIVE macro defined.
	2. fixed incorrect request generating in case of root path '/' (leading double slash in URI)
	3. separated fully PXE_IP_WWW and PXE_IP_ROOT. Now must be possible normal usage of proxies.

Affected files ...

.. //depot/projects/soc2007/taleks-pxe_http/Makefile#16 edit
.. //depot/projects/soc2007/taleks-pxe_http/httpfs.c#9 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#27 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#23 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_dhcp.c#10 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_http.c#13 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_http.h#9 edit

Differences ...

==== //depot/projects/soc2007/taleks-pxe_http/Makefile#16 (text+ko) ====

@@ -43,4 +43,8 @@
 # define to send packets freqently to speed up connection
 #CFLAGS+=	-DPXE_TCP_AGRESSIVE
 
+# define to automatically choose non keep-alive method of
+# working, if keep-alive is not supported by server
+CFLAGS+=	-DPXE_HTTP_AUTO_KEEPALIVE
+
 .include <bsd.lib.mk>

==== //depot/projects/soc2007/taleks-pxe_http/httpfs.c#9 (text+ko) ====

@@ -90,7 +90,6 @@
 		return (ENOMEM);
 
 	pxe_memset(httpfile, 0, sizeof(PXE_HTTP_HANDLE));
-								
 
 	httpfile->offset = 0;
 	httpfile->socket = -1;
@@ -183,7 +182,7 @@
 			part1 = pxe_recv(httpfile->socket, addr2,
 				    httpfile->cache_size);
 #ifdef PXE_HTTP_DEBUG_HELL			
-			printf("http_read(): cache > %ld/%lu/%lu/%u bytes\n",
+			printf("http_read(): cache -> %ld/%lu/%lu/%u bytes\n",
 			    part1, to_read, size, httpfile->cache_size);
 #endif
 		}
@@ -194,21 +193,41 @@
 			httpfile->cache_size -= part1;
 		}
 		
-		/* update cache */
+		/* update cache. If auto keep-alive, then skip socket check */
+		PXE_BUFFER *buf = NULL;
+		
+#ifndef PXE_HTTP_AUTO_KEEPALIVE
 		if (httpfile->socket != -1) {
+
 			PXE_BUFFER *buf =
 				    pxe_sock_recv_buffer(httpfile->socket);
-			
+#endif			
 			size_t to_get = httpfile->size - httpfile->offset -
 					((part1 != -1) ? part1 : 0 );
 			
-			if (to_get > buf->bufsize / 2)
-				 to_get = buf->bufsize / 2;
+			if (buf != NULL) {
+				if (to_get > buf->bufsize / 2)
+					to_get = buf->bufsize / 2;
+			} else {
+				if (to_get > PXE_DEFAULT_RECV_BUFSIZE / 2)
+					to_get = PXE_DEFAULT_RECV_BUFSIZE / 2;
+			}
+
 #ifdef PXE_HTTP_DEBUG_HELL
-			printf("http_read(): cache < %lu bytes\n", to_get);
-#endif				
+			printf("http_read(): cache <- %lu bytes\n", to_get);
+#endif			
+			/* if none keep-alive connection, then connection
+			 * is already closed, but we used socket recv buffer
+			 * to store cache data till now. Now, closing socket.
+			 */
+			if ( (httpfile->isKeepAlive == 0) &&
+			     (httpfile->socket != -1) )
+				pxe_close(httpfile->socket);
+				
 			pxe_get(httpfile, to_get, NULL);
+#ifndef PXE_HTTP_AUTO_KEEPALIVE
 		}
+#endif
 	}
 	
 	/* try reading of cache */

==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#27 (text+ko) ====

@@ -143,6 +143,17 @@
         setenv("boot.nfsroot.server", inet_ntoa(tmp_in), 1);
         setenv("boot.nfsroot.path", rootpath, 1);
 #endif
+
+	/* if it's just '/' then make rootpath empty */
+	if (rootpath[1] == '\0')
+		rootpath[0] = '\0';
+	
+	/* check if Web server option specified,
+	 * if not, make it equal to root ip
+	 */
+	if (pxe_get_ip(PXE_IP_WWW)->ip == 0) {
+		pxe_set_ip(PXE_IP_WWW, pxe_get_ip(PXE_IP_ROOT));
+	}
 }
 
 /* pxe_core_init() - performs initialization of all PXE related code

==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#23 (text+ko) ====

@@ -139,8 +139,8 @@
 #define PXE_IP_BROADCAST	5
 #define PXE_IP_SERVER		6
 #define PXE_IP_WWW		7
-#define PXE_IP_ROOT		7
-#define PXE_IP_MAX		8
+#define PXE_IP_ROOT		8
+#define PXE_IP_MAX		9
 const PXE_IPADDR *pxe_get_ip(uint8_t id);
 void pxe_set_ip(uint8_t id, const PXE_IPADDR *ip);
 

==== //depot/projects/soc2007/taleks-pxe_http/pxe_dhcp.c#10 (text+ko) ====

@@ -441,6 +441,7 @@
 	
 	addr.ip = rootip.s_addr;
 	pxe_set_ip(PXE_IP_ROOT, &addr);
+	pxe_set_ip(PXE_IP_WWW, &addr);
 	
 	/* "network route". direct connect for those addresses */
 	pxe_ip_route_add(pxe_get_ip(PXE_IP_MY), netmask, NULL);

==== //depot/projects/soc2007/taleks-pxe_http/pxe_http.c#13 (text+ko) ====

@@ -101,6 +101,13 @@
 	if (found == NULL)
 		return (0);	/* failed to parse response code */
 
+	parse_data->isKeepAlive = 1;
+#ifdef PXE_HTTP_AUTO_KEEPALIVE
+	found = strstr(data, "Connection: close");
+	
+	if (found != NULL)
+		parse_data->isKeepAlive = 0;
+#endif 
 	found = strstr(data, "Content-Length:");
 
 	parse_data->size = PXE_HTTP_SIZE_UNKNOWN;
@@ -156,7 +163,12 @@
 		data[count + result] = ch;
 		
 		count += result;
-		
+
+#ifdef PXE_HTTP_DEBUG_HELL
+		if (found != NULL)
+			printf("%s", data);
+#endif		
+
 		if (found != NULL)
 			break;
 	}
@@ -220,7 +232,7 @@
 #ifdef PXE_HTTP_DEBUG_HELL
 		if (found != NULL)
 			printf("%s", data);
-#endif			
+#endif
 		/* restore char replaced by zero */
 		data[count] = ch;
 		
@@ -416,8 +428,21 @@
 int
 pxe_get(PXE_HTTP_HANDLE *hh, size_t size, void *buffer)
 {
+
 	size_t size_to_get = (size > 0) ? size : hh->size;
 	
+	if (hh->isKeepAlive == 0) {
+#ifdef PXE_HTTP_AUTO_KEEPALIVE
+		/* if connection is not keep-alived, then try pxe_get_close() */
+		return pxe_get_close(hh, size_to_get, buffer);
+#endif
+		printf("pxe_get(): auto keep-alive feature not enabled "
+		       "during compile time. Connection is closed.\n");
+
+		return (-1);
+	}
+
+	
 #ifdef PXE_HTTP_DEBUG_HELL
 	printf("pxe_get(): %s:%s:%llu+%lu(%lu:%lu) to 0x%x\n",
 	    inet_ntoa(hh->addr.ip), hh->filename, hh->offset,
@@ -584,7 +609,7 @@
 	return (count);
 }
 
-#ifdef PXE_MORE
+#if defined(PXE_MORE) || defined(PXE_HTTP_AUTO_KEEPALIVE)
 /* pxe_get_close() - gets portion of file, closing socket after getting
  * in:
  *	hh	- descriptor of file to read data from
@@ -598,17 +623,22 @@
 {
 	size_t size_to_get = (size > 0) ? size : hh->size;
 	
-#ifdef PXE_DEBUG
+#ifdef PXE_HTTP_DEBUG_HELL
 	printf("pxe_get_close(): %s:%s:%llu+%lu(%lu:%lu) to 0x%x\n",
 	    inet_ntoa(hh->addr.ip), hh->filename, hh->offset,
 	    size_to_get, size, hh->size, hh->buf);
 #endif
 	int socket = pxe_socket();
+	
+	if (socket == -1) {
+		printf("pxe_get_close(): failed to create socket.\n");
+		return (-1);
+	}
 
 	int result = pxe_connect(socket, &hh->addr, 80, PXE_TCP_PROTOCOL);
 	
 	if (result == -1) {
-#ifdef PXE_DEBUG
+#ifdef PXE_HTTP_DEBUG
 		printf("pxe_get_close(): failed to connect.\n");
 #endif
 		pxe_close(socket);
@@ -632,6 +662,14 @@
 
 	size_t len = strlen(hh->buf);
 
+#ifdef PXE_HTTPFS_CACHING
+	PXE_HTTP_WAIT_DATA	wait_data;	
+	wait_data.buf = pxe_sock_recv_buffer(socket);
+	/* assuming recv_buffer always is not NULL */
+	wait_data.start_size = pxe_buffer_space(wait_data.buf);
+	wait_data.wait_size = (uint16_t)size;
+	wait_data.socket = socket;
+#endif
 	if (len != pxe_send(socket, hh->buf, len)) {
 		printf("pxe_get_close(): failed to send request.\n");
 		pxe_close(socket);
@@ -647,9 +685,15 @@
 	size_t	count = 0;
 	char	*found = NULL;
 
-	/* retrieve header */	
+	/* retrieve header */
+
+#ifndef PXE_HTTPFS_CACHING
 	result = http_get_header(socket, hh->buf, hh->bufsize - 1,
 		    &found, &count);
+#else
+	result = http_get_header2(socket, hh->buf, hh->bufsize - 1,
+		    &found, &count);
+#endif
 
 	if (found == NULL) {	/* haven't found end of header */
 		printf("pxe_get_close(): cannot find reply header\n");
@@ -688,7 +732,8 @@
 #endif		
 		count = size_to_get;
 	}
-	
+
+#ifndef PXE_HTTPFS_CACHING
 	pxe_memcpy((char *)found + 4, buffer, count);
 	
 	while (count < size_to_get) {
@@ -702,10 +747,11 @@
 		
 		count += result;
 	}
-	
+#ifndef PXE_HTTP_AUTO_KEEPALIVE
 	pxe_close(socket);
+#endif
 
-#ifdef PXE_DEBUG
+#ifdef PXE_HTTP_DEBUG
 	printf("\npxe_get_close(): %lu of %lu byte(s) received.\n",
 	    count, size);
 #endif
@@ -717,10 +763,27 @@
 #endif		       
 		count = size_to_get;
 	}
+#else /* PXE_HTTPFS_CACHING */
+
+	if (wait_data.start_size - pxe_buffer_space(wait_data.buf) < size)
+		/* receiving data, maximum wait 1 minute */
+		pxe_await(http_await, 1, 60000, &wait_data);
 	
+	count = wait_data.start_size -
+		pxe_buffer_space(wait_data.buf);
+
+	hh->cache_size += count;
+
+	hh->socket = socket;
+		
+#ifdef PXE_HTTP_DEBUG
+	printf("%lu read, cache: %lu \n", count, hh->cache_size);
+#endif
+
+#endif /* PXE_HTTPFS_CACHING */
 	return (count);
 }
-#endif
+#endif /* PXE_MORE || PXE_HTTP_AUTO_KEEPALIVE */
 
 /* pxe_exists() - checks if file exists and gets it's size
  * in:
@@ -771,6 +834,7 @@
 		return (0);
 	}
 	
+	
 	/* parse header */
 	PXE_HTTP_PARSE_DATA	parse_data;
 	pxe_memset(&parse_data, 0, sizeof(PXE_HTTP_PARSE_DATA));
@@ -791,8 +855,16 @@
 		return (0);
 	}
 	
+	/* server doesn't support keep-alive connections */
+	if (parse_data.isKeepAlive == 0) {
+		printf("pxe_exists(): Server denied keep-alive connection.\n");
+		pxe_close(socket);
+		socket = -1;
+	}
+	
 	hh->socket = socket;
 	hh->size = parse_data.size;
+	hh->isKeepAlive = parse_data.isKeepAlive;
 
 #ifdef PXE_HTTP_DEBUG
 	printf("pxe_exists(): size = %lu bytes\n", hh->size);

==== //depot/projects/soc2007/taleks-pxe_http/pxe_http.h#9 (text+ko) ====

@@ -62,6 +62,7 @@
 	uint16_t	cache_size;	/* size of cached block */
 #endif
 	size_t		size;		/* file size if known */
+	int		isKeepAlive;	/* if connection keep-alive? */
 } PXE_HTTP_HANDLE;
 
 /* gets requested data from server */
@@ -78,6 +79,9 @@
 typedef struct pxe_http_parse_data {
 	uint16_t	code;	/* response code */
 	size_t		size;	/* size of data if known */
+	int		isKeepAlive;	/* positive if server supports
+					 * keep-alive connections
+					 */
 } PXE_HTTP_PARSE_DATA;
 
 #ifdef PXE_HTTPFS_CACHING


More information about the p4-projects mailing list