PERFORCE change 123376 for review

Alexey Tarasov taleks at FreeBSD.org
Thu Jul 12 14:28:12 UTC 2007


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

Change 123376 by taleks at taleks_th on 2007/07/12 14:27:18

	added new module httpfs to emulate file system.
	pxe_http: changed request header for partial getting to correct format, add pxe_get()  and pxe_exists() to be used from httpfs module.

Affected files ...

.. //depot/projects/soc2007/taleks-pxe_http/Makefile#9 edit
.. //depot/projects/soc2007/taleks-pxe_http/httpfs.c#1 add
.. //depot/projects/soc2007/taleks-pxe_http/httpfs.h#1 add
.. //depot/projects/soc2007/taleks-pxe_http/pxe_http.c#5 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_http.h#3 edit

Differences ...

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

@@ -5,7 +5,7 @@
 
 SRCS= pxe_conv.c pxe_isr.S pxe_mem.c pxe_buffer.c pxe_await.c pxe_arp.c pxe_ip.c pxe_mutex.c \
 	pxe_core.c pxe_icmp.c pxe_udp.c pxe_filter.c pxe_dns.c pxe_dhcp.c pxe_segment.c pxe_tcp.c pxe_sock.c \
-	pxe_connection.c pxe_http.c
+	pxe_connection.c pxe_http.c httpfs.c
 
 CFLAGS+=	-I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \
 		-I${.CURDIR}/../../../contrib/dev/acpica \

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

@@ -78,11 +78,14 @@
  * must be big enough to store size bytes.
  */
 int
-pxe_fetch(char *server_name, char *filename, uint32_t from, uint32_t size, void *where)
+pxe_fetch(char *server_name, char *filename, uint32_t from, uint32_t size)
 {
 	PXE_IPADDR	server;
 	
-	printf("pxe_fetch(): fetching http://%s:80/%s\n", server_name, filename);
+	printf("pxe_fetch(): fetching http://%s:80/%s (%d - %d)\n",
+	    server_name, filename, from, from + size
+	);
+	
 	server.ip = pxe_gethostbyname(server_name);
 	
 	if (server.ip == 0) {
@@ -104,11 +107,11 @@
 	}
 
 	if ( (from == 0) && (size == 0) ) {
-		sprintf(http_data, "GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: Close\r\n\r\n",
+		sprintf(http_data, "GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: Close\r\nUser-Agent: pxe_http/0\r\n\r\n",
 		    filename, server_name
 		);
 	} else {
-		sprintf(http_data, "GET /%s HTTP/1.1\r\nHost: %s\r\nRange: %d-%d\r\nConnection: Close\r\n\r\n",
+		sprintf(http_data, "GET /%s HTTP/1.1\r\nHost: %s\r\nRange: bytes=%d-%d\r\nConnection: Close\r\nUser-Agent: pxe_http/0\r\n\r\n",
 		    filename, server_name, from, from + size
 		);
 	}
@@ -142,7 +145,6 @@
 			continue;
 
 		http_data[count + result] = '\0';
-/*		printf("%s", http_data); */
 		
 		/* end of reply */
 		found = strstr(&http_data[count], "\r\n\r\n");
@@ -167,10 +169,6 @@
 	}
 
 	/* calculating body data offset*/
-/*	result = (found - http_data) + 4; */
-/*	result = count - result;	/* result = size of retirieved part of body */
-/*	count = (found - http_data) + 4; */
-/*	pxe_memcpy(&http_data[count], http_data, result); */
 	
 	printf("pxe_fetch(): response %d, length = %d\n", parse_data.code, parse_data.size);
 	delay(2000000);
@@ -211,3 +209,230 @@
 	
 	return (1);
 }
+
+/* pxe_get() - gets portion of file
+ * in:
+ *	hh	- descriptor of file to read data from
+ *	size	- size of part to read starting at from offset
+ * out:
+ *	-1	- failed
+ *	>=0	- actual bytes read
+ */
+int
+pxe_get(PXE_HTTP_HANDLE *hh, uint32_t size, void *buffer)
+{
+
+#ifdef PXE_DEBUG
+	printf("pxe_get(): 0x%x:%s:%d-%d to 0x%x\n",
+	    hh->ip, hh->filename, hh->offset, hh->offset + size, hh->buf
+	);
+#endif	
+
+	int socket = pxe_socket();
+	
+	int result = pxe_connect(socket, hh->ip, 80, PXE_TCP_PROTOCOL);
+	
+	if (result == -1) {
+#ifdef PXE_DEBUG
+		printf("pxe_get(): failed to connect.\n");
+#endif
+		return (-1);
+	}
+
+	/* hoping that buffer is big enough */
+	sprintf(hh->buf, "GET /%s HTTP/1.1\r\nHost: %s\r\nRange: bytes=%d-%d\r\nConnection: Close\r\nUser-Agent: pxe_http/0\r\n\r\n",
+	    hh->filename, hh->servername, hh->offset, hh->offset + size
+	);
+
+	int len = strlen(hh->buf);
+
+	if (len != pxe_send(socket, hh->buf, len)) {
+		printf("pxe_get(): failed to send request.\n");
+		pxe_close(socket);
+		return (-1);
+	}
+
+	if (pxe_flush(socket) == -1) {
+		printf("pxe_get(): failed to push request.\n");
+		pxe_close(socket);
+		return (-1);
+	}
+
+	int	count = 0;
+	char	*found = NULL;
+	char	ch = 0;
+
+	/* retrieve header */	
+	while (count < hh->bufsize) {
+		result = pxe_recv(socket, &hh->buf[count], hh->bufsize - count);
+		
+		if (result == -1) {
+			break;
+		}
+		
+		if (result == 0)
+			continue;
+
+		/* searching end of reply header */
+		/* found = strnstr(&hh->buf[count], "\r\n\r\n", result); */
+		
+		ch = hh->buf[count + result];
+		found = strstr(&hh->buf[count], "\r\n\r\n");
+		hh->buf[count + result] = ch;
+		
+		count += result;
+		
+		if (found != NULL)
+			break;
+	}
+
+	if (found == NULL) {	/* haven't found end of header */
+		pxe_close(socket);
+		return (-1);
+	}
+	
+	/* parse header */
+	PXE_HTTP_PARSE_DATA	parse_data;
+	pxe_memset(&parse_data, 0, sizeof(PXE_HTTP_PARSE_DATA));
+	
+	if (!http_reply_parse(hh->buf, count, &parse_data)) {
+		pxe_close(socket);
+		return (-1);
+	}
+
+	if ( (parse_data.code < 200) ||
+	     (parse_data.code >= 300) )
+	{
+		printf("pxe_get(): failed to get (status: %d).\n", parse_data.code);
+		pxe_close(socket);
+		return (-1);
+	}
+
+	/* update counter, substruct header size */	
+	count -= (found - http_data) + 4;
+		
+	/* process body data */
+	if (count > size) { /* sanity check, never must be  */
+		count = size;
+		printf("pxe_get(): warning, received more then needed\n");
+	}
+	
+	pxe_memcpy(hh->buf, buffer, count);
+
+	while (count < size) {
+		result = pxe_recv(socket, buffer + count, size - count);
+		
+		if (result == -1) {
+			break;
+		}
+		
+		if (result == 0)
+			continue;
+		
+		count += result;
+	}
+	
+	pxe_close(socket);
+
+#ifdef PXE_DEBUG
+	printf("\npxe_get(): %d of %d byte(s) received.\n", count, size);
+#endif	
+
+	if (count > size) { /* sanity check, never must be */
+		count = size;
+		printf("pxe_get(): warning, received more then needed\n");
+	}
+	
+	return (count);
+}
+
+/* pxe_exists() - checks if file exists and gets it's size
+ * in:
+ *	hh	- descriptor of file to read data from
+ * out:
+ *	0	- failed, not exists
+ *	1	- ok, file exists
+ */
+int
+pxe_exists(PXE_HTTP_HANDLE *hh)
+{
+	int socket = pxe_socket();
+	
+	int result = pxe_connect(socket, hh->ip, 80, PXE_TCP_PROTOCOL);
+	
+	if (result == -1) {
+		return (0);
+	}
+
+	/* hoping that buffer is big enough */
+	sprintf(hh->buf, "HEAD /%s HTTP/1.1\r\nHost: %s\r\nConnection: Close\r\nUser-Agent: pxe_http/0\r\n\r\n",
+	    hh->filename, hh->servername
+	);
+
+	int len = strlen(hh->buf);
+
+	if (len != pxe_send(socket, hh->buf, len)) {
+		printf("pxe_exists(): failed to send request.\n");
+		pxe_close(socket);
+		return (0);
+	}
+
+	if (pxe_flush(socket) == -1) {
+		printf("pxe_exists(): failed to push request.\n");
+		pxe_close(socket);
+		return (0);
+	}
+
+	int	count = 0;
+	char	*found = NULL;
+	char	ch = 0;
+
+	/* retrieve header */	
+	while (count < hh->bufsize) {
+		result = pxe_recv(socket, &hh->buf[count], hh->bufsize - count);
+		
+		if (result == -1) {
+			break;
+		}
+		
+		if (result == 0)
+			continue;
+
+		/* searching end of reply header */
+		/* found = strnstr(&hh->buf[count], "\r\n\r\n", result); */
+		ch = hh->buf[count + result];
+		found = strstr(&hh->buf[count], "\r\n\r\n");
+		hh->buf[count + result] = ch;
+		
+		count += result;
+		
+		if (found != NULL)
+			break;
+	}
+
+	pxe_close(socket);
+	
+	if (found == NULL) {	/* haven't found end of header */
+		return (0);
+	}
+	
+	/* parse header */
+	PXE_HTTP_PARSE_DATA	parse_data;
+	pxe_memset(&parse_data, 0, sizeof(PXE_HTTP_PARSE_DATA));
+	
+	if (!http_reply_parse(hh->buf, count, &parse_data)) {
+		return (0);
+	}
+
+	if ( (parse_data.code < 200) ||
+	     (parse_data.code >= 300) )
+	{
+		printf("pxe_exists(): failed to get header (status: %d).\n", parse_data.code);
+
+		return (0);
+	}
+	
+	hh->size = parse_data.size;
+
+	return (1);
+}

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

@@ -1,10 +1,32 @@
 #ifndef PXE_HTTP_INCLUDED
 #define PXE_HTTP_INCLUDED
 
+#include <sys/types.h>
 #include <stdint.h>
 
 #define PXE_MAX_HTTP_HDRLEN	1024
-int pxe_fetch(char *server, char *filename, uint32_t from, uint32_t size, void* where);
+/* testing function, outputs received data to screen */
+int pxe_fetch(char *server, char *filename, uint32_t from, uint32_t size);
+
+typedef struct pxe_http_handle {
+
+	char		*filename;	/* filename including path on server */
+	char		*servername;	/* server name */
+	
+	char		*buf;		/* buffer for creating requests */
+	uint16_t	bufsize;	/* size of buffer */
+	
+	uint32_t	ip;		/* web server ip */
+	off_t		offset;		/* current offset in bytes from neginning of file */
+
+	size_t		size;		/* file size if known */
+} PXE_HTTP_HANDLE;
+
+/* gets requested data from server */
+int pxe_get(PXE_HTTP_HANDLE *hh, uint32_t size, void *buffer);
+
+/* checks if file exists and fills filesize if known */
+int pxe_exists(PXE_HTTP_HANDLE *hh);
 
 #define PXE_HTTP_SIZE_UNKNOWN	0xffffffff
 


More information about the p4-projects mailing list