friendev EtherDune TCP/IP library
/home/jander/temp/etherdune/HTTPClient.cpp
Go to the documentation of this file.
1 // EtherDune HTTP Client class
2 // Author: Javier Peletier <jm@friendev.com>
3 // Summary: Provides an easy way to query a web server
4 //
5 // Copyright (c) 2015 All Rights Reserved, http://friendev.com
6 //
7 // This source is subject to the GPLv2 license.
8 // Please see the License.txt file for more information.
9 // All other rights reserved.
10 //
11 // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
12 // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13 // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
14 // PARTICULAR PURPOSE.
15 
16 #include "HTTPClient.h"
17 #include "DNS.h"
18 
19 #define AC_LOGLEVEL 6
20 #include <ACLog.h>
21 ACROSS_MODULE("HTTPClient");
22 
23 
38 void HTTPClient::onHeaderReceived(uint16_t len, const byte* data) {}
44 void HTTPClient::onBodyReceived(uint16_t len, const byte* data) {}
51 
52 
54  statusCodePattern(statusCodePatternString),
55  bodyBeginPattern(bodyBeginPatternString),
56  DNSid(0)
57 {
58  remoteIP.zero();
59  remotePort = 80;
60 }
61 
68 void HTTPClient::request(const String& hostName, const String& resource, uint16_t port )
69 {
70  remotePort = port;
71 
72  host = hostName;
73  res = resource;
74 
75  if (remoteIP.u == 0)
76  DNSid = DNS().resolve(hostName.c_str());
77  else
78  connect();
79 }
80 
81 
82 void HTTPClient::onDNSResolve(uint8_t status, uint16_t identification, const IPAddress& ip)
83 {
84  if (identification == DNSid)
85  {
86  if (status == 0)
87  {
88  DNSid = 0;
89  remoteIP = ip;
90  connect();
91  }
92  else
93  {
94  ACERROR("Could not resolve hostname");
95  }
96  }
97 }
98 
99 
100 void HTTPClient::onConnect()
101 {
102  scanner.setPattern(statusCodePattern);
103  statusCode = 0;
104  bodyBeginPattern.signaled = false;
105 
106  write(F("GET % HTTP/1.1" "\r\n" "Accept:*" "/" "*" "\r\n" "Host:%\r\n\r\n"), &res, &host);
107 }
108 
109 void HTTPClient::onReceive(uint16_t len, const byte* data)
110 {
111 
112  if (bodyBeginPattern.signaled)
113  {
114  onBodyReceived(len, data);
115  return;
116  }
117 
118  const byte* headerStart = data;
119 
120  while (len--)
121  {
122  uint8_t c = *data++;
123 
124 
125  if (statusCodePattern.signaled)
126  {
127  if (scanner.scan(c))
128  {
129  onHeaderReceived(data - headerStart, headerStart);
130  onBodyBegin();
131  onBodyReceived(len, data);
132  return;
133  }
134  }
135  else
136  {
137  if (scanner.scan(c, &statusCode))
138  {
140  scanner.setPattern(bodyBeginPattern);
141  headerStart = data;
142  }
143 
144  }
145  }
146 
147  if (statusCodePattern.signaled)
148  onHeaderReceived(data - headerStart, headerStart);
149 
150 }
151 
152 
153 void HTTPClient::onClose()
154 {
155  close();
156  onResponseEnd();
157 }
158 
160 {
161  onClose();
162 }
void request(const String &hostName, const String &resource, uint16_t port=80)
Starts a new HTTP request.
Definition: HTTPClient.cpp:68
virtual void onResponseReceived()
Called immediately after the first line is received and there is a status code, e.g.
Definition: HTTPClient.cpp:28
uint32_t u
access the IP as a uint32_t for convenience
Definition: inet.h:184
virtual void onBodyBegin()
Called when all HTTP headers have been received and the body of the response is about to arrive...
Definition: HTTPClient.cpp:50
static DNSClient & DNS()
Obtains access to the DNS service singleton instance.
uint16_t write(uint16_t len, const byte *data)
In the case of TCP, writes the given data buffer to the socket.
Definition: Socket.cpp:54
static const char bodyBeginPatternString[]
Definition: HTTPClient.h:39
nint16_t remotePort
remote TCP or UDP port
Definition: Socket.h:53
ACROSS_MODULE("HTTPClient")
represents an IP address in memory
Definition: inet.h:181
FlowScanner scanner
Internal FlowScanner instance used to detect header/response/status code, etc.
Definition: HTTPClient.h:59
void connect()
Initiates a TCP connection to remoteIP and remotePort.
Definition: TCPSocket.cpp:71
uint16_t statusCode
Contains the HTTP status code of the response.
Definition: HTTPClient.h:64
void zero()
Sets the IP address to zero.
Definition: inet.h:207
uint16_t resolve(const char *name)
Resolves a host name to an IP address
Definition: DNS.cpp:45
virtual void onBodyReceived(uint16_t len, const byte *data)
Called once for each fragment of the body that is received.
Definition: HTTPClient.cpp:44
IPAddress remoteIP
remote IP address to connect to (TCP) or send the next packet to (UDP)
Definition: Socket.h:55
virtual void onHeaderReceived(uint16_t len, const byte *data)
Called once for each fragment of the header portion of the response
Definition: HTTPClient.cpp:38
virtual void onResponseEnd()
Called after all the body has been received
Definition: HTTPClient.cpp:32
void close()
Attempts to gracefully close a connection.
Definition: TCPSocket.cpp:194
static const char statusCodePatternString[]
Definition: HTTPClient.h:38