Date: Mon, 27 Aug 2007 09:49:25 GMT From: Alexey Tarasov <taleks@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 125737 for review Message-ID: <200708270949.l7R9nPSk053861@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125737 Change 125737 by taleks@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708270949.l7R9nPSk053861>