1 //==========================================================================
5 // Stand-alone HTTP support for RedBoot
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2002, 2003 Gary Thomas
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
45 // Contributors: gthomas
50 // This code is part of RedBoot (tm).
52 //####DESCRIPTIONEND####
54 //==========================================================================
56 // HTTP client support
58 #include <redboot.h> // have_net
62 // So we remember which ports have been used
63 static int get_port = 7800;
65 static struct _stream{
67 int avail, actual_len, pos, filelen;
83 http_stream_open(connection_info_t *info, int *err)
86 struct _stream *s = &http_stream;
88 if (!info->server->sin_port)
89 info->server->sin_port = 80; // HTTP port
90 if ((res = __tcp_open(&s->sock, info->server, get_port++, 5000, err)) < 0) {
94 diag_sprintf(s->data, "GET %s HTTP/1.0\r\n\r\n", info->filename);
95 __tcp_write_block(&s->sock, s->data, strlen(s->data));
103 http_stream_close(int *err)
105 struct _stream *s = &http_stream;
108 __tcp_abort(&s->sock,1);
114 http_stream_read(void *buf,
118 struct _stream *s = &http_stream;
123 return -1; // Shouldn't happen, but...
126 while (s->avail == 0) {
127 // Need to wait for some data to arrive
129 if (s->sock.state != _ESTABLISHED) {
130 if (s->sock.state == _CLOSE_WAIT) {
131 // This connection is breaking
132 if (s->sock.data_bytes == 0 && s->sock.rxcnt == 0) {
133 __tcp_close(&s->sock);
136 } else if (s->sock.state == _CLOSED) {
137 // The connection is gone
145 s->actual_len = __tcp_read(&s->sock, s->data, sizeof(s->data));
146 if (s->actual_len > 0) {
148 s->avail = s->actual_len;
150 // First data - need to scan HTTP response header
151 if (strncmp(s->bufp, "HTTP/", 5) == 0) {
152 // Should look like "HTTP/1.1 200 OK"
156 while ((s->avail > 0) && (*s->bufp != ' ')) {
160 // Now the integer response
162 while ((s->avail > 0) && (*s->bufp == ' ')) {
166 while ((s->avail > 0) && isdigit(*s->bufp)) {
167 code = (code * 10) + (*s->bufp - '0');
171 // Make sure it says OK
172 while ((s->avail > 0) && (*s->bufp == ' ')) {
176 if (strncmp(s->bufp, "OK", 2)) {
182 *err = HTTP_FORBIDDEN;
193 // Find \r\n\r\n - end of HTTP preamble
194 while (s->avail >= 4) {
195 // This could be done faster, but not simpler
196 if (strncmp(s->bufp, "\r\n\r\n", 4) == 0) {
199 #if 0 // DEBUG - show header
201 diag_printf(s->data);
210 // Unrecognized response
215 } else if (s->actual_len < 0) {
220 cnt = min(len, s->avail);
221 memcpy(buf, s->bufp, cnt);
224 buf = (char *)buf + cnt;
234 char *errmsg = "Unknown error";
240 return "Unrecognized HTTP response";
242 return "Bad HTTP request (check file name)";
244 return "No such file";
246 return "Can't connect to host";
250 return "Forbidden (check permissions)";
258 GETC_IO_FUNCS(http_io, http_stream_open, http_stream_close,
259 0, http_stream_read, http_error);
260 RedBoot_load(http, http_io, true, true, 0);