Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the generic Client interface instead of embedding Ethernet #21

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 13 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,64 +24,37 @@ You need to have the `Ethernet` library already included.
#include "RestClient.h"
```

### RestClient(host/ip, [port])
### RestClient(host/ip, [port], Client)

Constructor to create an RestClient object to make requests against.

Use domain name and default to port 80:
```c++
RestClient client = RestClient("arduino-http-lib-test.herokuapp.com");
EthernetClient client
RestClient client = RestClient("arduino-http-lib-test.herokuapp.com", client);
```

Use a local IP and an explicit port:
```c++
RestClient client = RestClient("192.168.1.50",5000);
EthernetClient client
RestClient client = RestClient("192.168.1.50", 5000, client);
```
### Ethernet Setup

### dhcp()

Sets up `EthernetClient` with a mac address of `DEADBEEFFEED`. Returns `true` or `false` to indicate if setting up DHCP
was successful or not

```c++
client.dhcp()
```

Note: you can have multiple RestClient objects but only need to call
this once.

Note: if you have multiple Arduinos on the same network, you'll need
to give each one a different mac address.

### begin(byte mac[])

It just wraps the `EthernetClient` call to `begin` and DHCPs.
Use this if you need to explicitly set the mac address.

```c++
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
if (client.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
}
```

### Manual Ethernet Setup

You can skip the above methods and just configure the EthernetClient yourself:
You should configure an EthernetClient-compatible client and supply it to the library:

```c++
EthernetClient client
RestClient restClient("arduino-http-lib-test.herokuapp.com", client);
void setup() {
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//the IP address for the shield:
byte ip[] = { 192, 168, 2, 11 };
Ethernet.begin(mac,ip);
```

```c++
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
Ethernet.begin(mac);
Ethernet.begin(mac, ip);
}
```

This is especially useful for debugging network connection issues.
See the official documentation for [Ethernet](https://www.arduino.cc/en/Reference/Ethernet) for more information.

## RESTful methods

Expand Down
77 changes: 33 additions & 44 deletions RestClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,25 @@
#define HTTP_DEBUG_PRINT(string)
#endif

RestClient::RestClient(const char* _host){
RestClient::RestClient(const char* _host, Client& client){
host = _host;
port = 80;
num_headers = 0;
contentType = "application/x-www-form-urlencoded"; // default
setClient(client);
}

RestClient::RestClient(const char* _host, int _port){
RestClient::RestClient(const char* _host, int _port, Client& client){
host = _host;
port = _port;
num_headers = 0;
contentType = "application/x-www-form-urlencoded"; // default
setClient(client);
}

bool RestClient::dhcp(){
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
if (begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
return false;
}

//give it time to initialize
delay(1000);
return true;
}

int RestClient::begin(byte mac[]){
return Ethernet.begin(mac);
//give it time to initialize
delay(1000);
RestClient& RestClient::setClient(Client& client) {
this->client = &client;
return *this;
}

// GET path
Expand Down Expand Up @@ -92,26 +81,28 @@ int RestClient::del(const char* path, const char* body, String* response){

void RestClient::write(const char* string){
HTTP_DEBUG_PRINT(string);
client.print(string);
client->print(string);
}

void RestClient::setHeader(const char* header){
RestClient& RestClient::setHeader(const char* header){
headers[num_headers] = header;
num_headers++;
return *this;
}

void RestClient::setContentType(const char* contentTypeValue){
RestClient& RestClient::setContentType(const char* contentTypeValue){
contentType = contentTypeValue;
return *this;
}

// The mother- generic request method.
//
int RestClient::request(const char* method, const char* path,
const char* body, String* response){
const char* body, String* response){

HTTP_DEBUG_PRINT("HTTP: connect\n");

if(client.connect(host, port)){
if(client->connect(host, port)){
HTTP_DEBUG_PRINT("HTTP: connected\n");
HTTP_DEBUG_PRINT("REQUEST: \n");
// Make a HTTP request line:
Expand All @@ -133,9 +124,9 @@ int RestClient::request(const char* method, const char* path,
sprintf(contentLength, "Content-Length: %d\r\n", strlen(body));
write(contentLength);

write("Content-Type: ");
write(contentType);
write("\r\n");
write("Content-Type: ");
write(contentType);
write("\r\n");
}

write("\r\n");
Expand All @@ -156,7 +147,7 @@ int RestClient::request(const char* method, const char* path,
//cleanup
HTTP_DEBUG_PRINT("HTTP: stop client\n");
num_headers = 0;
client.stop();
client->stop();
delay(50);
HTTP_DEBUG_PRINT("HTTP: client stopped\n");

Expand Down Expand Up @@ -185,13 +176,13 @@ int RestClient::readResponse(String* response) {
}

HTTP_DEBUG_PRINT("HTTP: RESPONSE: \n");
while (client.connected()) {
while (client->connected()) {
HTTP_DEBUG_PRINT(".");

if (client.available()) {
if (client->available()) {
HTTP_DEBUG_PRINT(",");

char c = client.read();
char c = client->read();
HTTP_DEBUG_PRINT(c);

if(c == ' ' && !inStatus){
Expand All @@ -213,22 +204,20 @@ int RestClient::readResponse(String* response) {
}
else
{
if (c == '\n' && currentLineIsBlank) {
httpBody = true;
}

if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
if (c == '\n' && currentLineIsBlank) {
httpBody = true;
}

if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
}

HTTP_DEBUG_PRINT("HTTP: return readResponse3\n");
return code;
}
22 changes: 10 additions & 12 deletions RestClient.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
#include <Arduino.h>
#include <SPI.h>
#include <Ethernet.h>
#include "Client.h"

class RestClient {

public:
RestClient(const char* host);
RestClient(const char* _host, int _port);

//Client Setup
bool dhcp();
int begin(byte*);
RestClient(const char* host, Client& client);
RestClient(const char* _host, int _port, Client& client);

//Generic HTTP Request
int request(const char* method, const char* path,
const char* body, String* response);

// Set a Request Header
void setHeader(const char*);
RestClient& setHeader(const char*);
// Set Content-Type Header
void setContentType(const char*);
RestClient& setContentType(const char*);

RestClient& setClient(Client& client);

// GET path
int get(const char*);
Expand All @@ -45,12 +43,12 @@ class RestClient {
int del(const char*, const char*, String*);

private:
EthernetClient client;
Client* client;
int readResponse(String*);
void write(const char*);
const char* host;
int port;
int num_headers;
const char* headers[10];
const char* contentType;
const char* contentType;
};
11 changes: 8 additions & 3 deletions examples/full_test_suite/full_test_suite.ino
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@
int test_delay = 1000; //so we don't spam the API
boolean describe_tests = true;

RestClient client = RestClient("arduino-http-lib-test.herokuapp.com");
const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetClient ethclient;

RestClient client = RestClient("arduino-http-lib-test.herokuapp.com", ethclient);
//RestClient client = RestClient("10.0.1.47",5000);


//Setup
void setup() {
Serial.begin(9600);
// Connect via DHCP
Serial.println("connect to network");
client.dhcp();
if(Ethernet.begin(mac)) {
Serial.println("connected to network via DHCP");
Serial.print("IP received:"); Serial.println(Ethernet.localIP());
}
/*
//Can still fall back to manual config:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
Expand Down
11 changes: 8 additions & 3 deletions examples/simple_GET/simple_GET.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@
#include <SPI.h>
#include "RestClient.h"

RestClient client = RestClient("arduino-http-lib-test.herokuapp.com");
const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetClient ethclient;

RestClient client = RestClient("arduino-http-lib-test.herokuapp.com", ethclient);

//Setup
void setup() {
Serial.begin(9600);
// Connect via DHCP
Serial.println("connect to network");
client.dhcp();
if(Ethernet.begin(mac)) {
Serial.println("connected to network via DHCP");
Serial.print("IP received:"); Serial.println(Ethernet.localIP());
}
/*
// Can still fall back to manual config:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
Expand Down
11 changes: 8 additions & 3 deletions examples/simple_POST/simple_POST.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@
#include <SPI.h>
#include "RestClient.h"

RestClient client = RestClient("arduino-http-lib-test.herokuapp.com");
const byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetClient ethclient;

RestClient client = RestClient("arduino-http-lib-test.herokuapp.com", ethclient);

//Setup
void setup() {
Serial.begin(9600);
// Connect via DHCP
Serial.println("connect to network");
client.dhcp();
if(Ethernet.begin(mac)) {
Serial.println("connected to network via DHCP");
Serial.print("IP received:"); Serial.println(Ethernet.localIP());
}
/*
// Can still fall back to manual config:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
Expand Down