From c3023b25ee89d736862ed0525d98834f227c398f Mon Sep 17 00:00:00 2001 From: Sandeep Mistry Date: Wed, 22 Jun 2016 12:10:47 -0400 Subject: [PATCH] Add optional content type, content length and body parameters to post, put, and startRequest Also, flush client RX data in start request, if state is ready body. --- HttpClient.cpp | 103 +++++++++++++++++++++++++---- HttpClient.h | 52 ++++++++++----- examples/DweetGet/DweetGet.ino | 2 - examples/DweetPost/DweetPost.ino | 9 +-- examples/SimpleGet/SimpleGet.ino | 5 +- examples/SimplePost/SimplePost.ino | 8 +-- examples/SimplePut/SimplePut.ino | 8 +-- 7 files changed, 134 insertions(+), 53 deletions(-) diff --git a/HttpClient.cpp b/HttpClient.cpp index 9176108..72c471f 100644 --- a/HttpClient.cpp +++ b/HttpClient.cpp @@ -59,17 +59,18 @@ void HttpClient::beginRequest() iState = eRequestStarted; } -int HttpClient::startRequest(const char* aURLPath, const char* aHttpMethod) +int HttpClient::startRequest(const char* aURLPath, const char* aHttpMethod, + const char* aContentType, int aContentLength, const byte aBody[]) { - tHttpState initialState = iState; - - if (!iConnectionClose) + if (iState == eReadingBody) { flushClientRx(); resetState(); } + tHttpState initialState = iState; + if ((eIdle != iState) && (eRequestStarted != iState)) { return HTTP_ERROR_API; @@ -104,12 +105,31 @@ int HttpClient::startRequest(const char* aURLPath, const char* aHttpMethod) // Now we're connected, send the first part of the request int ret = sendInitialHeaders(aURLPath, aHttpMethod); - if ((initialState == eIdle) && (HTTP_SUCCESS == ret)) + + if (HTTP_SUCCESS == ret) { - // This was a simple version of the API, so terminate the headers now - finishHeaders(); + if (aContentType) + { + sendHeader(HTTP_HEADER_CONTENT_TYPE, aContentType); + } + + if (aContentLength > 0) + { + sendHeader(HTTP_HEADER_CONTENT_LENGTH, aContentLength); + } + + if ((initialState == eIdle)) + { + // This was a simple version of the API, so terminate the headers now + finishHeaders(); + + if (aBody && aContentLength > 0) + { + write(aBody, aContentLength); + } + } + // else we'll call it in endRequest or in the first call to print, etc. } - // else we'll call it in endRequest or in the first call to print, etc. return ret; } @@ -231,12 +251,9 @@ void HttpClient::finishHeaders() void HttpClient::flushClientRx() { - if (iClient->connected()) + while (iClient->available()) { - while (iClient->available()) - { - iClient->read(); - } + iClient->read(); } } @@ -250,6 +267,66 @@ void HttpClient::endRequest() // else the end of headers has already been sent, so nothing to do here } +int HttpClient::get(const char* aURLPath) +{ + return startRequest(aURLPath, HTTP_METHOD_GET); +} + +int HttpClient::get(const String& aURLPath) +{ + return get(aURLPath.c_str()); +} + +int HttpClient::post(const char* aURLPath) +{ + return startRequest(aURLPath, HTTP_METHOD_POST); +} + +int HttpClient::post(const String& aURLPath) +{ + return post(aURLPath.c_str()); +} + +int HttpClient::post(const char* aURLPath, const char* aContentType, const char* aBody) +{ + return post(aURLPath, aContentType, strlen(aBody), (const byte*)aBody); +} + +int HttpClient::post(const String& aURLPath, const String& aContentType, const String& aBody) +{ + return post(aURLPath.c_str(), aContentType.c_str(), aBody.length(), (const byte*)aBody.c_str()); +} + +int HttpClient::post(const char* aURLPath, const char* aContentType, int aContentLength, const byte aBody[]) +{ + return startRequest(aURLPath, HTTP_METHOD_POST, aContentType, aContentLength, aBody); +} + +int HttpClient::put(const char* aURLPath) +{ + return startRequest(aURLPath, HTTP_METHOD_PUT); +} + +int HttpClient::put(const String& aURLPath) +{ + return put(aURLPath.c_str()); +} + +int HttpClient::put(const char* aURLPath, const char* aContentType, const char* aBody) +{ + return put(aURLPath, aContentType, strlen(aBody), (const byte*)aBody); +} + +int HttpClient::put(const String& aURLPath, const String& aContentType, const String& aBody) +{ + return put(aURLPath.c_str(), aContentType.c_str(), aBody.length(), (const byte*)aBody.c_str()); +} + +int HttpClient::put(const char* aURLPath, const char* aContentType, int aContentLength, const byte aBody[]) +{ + return startRequest(aURLPath, HTTP_METHOD_PUT, aContentType, aContentLength, aBody); +} + int HttpClient::responseStatusCode() { if (iState < eRequestSent) diff --git a/HttpClient.h b/HttpClient.h index 4b51ca3..06af847 100644 --- a/HttpClient.h +++ b/HttpClient.h @@ -31,6 +31,7 @@ static const int HTTP_ERROR_INVALID_RESPONSE =-4; #define HTTP_METHOD_PUT "PUT" #define HTTP_METHOD_DELETE "DELETE" #define HTTP_HEADER_CONTENT_LENGTH "Content-Length" +#define HTTP_HEADER_CONTENT_TYPE "Content-Type" #define HTTP_HEADER_CONNECTION "Connection" #define HTTP_HEADER_USER_AGENT "User-Agent" @@ -64,39 +65,58 @@ public: @param aURLPath Url to request @return 0 if successful, else error */ - int get(const char* aURLPath) - { return startRequest(aURLPath, HTTP_METHOD_GET); } - - int get(const String& aURLPath) - { return get(aURLPath.c_str()); } + int get(const char* aURLPath); + int get(const String& aURLPath); /** Connect to the server and start to send a POST request. @param aURLPath Url to request @return 0 if successful, else error */ - int post(const char* aURLPath) - { return startRequest(aURLPath, HTTP_METHOD_POST); } + int post(const char* aURLPath); + int post(const String& aURLPath); - int post(const String& aURLPath) - { return post(aURLPath.c_str()); } + /** Connect to the server and start to send a POST request + with body and content type + @param aURLPath Url to request + @param aContentType Content type of request body + @param aBody Body of the request + @return 0 if successful, else error + */ + int post(const char* aURLPath, const char* aContentType, const char* aBody); + int post(const String& aURLPath, const String& aContentType, const String& aBody); + int post(const char* aURLPath, const char* aContentType, int aContentLength, const byte aBody[]); /** Connect to the server and start to send a PUT request. @param aURLPath Url to request @return 0 if successful, else error */ - int put(const char* aURLPath) - { return startRequest(aURLPath, HTTP_METHOD_PUT); } + int put(const char* aURLPath); + int put(const String& aURLPath); - int put(const String& aURLPath) - { return put(aURLPath.c_str()); } + /** Connect to the server and start to send a PUT request + with body and content type + @param aURLPath Url to request + @param aContentType Content type of request body + @param aBody Body of the request + @return 0 if successful, else error + */ + int put(const char* aURLPath, const char* aContentType, const char* aBody); + int put(const String& aURLPath, const String& aContentType, const String& aBody); + int put(const char* aURLPath, const char* aContentType, int aContentLength, const byte aBody[]); /** Connect to the server and start to send the request. - @param aURLPath Url to request - @param aHttpMethod Type of HTTP request to make, e.g. "GET", "POST", etc. + @param aURLPath Url to request + @param aHttpMethod Type of HTTP request to make, e.g. "GET", "POST", etc. + @param aContentType Content type of request body (optional) + @param aContentLength Length of request body (optional) + @param aBody Body of request (optional) @return 0 if successful, else error */ int startRequest(const char* aURLPath, - const char* aHttpMethod); + const char* aHttpMethod, + const char* aContentType = NULL, + int aContentLength = -1, + const byte aBody[] = NULL); /** Send an additional header line. This can only be called in between the calls to startRequest and finishRequest. diff --git a/examples/DweetGet/DweetGet.ino b/examples/DweetGet/DweetGet.ino index 11d3daa..7ab952f 100644 --- a/examples/DweetGet/DweetGet.ino +++ b/examples/DweetGet/DweetGet.ino @@ -63,9 +63,7 @@ void loop() { // send the GET request Serial.println("making GET request"); - client.beginRequest(); client.get(path); - client.endRequest(); // read the status code of the response statusCode = client.responseStatusCode(); diff --git a/examples/DweetPost/DweetPost.ino b/examples/DweetPost/DweetPost.ino index 04b5f3e..d2f0582 100644 --- a/examples/DweetPost/DweetPost.ino +++ b/examples/DweetPost/DweetPost.ino @@ -56,6 +56,8 @@ void loop() { String dweetName = "scandalous-cheese-hoarder"; String path = "/dweet/for/" + dweetName; + String contentType = "application/json"; + // assemble the body of the POST message: int sensorValue = analogRead(A0); String postData = "{\"sensorValue\":\""; @@ -65,12 +67,7 @@ void loop() { Serial.println("making POST request"); // send the POST request - client.beginRequest(); - client.post(path); - client.sendHeader("Content-Type", "application/json"); - client.sendHeader("Content-Length", postData.length()); - client.endRequest(); - client.write((const byte*)postData.c_str(), postData.length()); + client.post(path, contentType, postData); // read the status code and content length of the response statusCode = client.responseStatusCode(); diff --git a/examples/SimpleGet/SimpleGet.ino b/examples/SimpleGet/SimpleGet.ino index 86cdb9d..78c3062 100644 --- a/examples/SimpleGet/SimpleGet.ino +++ b/examples/SimpleGet/SimpleGet.ino @@ -49,12 +49,9 @@ void setup() { void loop() { Serial.println("making GET request"); + client.get("/"); // read the status code and content length of the response - client.beginRequest(); - client.get("/"); - client.endRequest(); - statusCode = client.responseStatusCode(); contentLength = client.contentLength(); diff --git a/examples/SimplePost/SimplePost.ino b/examples/SimplePost/SimplePost.ino index 46982ca..341205d 100644 --- a/examples/SimplePost/SimplePost.ino +++ b/examples/SimplePost/SimplePost.ino @@ -50,14 +50,10 @@ void setup() { void loop() { Serial.println("making POST request"); + String contentType = "application/x-www-form-urlencoded"; String postData = "name=Alice&age=12"; - client.beginRequest(); - client.post("/"); - client.sendHeader("Content-Type", "application/x-www-form-urlencoded"); - client.sendHeader("Content-Length", postData.length()); - client.endRequest(); - client.write((const byte*)postData.c_str(), postData.length()); + client.post("/", contentType, postData); // read the status code and content length of the response statusCode = client.responseStatusCode(); diff --git a/examples/SimplePut/SimplePut.ino b/examples/SimplePut/SimplePut.ino index 611f55c..dfca20c 100644 --- a/examples/SimplePut/SimplePut.ino +++ b/examples/SimplePut/SimplePut.ino @@ -50,14 +50,10 @@ void setup() { void loop() { Serial.println("making PUT request"); + String contentType = "application/x-www-form-urlencoded"; String putData = "name=light&age=46"; - client.beginRequest(); - client.put("/"); - client.sendHeader("Content-Type", "application/x-www-form-urlencoded"); - client.sendHeader("Content-Length", putData.length()); - client.endRequest(); - client.write((const byte*)putData.c_str(), putData.length()); + client.put("/", contentType, putData); // read the status code and content length of the response statusCode = client.responseStatusCode();