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