OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [redboot/] [v2_0/] [src/] [net/] [http_client.c] - Blame information for rev 1773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1254 phoenix
//==========================================================================
2
//
3
//      net/http_client.c
4
//
5
//      Stand-alone HTTP support for RedBoot
6
//
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 Gary Thomas
13
//
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.
17
//
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
21
// for more details.
22
//
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.
26
//
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.
33
//
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.
36
//
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####
43
//
44
// Author(s):    gthomas
45
// Contributors: gthomas
46
// Date:         2002-05-22
47
// Purpose:      
48
// Description:  
49
//              
50
// This code is part of RedBoot (tm).
51
//
52
//####DESCRIPTIONEND####
53
//
54
//==========================================================================
55
 
56
// HTTP client support
57
 
58
#include <redboot.h>     // have_net
59
#include <net/net.h>
60
#include <net/http.h>
61
 
62
// So we remember which ports have been used
63
static int get_port = 7800;
64
 
65
static struct _stream{
66
    bool open;
67
    int  avail, actual_len, pos, filelen;
68
    char data[4096];
69
    char *bufp;
70
    tcp_socket_t sock;
71
} http_stream;
72
 
73
static __inline__ int
74
min(int a, int b)
75
{
76
    if (a < b)
77
        return a;
78
    else
79
        return b;
80
}
81
 
82
int
83
http_stream_open(connection_info_t *info, int *err)
84
{
85
    int res;
86
    struct _stream *s = &http_stream;
87
 
88
    info->server->sin_port = 80;  // HTTP port
89
    if ((res = __tcp_open(&s->sock, info->server, get_port++, 5000, err)) < 0) {
90
        *err = HTTP_OPEN;
91
        return -1;
92
    }
93
    diag_sprintf(s->data, "GET %s HTTP/1.0\r\n\r\n", info->filename);
94
    __tcp_write_block(&s->sock, s->data, strlen(s->data));
95
    s->avail = 0;
96
    s->open = true;
97
    s->pos = 0;
98
    return 0;
99
}
100
 
101
void
102
http_stream_close(int *err)
103
{
104
    struct _stream *s = &http_stream;
105
 
106
    if (s->open) {
107
        __tcp_close(&s->sock);
108
        s->open = false;
109
    }
110
}
111
 
112
int
113
http_stream_read(char *buf,
114
                 int len,
115
                 int *err)
116
{
117
    struct _stream *s = &http_stream;
118
    int total = 0;
119
    int cnt, code;
120
 
121
    if (!s->open) {
122
        return -1;  // Shouldn't happen, but...
123
    }
124
    while (len) {
125
        while (s->avail == 0) {
126
            // Need to wait for some data to arrive
127
            __tcp_poll();
128
            if (s->sock.state != _ESTABLISHED) {
129
                if (s->sock.state == _CLOSE_WAIT) {
130
                    // This connection is breaking
131
                    if (s->sock.data_bytes == 0 && s->sock.rxcnt == 0) {
132
                        __tcp_close(&s->sock);
133
                        return total;
134
                    }
135
                } else if (s->sock.state == _CLOSED) {
136
                        // The connection is gone
137
                        s->open = false;
138
                        return -1;
139
                } else {
140
                    *err = HTTP_IO;
141
                    return -1;
142
                }
143
            }
144
            s->actual_len = __tcp_read(&s->sock, s->data, sizeof(s->data));
145
            if (s->actual_len > 0) {
146
                s->bufp = s->data;
147
                s->avail = s->actual_len;
148
                if (s->pos == 0) {
149
                    // First data - need to scan HTTP response header
150
                    if (strncmp(s->bufp, "HTTP/", 5) == 0) {
151
                        // Should look like "HTTP/1.1 200 OK"
152
                        s->bufp += 5;
153
                        s->avail -= 5;
154
                        // Find first space
155
                        while ((s->avail > 0) && (*s->bufp != ' ')) {
156
                            s->bufp++;
157
                            s->avail--;
158
                        }
159
                        // Now the integer response
160
                        code = 0;
161
                        while ((s->avail > 0) && (*s->bufp == ' ')) {
162
                            s->bufp++;
163
                            s->avail--;
164
                        }
165
                        while ((s->avail > 0) && isdigit(*s->bufp)) {
166
                            code = (code * 10) + (*s->bufp - '0');
167
                            s->bufp++;
168
                            s->avail--;
169
                        }
170
                        // Make sure it says OK
171
                        while ((s->avail > 0) && (*s->bufp == ' ')) {
172
                            s->bufp++;
173
                            s->avail--;
174
                        }
175
                        if (strncmp(s->bufp, "OK", 2)) {
176
                            *err = HTTP_BADHDR;
177
                            return -1;
178
                        }
179
                        // Find \r\n\r\n - end of HTTP preamble
180
                        while (s->avail > 4) {
181
                            // This could be done faster, but not simpler
182
                            if (strncmp(s->bufp, "\r\n\r\n", 4) == 0) {
183
                                s->bufp += 4;
184
                                s->avail -= 4;
185
#if 0 // DEBUG - show header
186
                                *(s->bufp-2) = '\0';
187
                                diag_printf(s->data);
188
#endif
189
                                break;
190
                            }
191
                            s->avail--;
192
                            s->bufp++;
193
                        }
194
                        s->pos++;
195
                    } else {
196
                        // Unrecognized response
197
                        *err = HTTP_BADHDR;
198
                        return -1;
199
                    }
200
                }
201
            } else if (s->actual_len < 0) {
202
                *err = HTTP_IO;
203
                return -1;
204
            }
205
        }
206
        cnt = min(len, s->avail);
207
        memcpy(buf, s->bufp, cnt);
208
        s->avail -= cnt;
209
        s->bufp += cnt;
210
        buf += cnt;
211
        total += cnt;
212
        len -= cnt;
213
    }
214
    return total;
215
}
216
 
217
char *
218
http_error(int err)
219
{
220
    char *errmsg = "Unknown error";
221
 
222
    switch (err) {
223
    case HTTP_NOERR:
224
        return "";
225
    case HTTP_BADHDR:
226
        return "Unrecognized HTTP response";
227
    case HTTP_OPEN:
228
        return "Can't connect to host";
229
    case HTTP_IO:
230
        return "I/O error";
231
    }
232
    return errmsg;
233
}
234
 
235
//
236
// RedBoot interface
237
//
238
GETC_IO_FUNCS(http_io, http_stream_open, http_stream_close,
239
              0, http_stream_read, http_error);
240
RedBoot_load(http, http_io, true, true, 0);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.