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