PERFORCE change 123897 for review
Alexey Tarasov
taleks at FreeBSD.org
Sun Jul 22 14:15:23 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=123897
Change 123897 by taleks at taleks_th on 2007/07/22 14:15:16
pxe_sock: added pxe_socket_state() funxtion, used to get current socket state.
pxe_http: added support for keep-alive connections and reestablishing of closed connections.
Affected files ...
.. //depot/projects/soc2007/taleks-pxe_http/Makefile#11 edit
.. //depot/projects/soc2007/taleks-pxe_http/httpfs.c#4 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_connection.c#10 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_http.c#8 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_http.h#6 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#16 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.h#14 edit
Differences ...
==== //depot/projects/soc2007/taleks-pxe_http/Makefile#11 (text+ko) ====
@@ -30,6 +30,7 @@
#CFLAGS+= -DPXE_ARP_DEBUG
#CFLAGS+= -DPXE_ARP_DEBUG_HELL
# httpfs module
-#CFLAGS+= -DPXE_HTTP_DEBUG
+CFLAGS+= -DPXE_HTTP_DEBUG
+#CFLAGS+= -DPXE_HTTP_DEBUG_HELL
.include <bsd.lib.mk>
==== //depot/projects/soc2007/taleks-pxe_http/httpfs.c#4 (text+ko) ====
@@ -124,7 +124,10 @@
}
f->f_fsdata = (void *) httpfile;
-
+
+#ifdef PXE_HTTP_DEBUG
+ printf("http_open(): success\n");
+#endif
return (0);
}
@@ -138,7 +141,7 @@
return (EINVAL);
}
-#ifdef PXE_HTTP_DEBUG
+#ifdef PXE_HTTP_DEBUG_HELL
printf("http_read(): %s:%llu+%lu\n",
httpfile->filename, httpfile->offset, size);
#endif
@@ -148,7 +151,7 @@
{
if (resid)
*resid = size;
-#ifdef PXE_HTTP_DEBUG
+#ifdef PXE_HTTP_DEBUG_HELL
printf("http_read(): EOF\n");
#endif
return (0);
==== //depot/projects/soc2007/taleks-pxe_http/pxe_connection.c#10 (text+ko) ====
@@ -536,6 +536,10 @@
if ( (connection->state != PXE_TCP_ESTABLISHED) &&
(recv_buffer->bufleft == recv_buffer->bufsize) )
{
+#ifdef PXE_DEBUG
+ printf("pxe_tcp_read(): state %u, no data in buffer\n",
+ connection->state);
+#endif
return (-1); /* connection closed and no data in buffer */
}
==== //depot/projects/soc2007/taleks-pxe_http/pxe_http.c#8 (text+ko) ====
@@ -91,7 +91,7 @@
if (found == NULL)
return (0); /* failed to parse response code */
-
+
found = strstr(data, "Content-Length:");
parse_data->size = PXE_HTTP_SIZE_UNKNOWN;
@@ -126,8 +126,12 @@
while (count < maxsize - 1) {
result = pxe_recv(socket, &data[count], maxsize - 1 - count);
- if (result == -1) /* failed to recv */
+ if (result == -1) { /* failed to recv */
+#ifdef PXE_HTTP_DEBUG_HELL
+ printf("http_get_header(): pxe_recv() failed\n");
+#endif
break;
+ }
if (result == 0) /* nothing received yet */
continue;
@@ -157,6 +161,65 @@
return (result);
}
+/* http_get_header2() - gets from socket data related to http header
+ * byte by byte.
+ * in:
+ * socket - socket descriptor
+ * data - pointer to working buffer
+ * maxsize - buffer size
+ * found_result - if not NULL, there stored pointer to end of header
+ * count_result - if not NULL, received count stored
+ * out:
+ * -1 - failed
+ * >=0 - success
+ */
+int
+http_get_header2(int socket, char *data, size_t maxsize,
+ char **found_result, size_t *count_result)
+{
+ int result = -1;
+ size_t count = 0;
+ char *found = NULL;
+ char ch = '\0';
+
+ while (count < maxsize - 1) {
+ result = pxe_recv(socket, &data[count], 1);
+
+ if (result == -1) { /* failed to recv */
+#ifdef PXE_HTTP_DEBUG_HELL
+ printf("http_get_header2(): pxe_recv() failed\n");
+#endif
+ break;
+ }
+
+ if (result == 0) /* nothing received yet */
+ continue;
+
+ /* make string ended with '\0' */
+ ch = data[count + result];
+ data[count + result] = '\0';
+
+ /* searching end of reply */
+ found = strstr(&data[count], "\r\n\r\n");
+
+ /* restore char replaced by zero */
+ data[count + result] = ch;
+
+ count += 1;
+
+ if (found != NULL)
+ break;
+ }
+
+ if (found_result)
+ *found_result = found;
+
+ if (count_result)
+ *count_result = count;
+
+ return (result);
+}
+
/* pxe_fetch() - testing function, if size = from = 0, retrieve full file,
* otherwise partial
* in:
@@ -300,23 +363,45 @@
{
size_t size_to_get = (size > 0) ? size : hh->size;
-#ifdef PXE_DEBUG
+#ifdef PXE_HTTP_DEBUG_HELL
printf("pxe_get(): %s:%s:%llu+%lu(%lu:%lu) to 0x%x\n",
inet_ntoa(hh->ip), hh->filename, hh->offset,
size_to_get, size, hh->size, hh->buf);
#endif
if (hh->socket == -1) {
- printf("pxe_get(): socket is not connected.\n");
+ printf("pxe_get(): invalid socket.\n");
return (-1);
}
+
+ if (pxe_socket_state(hh->socket) != PXE_SOCKET_ESTABLISHED) {
+ /* means connection was closed, due e.g. for Apache
+ * - MaxKeepAliveRequests exceeds for that connection
+ * - Waited between read attempts more than KeepAliveTimeout
+ * or
+ * some other problem
+ * need to reestablish connection
+ */
+
+ /* close socket gracefully */
+ pxe_close(hh->socket);
+ hh->socket = -1;
+
+ if (!pxe_exists(hh)) {
+#ifdef PXE_HTTP_DEBUG
+ printf("pxe_get(): connection breaked.\n");
+#endif
+ return (-1);
+ }
+ /* reestablished, continue normal work */
+ }
if ( (size_to_get < PXE_HTTP_SIZE_UNKNOWN) &&
(size_to_get > 0))
{
snprintf(hh->buf, hh->bufsize, "GET %s HTTP/1.1\r\nHost: %s\r\n"
"Range: bytes=%llu-%llu\r\nConnection: keep-alive\r\n"
- "User-Agent: pxe_http/0\r\n\r\n",
+ "Keep-Alive: 300\r\nUser-Agent: pxe_http/0\r\n\r\n",
hh->filename, hh->servername, hh->offset,
hh->offset + size - 1);
} else {
@@ -345,7 +430,7 @@
&found, &count);
if (found == NULL) { /* haven't found end of header */
- printf("pxe_get(): cannot find reply header\n");
+ printf("pxe_get(): cannot find reply header.\n");
return (-1);
}
@@ -354,7 +439,7 @@
pxe_memset(&parse_data, 0, sizeof(PXE_HTTP_PARSE_DATA));
if (!http_reply_parse(hh->buf, count, &parse_data)) {
- printf("pxe_get(): cannot parse reply header\n");
+ printf("pxe_get(): cannot parse reply header.\n");
return (-1);
}
@@ -394,7 +479,7 @@
count += result;
}
-#ifdef PXE_DEBUG
+#ifdef PXE_HTTP_DEBUG_HELL
printf("\npxe_get(): %lu of %lu byte(s) received.\n", count, size);
#endif
@@ -470,7 +555,8 @@
char *found = NULL;
/* retrieve header */
- result = http_get_header(socket, hh->buf, hh->bufsize - 1, &found, &count);
+ result = http_get_header(socket, hh->buf, hh->bufsize - 1,
+ &found, &count);
if (found == NULL) { /* haven't found end of header */
printf("pxe_get_close(): cannot find reply header\n");
@@ -583,8 +669,6 @@
/* retrieve header */
result = http_get_header(socket, hh->buf, hh->bufsize, &found, &count);
-/* pxe_close(socket); */
-
if (found == NULL) { /* haven't found end of header */
pxe_close(socket);
return (0);
==== //depot/projects/soc2007/taleks-pxe_http/pxe_http.h#6 (text+ko) ====
@@ -53,6 +53,9 @@
uint32_t ip; /* web server ip */
off_t offset; /* current offset in bytes from
* beginning of file */
+
+ off_t cache_start; /* cached block, to reduce http requests */
+ uint16_t cache_size; /* size of cached block */
size_t size; /* file size if known */
} PXE_HTTP_HANDLE;
@@ -60,8 +63,8 @@
/* gets requested data from server */
int pxe_get(PXE_HTTP_HANDLE *hh, size_t size, void *buffer);
-/* gets requested data from server */
-int pxe_get2(PXE_HTTP_HANDLE *hh, size_t size, void *buffer);
+/* gets requested data from server, closing connection after */
+int pxe_get_close(PXE_HTTP_HANDLE *hh, size_t size, void *buffer);
/* checks if file exists and fills filesize if known */
int pxe_exists(PXE_HTTP_HANDLE *hh);
==== //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#16 (text+ko) ====
@@ -170,10 +170,6 @@
/* flush data in buffers */
pxe_flush(socket);
- /* socket buffers seems not be used more */
-/* pxe_buffer_memfree(&sock->send_buffer);
- pxe_buffer_memfree(&sock->recv_buffer);
-*/
if (filter == NULL) { /* sanity check */
#ifdef PXE_DEBUG
printf("pxe_close(): filter is NULL.\n");
@@ -777,3 +773,42 @@
return (-1);
}
+
+/* pxe_socket_state() - returns current state of socket
+ * in:
+ * socket - socket descriptor number
+ * out:
+ * -1 - if failed
+ * one of PXE_SOCKET_ state flags otherwise
+ */
+int
+pxe_socket_state(int socket)
+{
+ if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
+ printf("pxe_socket_state(): invalid socket %d.\n", socket);
+ return (-1);
+ }
+
+ PXE_SOCKET *sock = &pxe_sockets[socket];
+ PXE_FILTER_ENTRY *filter = sock->filter;
+
+ if (filter == NULL) {
+#ifdef PXE_DEBUG
+ printf("pxe_socket_state(): NULL filter\n");
+#endif
+ return (PXE_SOCKET_USED);
+ }
+
+ if (filter->protocol == PXE_UDP_PROTOCOL) /* it's always 'established' */
+ return (PXE_SOCKET_ESTABLISHED);
+
+ else if (filter->protocol == PXE_TCP_PROTOCOL) {
+ /* for TCP connections need to check state */
+ PXE_TCP_CONNECTION *connection = filter_to_connection(filter);
+
+ if (connection && (connection->state == PXE_TCP_ESTABLISHED) )
+ return (PXE_SOCKET_ESTABLISHED);
+ }
+
+ return (PXE_SOCKET_CONNECTED);
+}
==== //depot/projects/soc2007/taleks-pxe_http/pxe_sock.h#14 (text+ko) ====
@@ -88,10 +88,8 @@
/* shows socket usage statistics */
void pxe_sock_stats();
-/* returns int socket by pointer to PXE_SOCKET
- * TODO: think about interfaces between pxe_filter and pxe_sock
- */
-int pxe_sock_get(PXE_SOCKET *sock);
+/* returns current socket state */
+int pxe_socket_state(int socket);
/* pxe_listen() - creates "listening" socket
* it's not the same as normal listen() system call.
More information about the p4-projects
mailing list