3
3
// Released under Apache License, version 2.0
4
4
5
5
#include " HttpClient.h"
6
- #include < ../ b64/b64.h >
6
+ #include " b64.h "
7
7
#include < Dns.h>
8
8
#include < string.h>
9
9
#include < ctype.h>
@@ -46,11 +46,17 @@ void HttpClient::stop()
46
46
resetState ();
47
47
}
48
48
49
- int HttpClient::startRequest ( const char * aServerName, uint16_t aServerPort, const char * aURLPath, const char * aHttpMethod, const char * aUserAgent, const char * aAcceptList )
49
+ void HttpClient::beginRequest ( )
50
50
{
51
- if (eIdle != iState)
51
+ iState = eRequestStarted;
52
+ }
53
+
54
+ int HttpClient::startRequest (const char * aServerName, uint16_t aServerPort, const char * aURLPath, const char * aHttpMethod, const char * aUserAgent)
55
+ {
56
+ tHttpState initialState = iState;
57
+ if ((eIdle != iState) && (eRequestStarted != iState))
52
58
{
53
- return HttpErrAPI ;
59
+ return HTTP_ERROR_API ;
54
60
}
55
61
56
62
if (iProxyPort)
@@ -60,7 +66,7 @@ int HttpClient::startRequest(const char* aServerName, uint16_t aServerPort, cons
60
66
#ifdef LOGGING
61
67
Serial.println (" Proxy connection failed" );
62
68
#endif
63
- return HttpErrConnectionFailed ;
69
+ return HTTP_ERROR_CONNECTION_FAILED ;
64
70
}
65
71
}
66
72
else
@@ -70,19 +76,28 @@ int HttpClient::startRequest(const char* aServerName, uint16_t aServerPort, cons
70
76
#ifdef LOGGING
71
77
Serial.println (" Connection failed" );
72
78
#endif
73
- return HttpErrConnectionFailed ;
79
+ return HTTP_ERROR_CONNECTION_FAILED ;
74
80
}
75
81
}
76
82
77
83
// Now we're connected, send the first part of the request
78
- return sendInitialHeaders (aServerName, IPAddress (0 ,0 ,0 ,0 ), aServerPort, aURLPath, aHttpMethod, aUserAgent, aAcceptList);
84
+ int ret = sendInitialHeaders (aServerName, IPAddress (0 ,0 ,0 ,0 ), aServerPort, aURLPath, aHttpMethod, aUserAgent);
85
+ if ((initialState == eIdle) && (HTTP_SUCCESS == ret))
86
+ {
87
+ // This was a simple version of the API, so terminate the headers now
88
+ finishHeaders ();
89
+ }
90
+ // else we'll call it in endRequest or in the first call to print, etc.
91
+
92
+ return ret;
79
93
}
80
94
81
- int HttpClient::startRequest (const IPAddress& aServerAddress, uint16_t aServerPort, const char * aServerName, const char * aURLPath , const char * aHttpMethod , const char * aUserAgent , const char * aAcceptList )
95
+ int HttpClient::startRequest (const IPAddress& aServerAddress, const char * aServerName, uint16_t aServerPort , const char * aURLPath , const char * aHttpMethod , const char * aUserAgent )
82
96
{
83
- if (eIdle != iState)
97
+ tHttpState initialState = iState;
98
+ if ((eIdle != iState) && (eRequestStarted != iState))
84
99
{
85
- return HttpErrAPI ;
100
+ return HTTP_ERROR_API ;
86
101
}
87
102
88
103
if (iProxyPort)
@@ -92,7 +107,7 @@ int HttpClient::startRequest(const IPAddress& aServerAddress, uint16_t aServerPo
92
107
#ifdef LOGGING
93
108
Serial.println (" Proxy connection failed" );
94
109
#endif
95
- return HttpErrConnectionFailed ;
110
+ return HTTP_ERROR_CONNECTION_FAILED ;
96
111
}
97
112
}
98
113
else
@@ -102,95 +117,96 @@ int HttpClient::startRequest(const IPAddress& aServerAddress, uint16_t aServerPo
102
117
#ifdef LOGGING
103
118
Serial.println (" Connection failed" );
104
119
#endif
105
- return HttpErrConnectionFailed ;
120
+ return HTTP_ERROR_CONNECTION_FAILED ;
106
121
}
107
122
}
108
123
109
124
// Now we're connected, send the first part of the request
110
- return sendInitialHeaders (aServerName, aServerAddress, aServerPort, aURLPath, aHttpMethod, aUserAgent, aAcceptList);
125
+ int ret = sendInitialHeaders (aServerName, aServerAddress, aServerPort, aURLPath, aHttpMethod, aUserAgent);
126
+ if ((initialState == eIdle) && (HTTP_SUCCESS == ret))
127
+ {
128
+ // This was a simple version of the API, so terminate the headers now
129
+ finishHeaders ();
130
+ }
131
+ // else we'll call it in endRequest or in the first call to print, etc.
132
+
133
+ return ret;
111
134
}
112
135
113
- int HttpClient::sendInitialHeaders (const char * aServerName, IPAddress aServerIP, uint16_t aPort, const char * aURLPath, const char * aHttpMethod, const char * aUserAgent, const char * aAcceptList )
136
+ int HttpClient::sendInitialHeaders (const char * aServerName, IPAddress aServerIP, uint16_t aPort, const char * aURLPath, const char * aHttpMethod, const char * aUserAgent)
114
137
{
115
138
#ifdef LOGGING
116
139
Serial.println (" Connected" );
117
140
#endif
118
141
// Send the HTTP command, i.e. "GET /somepath/ HTTP/1.0"
119
- print (aHttpMethod);
120
- print (" " );
142
+ iClient-> print (aHttpMethod);
143
+ iClient-> print (" " );
121
144
if (iProxyPort)
122
145
{
123
146
// We're going through a proxy, send a full URL
124
- print (" http://" );
147
+ iClient-> print (" http://" );
125
148
if (aServerName)
126
149
{
127
150
// We've got a server name, so use it
128
- print (aServerName);
151
+ iClient-> print (aServerName);
129
152
}
130
153
else
131
154
{
132
155
// We'll have to use the IP address
133
- print (aServerIP);
156
+ iClient-> print (aServerIP);
134
157
}
135
158
if (aPort != kHttpPort )
136
159
{
137
- print (" :" );
138
- print (aPort);
160
+ iClient-> print (" :" );
161
+ iClient-> print (aPort);
139
162
}
140
163
}
141
- print (aURLPath);
142
- println (" HTTP/1.0" );
164
+ iClient-> print (aURLPath);
165
+ iClient-> println (" HTTP/1.0" );
143
166
// The host header, if required
144
167
if (aServerName)
145
168
{
146
- // print("Host: ");
147
- // println(aServerName);
169
+ sendHeader (" Host" , aServerName);
148
170
}
149
171
// And user-agent string
150
- print (" User-Agent: " );
172
+ iClient-> print (" User-Agent: " );
151
173
if (aUserAgent)
152
174
{
153
- println (aUserAgent);
175
+ iClient-> println (aUserAgent);
154
176
}
155
177
else
156
178
{
157
- println (kUserAgent );
158
- }
159
- if (aAcceptList)
160
- {
161
- // We've got an accept list to send
162
- print (" Accept: " );
163
- println (aAcceptList);
179
+ iClient->println (kUserAgent );
164
180
}
165
181
166
182
// Everything has gone well
167
183
iState = eRequestStarted;
168
- return HttpSuccess ;
184
+ return HTTP_SUCCESS ;
169
185
}
170
186
171
187
void HttpClient::sendHeader (const char * aHeader)
172
188
{
173
- println (aHeader);
189
+ iClient-> println (aHeader);
174
190
}
175
191
176
192
void HttpClient::sendHeader (const char * aHeaderName, const char * aHeaderValue)
177
193
{
178
- print (aHeaderName);
179
- print (" : " );
180
- println (aHeaderValue);
194
+ iClient-> print (aHeaderName);
195
+ iClient-> print (" : " );
196
+ iClient-> println (aHeaderValue);
181
197
}
182
198
183
199
void HttpClient::sendHeader (const char * aHeaderName, const int aHeaderValue)
184
200
{
185
- print (aHeaderName);
186
- print (" : " );
187
- println (aHeaderValue);
201
+ iClient-> print (aHeaderName);
202
+ iClient-> print (" : " );
203
+ iClient-> println (aHeaderValue);
188
204
}
189
205
190
206
void HttpClient::sendBasicAuth (const char * aUser, const char * aPassword)
191
207
{
192
208
// Send the initial part of this header line
193
- print (" Authorization: Basic " );
209
+ iClient-> print (" Authorization: Basic " );
194
210
// Now Base64 encode "aUser:aPassword" and send that
195
211
// This seems trickier than it should be but it's mostly to avoid either
196
212
// (a) some arbitrarily sized buffer which hopes to be big enough, or
@@ -226,27 +242,37 @@ void HttpClient::sendBasicAuth(const char* aUser, const char* aPassword)
226
242
// NUL-terminate the output string
227
243
output[4 ] = ' \0 ' ;
228
244
// And write it out
229
- print ((char *)output);
245
+ iClient-> print ((char *)output);
230
246
// FIXME We might want to fill output with '=' characters if b64_encode doesn't
231
247
// FIXME do it for us when we're encoding the final chunk
232
248
inputOffset = 0 ;
233
249
}
234
250
}
235
251
// And end the header we've sent
236
- println ();
252
+ iClient-> println ();
237
253
}
238
254
239
- void HttpClient::finishRequest ()
255
+ void HttpClient::finishHeaders ()
240
256
{
241
- println ();
257
+ iClient-> println ();
242
258
iState = eRequestSent;
243
259
}
244
260
261
+ void HttpClient::endRequest ()
262
+ {
263
+ if (iState < eRequestSent)
264
+ {
265
+ // We still need to finish off the headers
266
+ finishHeaders ();
267
+ }
268
+ // else the end of headers has already been sent, so nothing to do here
269
+ }
270
+
245
271
int HttpClient::responseStatusCode ()
246
272
{
247
273
if (iState < eRequestSent)
248
274
{
249
- return HttpErrAPI ;
275
+ return HTTP_ERROR_API ;
250
276
}
251
277
// The first line will be of the form Status-Line:
252
278
// HTTP-Version SP Status-Code SP Reason-Phrase CRLF
@@ -289,7 +315,7 @@ int HttpClient::responseStatusCode()
289
315
}
290
316
else
291
317
{
292
- return HttpErrInvalidResponse ;
318
+ return HTTP_ERROR_INVALID_RESPONSE ;
293
319
}
294
320
break ;
295
321
case eReadingStatusCode:
@@ -339,13 +365,13 @@ int HttpClient::responseStatusCode()
339
365
else if (c != ' \n ' )
340
366
{
341
367
// We must've timed out before we reached the end of the line
342
- return HttpErrTimedOut ;
368
+ return HTTP_ERROR_TIMED_OUT ;
343
369
}
344
370
else
345
371
{
346
372
// This wasn't a properly formed status line, or at least not one we
347
373
// could understand
348
- return HttpErrInvalidResponse ;
374
+ return HTTP_ERROR_INVALID_RESPONSE ;
349
375
}
350
376
}
351
377
@@ -373,12 +399,12 @@ int HttpClient::skipResponseHeaders()
373
399
if (endOfHeadersReached ())
374
400
{
375
401
// Success
376
- return HttpSuccess ;
402
+ return HTTP_SUCCESS ;
377
403
}
378
404
else
379
405
{
380
406
// We must've timed out
381
- return HttpErrTimedOut ;
407
+ return HTTP_ERROR_TIMED_OUT ;
382
408
}
383
409
}
384
410
0 commit comments