44
55#include " HttpClient.h"
66#include < ../b64/b64.h>
7+ #include < Dns.h>
78#include < string.h>
89#include < ctype.h>
9- #include " wiring.h"
1010
1111// Initialize constants
1212const char * HttpClient::kUserAgent = " Arduino/2.0" ;
@@ -16,10 +16,19 @@ const char* HttpClient::kPut = "PUT";
1616const char * HttpClient::kDelete = " DELETE" ;
1717const char * HttpClient::kContentLengthPrefix = " Content-Length: " ;
1818
19- HttpClient::HttpClient (Client& aClient)
20- : iClient(&aClient)
19+ HttpClient::HttpClient (Client& aClient, const char * aProxy, uint16_t aProxyPort )
20+ : iClient(&aClient), iProxyPort(aProxyPort)
2121{
2222 resetState ();
23+ if (aProxy)
24+ {
25+ // Resolve the IP address for the proxy
26+ DNSClient dns;
27+ dns.begin (Ethernet.dnsServerIP ());
28+ // Not ideal that we discard any errors here, but not a lot we can do in the ctor
29+ // and we'll get a connect error later anyway
30+ (void )dns.getHostByName (aProxy, iProxyAddress);
31+ }
2332}
2433
2534void HttpClient::resetState ()
@@ -44,16 +53,29 @@ int HttpClient::startRequest(const char* aServerName, uint16_t aServerPort, cons
4453 return HttpErrAPI;
4554 }
4655
47- if (!iClient-> connect (aServerName, aServerPort) )
56+ if (iProxyPort )
4857 {
58+ if (!iClient->connect (iProxyAddress, iProxyPort))
59+ {
60+ #ifdef LOGGING
61+ Serial.println (" Proxy connection failed" );
62+ #endif
63+ return HttpErrConnectionFailed;
64+ }
65+ }
66+ else
67+ {
68+ if (!iClient->connect (aServerName, aServerPort))
69+ {
4970#ifdef LOGGING
50- Serial.println (" Connection failed" );
71+ Serial.println (" Connection failed" );
5172#endif
52- return HttpErrConnectionFailed;
73+ return HttpErrConnectionFailed;
74+ }
5375 }
5476
5577 // Now we're connected, send the first part of the request
56- return sendInitialHeaders (aServerName, aURLPath, aHttpMethod, aUserAgent, aAcceptList);
78+ return sendInitialHeaders (aServerName, IPAddress ( 0 , 0 , 0 , 0 ), aServerPort, aURLPath, aHttpMethod, aUserAgent, aAcceptList);
5779}
5880
5981int HttpClient::startRequest (const IPAddress& aServerAddress, uint16_t aServerPort, const char * aServerName, const char * aURLPath, const char * aHttpMethod, const char * aUserAgent, const char * aAcceptList)
@@ -63,33 +85,66 @@ int HttpClient::startRequest(const IPAddress& aServerAddress, uint16_t aServerPo
6385 return HttpErrAPI;
6486 }
6587
66- if (!iClient->connect (aServerAddress, aServerPort))
88+ if (iProxyPort)
89+ {
90+ if (!iClient->connect (iProxyAddress, iProxyPort))
91+ {
92+ #ifdef LOGGING
93+ Serial.println (" Proxy connection failed" );
94+ #endif
95+ return HttpErrConnectionFailed;
96+ }
97+ }
98+ else
6799 {
100+ if (!iClient->connect (aServerAddress, aServerPort))
101+ {
68102#ifdef LOGGING
69- Serial.println (" Connection failed" );
103+ Serial.println (" Connection failed" );
70104#endif
71- return HttpErrConnectionFailed;
105+ return HttpErrConnectionFailed;
106+ }
72107 }
73108
74109 // Now we're connected, send the first part of the request
75- return sendInitialHeaders (aServerName, aURLPath, aHttpMethod, aUserAgent, aAcceptList);
110+ return sendInitialHeaders (aServerName, aServerAddress, aServerPort, aURLPath, aHttpMethod, aUserAgent, aAcceptList);
76111}
77112
78- int HttpClient::sendInitialHeaders (const char * aServerName, const char * aURLPath, const char * aHttpMethod, const char * aUserAgent, const char * aAcceptList)
113+ int HttpClient::sendInitialHeaders (const char * aServerName, IPAddress aServerIP, uint16_t aPort, const char * aURLPath, const char * aHttpMethod, const char * aUserAgent, const char * aAcceptList)
79114{
80115#ifdef LOGGING
81116 Serial.println (" Connected" );
82117#endif
83118 // Send the HTTP command, i.e. "GET /somepath/ HTTP/1.0"
84119 print (aHttpMethod);
85120 print (" " );
121+ if (iProxyPort)
122+ {
123+ // We're going through a proxy, send a full URL
124+ print (" http://" );
125+ if (aServerName)
126+ {
127+ // We've got a server name, so use it
128+ print (aServerName);
129+ }
130+ else
131+ {
132+ // We'll have to use the IP address
133+ print (aServerIP);
134+ }
135+ if (aPort != kHttpPort )
136+ {
137+ print (" :" );
138+ print (aPort);
139+ }
140+ }
86141 print (aURLPath);
87142 println (" HTTP/1.0" );
88143 // The host header, if required
89144 if (aServerName)
90145 {
91- print (" Host: " );
92- println (aServerName);
146+ // print("Host: ");
147+ // println(aServerName);
93148 }
94149 // And user-agent string
95150 print (" User-Agent: " );
@@ -339,14 +394,28 @@ bool HttpClient::endOfBodyReached()
339394
340395int HttpClient::read ()
341396{
342- int ret =iClient->read ();
397+ uint8_t b[1 ];
398+ int ret = read (b, 1 );
399+ if (ret == 1 )
400+ {
401+ return b[0 ];
402+ }
403+ else
404+ {
405+ return -1 ;
406+ }
407+ }
408+
409+ int HttpClient::read (uint8_t *buf, size_t size)
410+ {
411+ int ret =iClient->read (buf, size);
343412 if (endOfHeadersReached () && iContentLength > 0 )
344413 {
345414 // We're outputting the body now and we've seen a Content-Length header
346415 // So keep track of how many bytes are left
347416 if (ret >= 0 )
348417 {
349- iBodyLengthConsumed++ ;
418+ iBodyLengthConsumed += ret ;
350419 }
351420 }
352421 return ret;
0 commit comments