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
171187void HttpClient::sendHeader (const char * aHeader)
172188{
173- println (aHeader);
189+ iClient-> println (aHeader);
174190}
175191
176192void 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
183199void 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
190206void 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+
245271int 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