Skip to content

Commit 44d790b

Browse files
committed
Updated to new API as discussed on the Arduino Developers mailing list. Part of the process of moving the library to live as one of the core Arduino libraries.
The get/put/post calls have been streamlined to require fewer parameters in the basic case - i.e. you can just call http.get("www.mysite.com", "/somepath") to make a simple request. The accept header has been removed from the list of possible parameters to get/put/post - if you need to use it then send it manually with sendHeader(...) instead. You don't need to call finishRequest() after the initial call to get/put/post if you aren't going to send any headers. However, if you /do/ want to send extra headers then you need to call beginRequest() before the get/put/post and endRequest() at the end of all the sent data (so after the data as well as the headers). E.g. http.beginRequest(); http.post("www.somesite.com", "/somepath"); http.sendHeader("Content-Length", strlen(postdata)); http.print(postdata); http.endRequest();
1 parent 222f718 commit 44d790b

File tree

7 files changed

+316
-137
lines changed

7 files changed

+316
-137
lines changed

HttpClient.cpp

Lines changed: 79 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Released under Apache License, version 2.0
44

55
#include "HttpClient.h"
6-
#include <../b64/b64.h>
6+
#include "b64.h"
77
#include <Dns.h>
88
#include <string.h>
99
#include <ctype.h>
@@ -46,11 +46,17 @@ void HttpClient::stop()
4646
resetState();
4747
}
4848

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()
5050
{
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))
5258
{
53-
return HttpErrAPI;
59+
return HTTP_ERROR_API;
5460
}
5561

5662
if (iProxyPort)
@@ -60,7 +66,7 @@ int HttpClient::startRequest(const char* aServerName, uint16_t aServerPort, cons
6066
#ifdef LOGGING
6167
Serial.println("Proxy connection failed");
6268
#endif
63-
return HttpErrConnectionFailed;
69+
return HTTP_ERROR_CONNECTION_FAILED;
6470
}
6571
}
6672
else
@@ -70,19 +76,28 @@ int HttpClient::startRequest(const char* aServerName, uint16_t aServerPort, cons
7076
#ifdef LOGGING
7177
Serial.println("Connection failed");
7278
#endif
73-
return HttpErrConnectionFailed;
79+
return HTTP_ERROR_CONNECTION_FAILED;
7480
}
7581
}
7682

7783
// 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;
7993
}
8094

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)
8296
{
83-
if (eIdle != iState)
97+
tHttpState initialState = iState;
98+
if ((eIdle != iState) && (eRequestStarted != iState))
8499
{
85-
return HttpErrAPI;
100+
return HTTP_ERROR_API;
86101
}
87102

88103
if (iProxyPort)
@@ -92,7 +107,7 @@ int HttpClient::startRequest(const IPAddress& aServerAddress, uint16_t aServerPo
92107
#ifdef LOGGING
93108
Serial.println("Proxy connection failed");
94109
#endif
95-
return HttpErrConnectionFailed;
110+
return HTTP_ERROR_CONNECTION_FAILED;
96111
}
97112
}
98113
else
@@ -102,95 +117,96 @@ int HttpClient::startRequest(const IPAddress& aServerAddress, uint16_t aServerPo
102117
#ifdef LOGGING
103118
Serial.println("Connection failed");
104119
#endif
105-
return HttpErrConnectionFailed;
120+
return HTTP_ERROR_CONNECTION_FAILED;
106121
}
107122
}
108123

109124
// 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;
111134
}
112135

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)
114137
{
115138
#ifdef LOGGING
116139
Serial.println("Connected");
117140
#endif
118141
// Send the HTTP command, i.e. "GET /somepath/ HTTP/1.0"
119-
print(aHttpMethod);
120-
print(" ");
142+
iClient->print(aHttpMethod);
143+
iClient->print(" ");
121144
if (iProxyPort)
122145
{
123146
// We're going through a proxy, send a full URL
124-
print("http://");
147+
iClient->print("http://");
125148
if (aServerName)
126149
{
127150
// We've got a server name, so use it
128-
print(aServerName);
151+
iClient->print(aServerName);
129152
}
130153
else
131154
{
132155
// We'll have to use the IP address
133-
print(aServerIP);
156+
iClient->print(aServerIP);
134157
}
135158
if (aPort != kHttpPort)
136159
{
137-
print(":");
138-
print(aPort);
160+
iClient->print(":");
161+
iClient->print(aPort);
139162
}
140163
}
141-
print(aURLPath);
142-
println(" HTTP/1.0");
164+
iClient->print(aURLPath);
165+
iClient->println(" HTTP/1.0");
143166
// The host header, if required
144167
if (aServerName)
145168
{
146-
// print("Host: ");
147-
// println(aServerName);
169+
sendHeader("Host", aServerName);
148170
}
149171
// And user-agent string
150-
print("User-Agent: ");
172+
iClient->print("User-Agent: ");
151173
if (aUserAgent)
152174
{
153-
println(aUserAgent);
175+
iClient->println(aUserAgent);
154176
}
155177
else
156178
{
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);
164180
}
165181

166182
// Everything has gone well
167183
iState = eRequestStarted;
168-
return HttpSuccess;
184+
return HTTP_SUCCESS;
169185
}
170186

171187
void HttpClient::sendHeader(const char* aHeader)
172188
{
173-
println(aHeader);
189+
iClient->println(aHeader);
174190
}
175191

176192
void HttpClient::sendHeader(const char* aHeaderName, const char* aHeaderValue)
177193
{
178-
print(aHeaderName);
179-
print(": ");
180-
println(aHeaderValue);
194+
iClient->print(aHeaderName);
195+
iClient->print(": ");
196+
iClient->println(aHeaderValue);
181197
}
182198

183199
void HttpClient::sendHeader(const char* aHeaderName, const int aHeaderValue)
184200
{
185-
print(aHeaderName);
186-
print(": ");
187-
println(aHeaderValue);
201+
iClient->print(aHeaderName);
202+
iClient->print(": ");
203+
iClient->println(aHeaderValue);
188204
}
189205

190206
void HttpClient::sendBasicAuth(const char* aUser, const char* aPassword)
191207
{
192208
// Send the initial part of this header line
193-
print("Authorization: Basic ");
209+
iClient->print("Authorization: Basic ");
194210
// Now Base64 encode "aUser:aPassword" and send that
195211
// This seems trickier than it should be but it's mostly to avoid either
196212
// (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)
226242
// NUL-terminate the output string
227243
output[4] = '\0';
228244
// And write it out
229-
print((char*)output);
245+
iClient->print((char*)output);
230246
// FIXME We might want to fill output with '=' characters if b64_encode doesn't
231247
// FIXME do it for us when we're encoding the final chunk
232248
inputOffset = 0;
233249
}
234250
}
235251
// And end the header we've sent
236-
println();
252+
iClient->println();
237253
}
238254

239-
void HttpClient::finishRequest()
255+
void HttpClient::finishHeaders()
240256
{
241-
println();
257+
iClient->println();
242258
iState = eRequestSent;
243259
}
244260

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+
245271
int HttpClient::responseStatusCode()
246272
{
247273
if (iState < eRequestSent)
248274
{
249-
return HttpErrAPI;
275+
return HTTP_ERROR_API;
250276
}
251277
// The first line will be of the form Status-Line:
252278
// HTTP-Version SP Status-Code SP Reason-Phrase CRLF
@@ -289,7 +315,7 @@ int HttpClient::responseStatusCode()
289315
}
290316
else
291317
{
292-
return HttpErrInvalidResponse;
318+
return HTTP_ERROR_INVALID_RESPONSE;
293319
}
294320
break;
295321
case eReadingStatusCode:
@@ -339,13 +365,13 @@ int HttpClient::responseStatusCode()
339365
else if (c != '\n')
340366
{
341367
// We must've timed out before we reached the end of the line
342-
return HttpErrTimedOut;
368+
return HTTP_ERROR_TIMED_OUT;
343369
}
344370
else
345371
{
346372
// This wasn't a properly formed status line, or at least not one we
347373
// could understand
348-
return HttpErrInvalidResponse;
374+
return HTTP_ERROR_INVALID_RESPONSE;
349375
}
350376
}
351377

@@ -373,12 +399,12 @@ int HttpClient::skipResponseHeaders()
373399
if (endOfHeadersReached())
374400
{
375401
// Success
376-
return HttpSuccess;
402+
return HTTP_SUCCESS;
377403
}
378404
else
379405
{
380406
// We must've timed out
381-
return HttpErrTimedOut;
407+
return HTTP_ERROR_TIMED_OUT;
382408
}
383409
}
384410

0 commit comments

Comments
 (0)