summaryrefslogtreecommitdiffstats
path: root/src/core/proto_http.c
diff options
context:
space:
mode:
authorMichael Brown2005-05-01 16:04:11 +0200
committerMichael Brown2005-05-01 16:04:11 +0200
commit85d9eae44ef5e2c48fcbefe36fb7bdfcb54c9f75 (patch)
tree00a1194278710abe5021f8bf00236ca41b14d087 /src/core/proto_http.c
parentAbort immediately if no nameserver is present. (diff)
downloadipxe-85d9eae44ef5e2c48fcbefe36fb7bdfcb54c9f75.tar.gz
ipxe-85d9eae44ef5e2c48fcbefe36fb7bdfcb54c9f75.tar.xz
ipxe-85d9eae44ef5e2c48fcbefe36fb7bdfcb54c9f75.zip
Moved protocols to proto/
Diffstat (limited to 'src/core/proto_http.c')
-rw-r--r--src/core/proto_http.c206
1 files changed, 0 insertions, 206 deletions
diff --git a/src/core/proto_http.c b/src/core/proto_http.c
deleted file mode 100644
index f2dc9dd18..000000000
--- a/src/core/proto_http.c
+++ /dev/null
@@ -1,206 +0,0 @@
-#include "etherboot.h"
-#include "http.h"
-
-#ifdef DOWNLOAD_PROTO_HTTP
-
-/* The block size is currently chosen to be 512 bytes. This means, we can
- allocate the receive buffer on the stack, but it results in a noticeable
- performance penalty.
- This is what needs to be done in order to increase the block size:
- - size negotiation needs to be implemented in TCP
- - the buffer needs to be allocated on the heap
- - path MTU discovery needs to be implemented
-*/ /***/ /* FIXME */
-#define BLOCKSIZE TFTP_DEFAULTSIZE_PACKET
-
-/**************************************************************************
-SEND_TCP_CALLBACK - Send data using TCP
-**************************************************************************/
-struct send_recv_state {
- int (*fnc)(unsigned char *data, int block, int len, int eof);
- char *send_buffer;
- char *recv_buffer;
- int send_length;
- int recv_length;
- int bytes_sent;
- int block;
- int bytes_received;
- enum { RESULT_CODE, HEADER, DATA, ERROR, MOVED } recv_state;
- int rc;
- char location[MAX_URL+1];
-};
-
-static int send_tcp_request(int length, void *buffer, void *ptr) {
- struct send_recv_state *state = (struct send_recv_state *)ptr;
-
- if (length > state->send_length - state->bytes_sent)
- length = state->send_length - state->bytes_sent;
- memcpy(buffer, state->send_buffer + state->bytes_sent, length);
- state->bytes_sent += length;
- return (length);
-}
-
-/**************************************************************************
-RECV_TCP_CALLBACK - Receive data using TCP
-**************************************************************************/
-static int recv_tcp_request(int length, const void *buffer, void *ptr) {
- struct send_recv_state *state = (struct send_recv_state *)ptr;
-
- /* Assume that the lines in an HTTP header do not straddle a packet */
- /* boundary. This is probably a reasonable assumption */
- if (state->recv_state == RESULT_CODE) {
- while (length > 0) {
- /* Find HTTP result code */
- if (*(const char *)buffer == ' ') {
- const char *ptr = ((const char *)buffer) + 1;
- int rc = strtoul(ptr, &ptr, 10);
- if (ptr >= (const char *)buffer + length) {
- state->recv_state = ERROR;
- return 0;
- }
- state->rc = rc;
- state->recv_state = HEADER;
- goto header;
- }
- ++(const char *)buffer;
- length--;
- }
- state->recv_state = ERROR;
- return 0;
- }
- if (state->recv_state == HEADER) {
- header: while (length > 0) {
- /* Check for HTTP redirect */
- if (state->rc >= 300 && state->rc < 400 &&
- !memcmp(buffer, "Location: ", 10)) {
- char *ptr = state->location;
- int i;
- memcpy(ptr, buffer + 10, MAX_URL);
- for (i = 0; i < MAX_URL && *ptr > ' ';
- i++, ptr++);
- *ptr = '\000';
- state->recv_state = MOVED;
- return 1;
- }
- /* Find beginning of line */
- while (length > 0) {
- length--;
- if (*((const char *)buffer)++ == '\n')
- break;
- }
- /* Check for end of header */
- if (length >= 2 && !memcmp(buffer, "\r\n", 2)) {
- state->recv_state = DATA;
- buffer += 2;
- length -= 2;
- break;
- }
- }
- }
- if (state->recv_state == DATA) {
- state->bytes_received += length;
- while (length > 0) {
- int copy_length = BLOCKSIZE - state->recv_length;
- if (copy_length > length)
- copy_length = length;
- memcpy(state->recv_buffer + state->recv_length,
- buffer, copy_length);
- if ((state->recv_length += copy_length) == BLOCKSIZE) {
- if (!state->fnc(state->recv_buffer,
- ++state->block, BLOCKSIZE, 0))
- return 0;
- state->recv_length = 0;
- }
- length -= copy_length;
- buffer += copy_length;
- }
- }
- return 1;
-}
-
-/**************************************************************************
-HTTP_GET - Get data using HTTP
-**************************************************************************/
-int http(const char *url,
- int (*fnc)(unsigned char *, unsigned int, unsigned int, int)) {
- static const char GET[] = "GET /%s HTTP/1.0\r\n\r\n";
- static char recv_buffer[BLOCKSIZE];
- in_addr destip;
- int port;
- int length;
- struct send_recv_state state;
-
- state.fnc = fnc;
- state.rc = -1;
- state.block = 0;
- state.recv_buffer = recv_buffer;
- length = strlen(url);
- if (length <= MAX_URL) {
- memcpy(state.location, url, length+1);
- destip = arptable[ARP_SERVER].ipaddr;
- port = url_port;
- if (port == -1)
- port = 80;
- goto first_time;
-
- do {
- state.rc = -1;
- state.block = 0;
- url = state.location;
- if (memcmp("http://", url, 7))
- break;
- url += 7;
- length = inet_aton(url, &destip);
- if (!length) {
- /* As we do not have support for DNS, assume*/
- /* that HTTP redirects always point to the */
- /* same machine */
- if (state.recv_state == MOVED) {
- while (*url &&
- *url != ':' && *url != '/') url++;
- } else {
- break;
- }
- }
- if (*(url += length) == ':') {
- port = strtoul(url, &url, 10);
- } else {
- port = 80;
- }
- if (!*url)
- url = "/";
- if (*url != '/')
- break;
- url++;
-
- first_time:
- length = strlen(url);
- state.send_length = sizeof(GET) - 3 + length;
-
- { char buf[state.send_length + 1];
- sprintf(state.send_buffer = buf, GET, url);
- state.bytes_sent = 0;
-
- state.bytes_received = 0;
- state.recv_state = RESULT_CODE;
-
- state.recv_length = 0;
- tcp_transaction(destip.s_addr, 80, &state,
- send_tcp_request, recv_tcp_request);
- }
- } while (state.recv_state == MOVED);
- } else {
- memcpy(state.location, url, MAX_URL);
- state.location[MAX_URL] = '\000';
- }
-
- if (state.rc == 200) {
- return fnc(recv_buffer, ++state.block, state.recv_length, 1);
- } else {
- printf("Failed to download %s (rc = %d)\n",
- state.location, state.rc);
- return 0;
- }
-}
-
-#endif /* DOWNLOAD_PROTO_HTTP */