Date: Thu, 12 Jul 2007 14:28:11 GMT From: Alexey Tarasov <taleks@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 123376 for review Message-ID: <200707121428.l6CESBSj045007@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=123376 Change 123376 by taleks@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707121428.l6CESBSj045007>