diff --git a/Sming/Services/WebHelpers/escape.cpp b/Sming/Services/WebHelpers/escape.cpp index 0bdfeb87c7..05371dcfb8 100644 --- a/Sming/Services/WebHelpers/escape.cpp +++ b/Sming/Services/WebHelpers/escape.cpp @@ -101,7 +101,8 @@ char *uri_escape(char *dest, size_t dest_len, const char *src, int src_len) /* escape these values ~!#$%^&(){}[]=:,;?'"\ * make sure there is room in dest for a '\0' */ for(;src_len>0 && dest_len>1;src++,src_len--) { - if(must_escape(*src)) { + char c = *src; + if(must_escape(c)) { /* check that there is room for "%XX\0" in dest */ if(dest_len<=3) { if(ret_is_allocated) @@ -113,6 +114,9 @@ char *uri_escape(char *dest, size_t dest_len, const char *src, int src_len) dest[2] = hexchar(*src & 0x0f); dest+=3; dest_len-=3; + } else if (c == ' ') { + *dest++ = '+'; + dest_len--; } else { *(dest++)=*src; dest_len--; @@ -232,23 +236,34 @@ void html_escape(char *dest, size_t len, const char *s) { String uri_escape(const char *src, int src_len) { - char* p = uri_escape(nullptr, 0, src, src_len); - String s(p); - if (p) - free(p); + String s; + if (src && src_len) { + unsigned dst_len = uri_escape_len(src, src_len); + if (s.setLength(dst_len)) + uri_escape(s.begin(), s.length() + 1, src, src_len); // +1 for nul terminator + } return s; } -int uri_unescape_inplace(String& s) +char* uri_unescape_inplace(char *str) { - // If string is invalid, ensure result remains invalid - if (!s) - return 0; + if (str) { + auto len = strlen(str); + uri_unescape(str, len + 1, str, len); // +1 for nul terminator + } + return str; +} - char* p = s.begin(); - uri_unescape(p, s.length(), p, s.length()); - s.setLength(strlen(p)); - return s.length(); +String& uri_unescape_inplace(String& str) +{ + if (str) { + char* p = str.begin(); + uri_unescape(p, str.length() + 1, p, str.length()); // +1 for nul terminator + auto len = strlen(p); + assert(len <= str.length()); + str.setLength(len); + } + return str; } diff --git a/Sming/Services/WebHelpers/escape.h b/Sming/Services/WebHelpers/escape.h index 782a33980f..7025832a8f 100644 --- a/Sming/Services/WebHelpers/escape.h +++ b/Sming/Services/WebHelpers/escape.h @@ -4,12 +4,50 @@ #include #include "WString.h" +/** @brief Obtain number of characters required to escape the given text + * @param s source text + * @param len Number of characters in source text + * @retval unsigned number of characters for output, NOT including nul terminator + */ unsigned uri_escape_len(const char *s, size_t len); + +static inline unsigned uri_escape_len(const String& str) +{ + return uri_escape_len(str.c_str(), str.length()); +} + +/** @brief Escape text + * @param dest buffer to store result + * @param dest_len available space in dest; requires +1 extra character for nul terminator, + * so at least uri_escape_len() + 1 + * @param src source text to escape + * @param src_len number of characters in source + * @retval char* points to start of dest + * @note destination and source MUST be different buffers + */ char *uri_escape(char *dest, size_t dest_len, const char *src, int src_len); + +/** @brief unescape text + * @param dest buffer to store result + * @param dest_len available space in dest; requires +1 extra character for nul terminator + * @param src source text to un-escape + * @param src_len number of characters in source + * @retval char* points to start of dest + * @note destination and source may be the same buffer + */ char *uri_unescape(char *dest, size_t dest_len, const char *src, int src_len); + unsigned html_escape_len(const char *s, size_t len); void html_escape(char *dest, size_t len, const char *s); + +/** @brief Replace a nul-terminated string with its unescaped version + * @param str the string to un-escape + * @retval char* the result, a copy of str + * @note unescaped string is never longer than escaped version + */ +char* uri_unescape_inplace(char *str); + /** @brief escape the given URI string * @param src * @param src_len @@ -24,18 +62,19 @@ static inline String uri_escape(const String& src) } -/** @brief replace the given uri by its unescaped version - * @retval int length of result +/** @brief replace the given text by its unescaped version + * @param str the string to unescape + * @retval reference to str, unescaped * @note unescaped string is never longer than escaped version */ -int uri_unescape_inplace(String& s); +String& uri_unescape_inplace(String& str); /** @brief return the unescaped version of a string * @retval String unescaped string */ -static inline String uri_unescape(const String& s) +static inline String uri_unescape(const String& str) { - String ret = s; + String ret = str; uri_unescape_inplace(ret); return ret; } diff --git a/Sming/SmingCore/Data/Stream/UrlencodedOutputStream.cpp b/Sming/SmingCore/Data/Stream/UrlencodedOutputStream.cpp index 07ddc5b282..c39fc9ae23 100644 --- a/Sming/SmingCore/Data/Stream/UrlencodedOutputStream.cpp +++ b/Sming/SmingCore/Data/Stream/UrlencodedOutputStream.cpp @@ -13,16 +13,10 @@ /* * @todo Revise this so stream produces encoded output line-by-line, rather than all at once. + * Can use StreamTransformer to do this. */ UrlencodedOutputStream::UrlencodedOutputStream(const HttpParams& params) { - for(unsigned i = 0; i < params.count(); i++) { - if(i > 0) - stream.write('&'); - - stream.print(uri_escape(params.keyAt(i))); - stream.print('='); - stream.print(uri_escape(params.valueAt(i))); - } + stream.print(params); } diff --git a/Sming/SmingCore/Data/Stream/UrlencodedOutputStream.h b/Sming/SmingCore/Data/Stream/UrlencodedOutputStream.h index 993ca45723..8699d9576b 100644 --- a/Sming/SmingCore/Data/Stream/UrlencodedOutputStream.h +++ b/Sming/SmingCore/Data/Stream/UrlencodedOutputStream.h @@ -12,16 +12,14 @@ #define _SMING_CORE_DATA_URL_ENCODDED_OUTPUT_STREAM_H_ #include "MemoryDataStream.h" -#include "WHashMap.h" +#include "Network/Http/HttpParams.h" /** * @brief UrlEncoded Stream * @ingroup stream data * * @{ -*/ - -typedef HashMap HttpParams; + */ class UrlencodedOutputStream : public ReadWriteStream { diff --git a/Sming/SmingCore/Data/Structures.h b/Sming/SmingCore/Data/Structures.h index 6883e13f21..4e46ad1381 100644 --- a/Sming/SmingCore/Data/Structures.h +++ b/Sming/SmingCore/Data/Structures.h @@ -47,6 +47,4 @@ template class SimpleConcurrentQueue : public FIFO HttpParams; - #endif /* _SMING_CORE_DATA_STRUCTURES_H_ */ diff --git a/Sming/SmingCore/Network/Http/HttpConnection.cpp b/Sming/SmingCore/Network/Http/HttpConnection.cpp index 8febadfdfa..2933ef5a97 100644 --- a/Sming/SmingCore/Network/Http/HttpConnection.cpp +++ b/Sming/SmingCore/Network/Http/HttpConnection.cpp @@ -476,24 +476,24 @@ void HttpConnection::sendRequestHeaders(HttpRequest* request) new MultipartStream(HttpPartProducerDelegate(&HttpConnection::multipartProducer, this)); request->headers[HTTP_HEADER_CONTENT_TYPE] = ContentType::toString(MIME_FORM_MULTIPART) + _F("; boundary=") + mStream->getBoundary(); - if(request->stream) { + if(request->bodyStream) { debug_e("HttpConnection: existing stream is discarded due to POST params"); - delete request->stream; + delete request->bodyStream; } - request->stream = mStream; + request->bodyStream = mStream; } else if(request->postParams.count()) { UrlencodedOutputStream* uStream = new UrlencodedOutputStream(request->postParams); request->headers[HTTP_HEADER_CONTENT_TYPE] = ContentType::toString(MIME_FORM_URL_ENCODED); - if(request->stream) { + if(request->bodyStream) { debug_e("HttpConnection: existing stream is discarded due to POST params"); - delete request->stream; + delete request->bodyStream; } - request->stream = uStream; + request->bodyStream = uStream; } /* if (request->postParams.count()) */ - if(request->stream != nullptr) { - if(request->stream->available() > -1) { - request->headers[HTTP_HEADER_CONTENT_LENGTH] = String(request->stream->available()); + if(request->bodyStream != nullptr) { + if(request->bodyStream->available() > -1) { + request->headers[HTTP_HEADER_CONTENT_LENGTH] = String(request->bodyStream->available()); } else { request->headers.remove(HTTP_HEADER_CONTENT_LENGTH); } @@ -515,17 +515,17 @@ bool HttpConnection::sendRequestBody(HttpRequest* request) if(state == eHCS_StartBody) { state = eHCS_SendingBody; - if(request->stream == nullptr) { + if(request->bodyStream == nullptr) { return true; } delete stream; if(request->headers[HTTP_HEADER_TRANSFER_ENCODING] == _F("chunked")) { - stream = new ChunkedStream(request->stream); + stream = new ChunkedStream(request->bodyStream); } else { - stream = request->stream; // avoid intermediate buffers + stream = request->bodyStream; // avoid intermediate buffers } - request->stream = nullptr; + request->bodyStream = nullptr; return false; } @@ -534,7 +534,7 @@ bool HttpConnection::sendRequestBody(HttpRequest* request) return true; } - if(request->stream == nullptr && !stream->isFinished()) { + if(request->bodyStream == nullptr && !stream->isFinished()) { return false; } diff --git a/Sming/SmingCore/Network/Http/HttpParams.cpp b/Sming/SmingCore/Network/Http/HttpParams.cpp new file mode 100644 index 0000000000..e3d1e37fcc --- /dev/null +++ b/Sming/SmingCore/Network/Http/HttpParams.cpp @@ -0,0 +1,27 @@ +/**** + * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. + * Created 2015 by Skurydin Alexey + * http://github.com/SmingHub/Sming + * All files of the Sming Core are provided under the LGPL v3 license. + * + * @author: 2018 - Mikee47 + * + ****/ + +#include "HttpParams.h" +#include "../Services/WebHelpers/escape.h" +#include "Print.h" + +size_t HttpParams::printTo(Print& p) const +{ + size_t charsPrinted = 0; + for(unsigned i = 0; i < count(); i++) { + if(i > 0) + charsPrinted += p.print('&'); + charsPrinted += p.print(uri_escape(keyAt(i))); + charsPrinted += p.print('='); + charsPrinted += p.print(uri_escape(valueAt(i))); + } + + return charsPrinted; +} diff --git a/Sming/SmingCore/Network/Http/HttpParams.h b/Sming/SmingCore/Network/Http/HttpParams.h new file mode 100644 index 0000000000..54d26a02ca --- /dev/null +++ b/Sming/SmingCore/Network/Http/HttpParams.h @@ -0,0 +1,41 @@ +/**** + * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. + * Created 2015 by Skurydin Alexey + * http://github.com/SmingHub/Sming + * All files of the Sming Core are provided under the LGPL v3 license. + * + * @author: 2018 - Mikee47 + * + * Class to manage HTTP URI query parameters + * + * The HttpParams class was an empty HashMap class living in 'Structures.h'. + * It has been expanded to incorporate escaping and unescaping. + * Custom URL parsing code has been replaced with the yuarel library https://github.com/jacketizer/libyuarel + * + ****/ + +#ifndef _SMINGCORE_HTTP_HTTP_PARAMS_H_ +#define _SMINGCORE_HTTP_HTTP_PARAMS_H_ + +#include "WString.h" +#include "WHashMap.h" +#include "Printable.h" + +/** @brief + * + * @todo values stored in escaped form, unescape return value and escape provided values. + * Revise HttpBodyParser.cpp as it will no longer do this job. + * + */ +class HttpParams : public HashMap, public Printable +{ +public: + virtual ~HttpParams() + { + } + + // Printable + virtual size_t printTo(Print& p) const; +}; + +#endif // _SMINGCORE_HTTP_HTTP_PARAMS_H_ diff --git a/Sming/SmingCore/Network/Http/HttpRequest.cpp b/Sming/SmingCore/Network/Http/HttpRequest.cpp index ca6ebfef93..9049b5def5 100644 --- a/Sming/SmingCore/Network/Http/HttpRequest.cpp +++ b/Sming/SmingCore/Network/Http/HttpRequest.cpp @@ -15,10 +15,6 @@ #include "Data/Stream/ChunkedStream.h" #include "Data/Stream/UrlencodedOutputStream.h" -HttpRequest::HttpRequest(const URL& uri) : uri(uri) -{ -} - HttpRequest::HttpRequest(const HttpRequest& value) : uri(value.uri) { *this = value; @@ -49,86 +45,7 @@ HttpRequest& HttpRequest::operator=(const HttpRequest& rhs) return *this; } -HttpRequest::~HttpRequest() -{ - reset(); -} - -HttpRequest* HttpRequest::setURL(const URL& uri) -{ - this->uri = uri; - return this; -} - -HttpRequest* HttpRequest::setMethod(const HttpMethod method) -{ - this->method = method; - return this; -} - -HttpRequest* HttpRequest::setHeaders(const HttpHeaders& headers) -{ - this->headers.setMultiple(headers); - return this; -} - -HttpRequest* HttpRequest::setHeader(const String& name, const String& value) -{ - this->headers[name] = value; - return this; -} - -HttpRequest* HttpRequest::setPostParameters(const HttpParams& params) -{ - postParams = params; - return this; -} - -HttpRequest* HttpRequest::setPostParameter(const String& name, const String& value) -{ - postParams[name] = value; - return this; -} - -HttpRequest* HttpRequest::setFile(const String& formElementName, FileStream* stream) -{ - if(stream == null) { - return this; - } - - files[formElementName] = stream; - - return this; -} - -#ifdef ENABLE_HTTP_REQUEST_AUTH -HttpRequest* HttpRequest::setAuth(AuthAdapter* adapter) -{ - adapter->setRequest(this); - auth = adapter; - return this; -} -#endif - -String HttpRequest::getHeader(const String& name) -{ - if(!headers.contains(name)) { - return ""; - } - - return headers[name]; -} - -String HttpRequest::getPostParameter(const String& name) -{ - if(!postParams.contains(name)) { - return ""; - } - - return postParams[name]; -} - -String HttpRequest::getQueryParameter(const String& parameterName, const String& defaultValue /* = "" */) +String HttpRequest::getQueryParameter(const String& parameterName, const String& defaultValue) { if(queryParams == nullptr) { queryParams = new HttpParams(); @@ -159,29 +76,29 @@ String HttpRequest::getQueryParameter(const String& parameterName, const String& String HttpRequest::getBody() { - if(stream == nullptr) { - return ""; + if(bodyStream == nullptr || bodyStream->getStreamType() != eSST_Memory) { + return nullptr; + } + + int len = bodyStream->available(); + if(len <= 0) { + // Cannot determine body size so need to use stream + return nullptr; } String ret; - if(stream->available() != -1 && stream->getStreamType() == eSST_Memory) { - MemoryDataStream* memory = (MemoryDataStream*)stream; - char buf[1024]; - while(stream->available() > 0) { - int available = memory->readMemoryBlock(buf, 1024); - memory->seek(available); - ret += String(buf, available); - if(available < 1024) { - break; - } - } + if(ret.setLength(len)) { + len = bodyStream->readMemoryBlock(ret.begin(), len); + // Just in case read count is less than reported count + ret.setLength(len); } + return ret; } ReadWriteStream* HttpRequest::getBodyStream() { - return stream; + return bodyStream; } HttpRequest* HttpRequest::setResponseStream(ReadWriteStream* stream) @@ -196,41 +113,10 @@ HttpRequest* HttpRequest::setResponseStream(ReadWriteStream* stream) return this; } -#ifdef ENABLE_SSL -HttpRequest* HttpRequest::setSslOptions(uint32_t sslOptions) -{ - this->sslOptions = sslOptions; - return this; -} - -uint32_t HttpRequest::getSslOptions() -{ - return sslOptions; -} - -HttpRequest* HttpRequest::pinCertificate(const SSLFingerprints& fingerprints) -{ - sslFingerprint = fingerprints; - return this; -} - -HttpRequest* HttpRequest::setSslKeyCert(const SSLKeyCertPair& keyCertPair) -{ - this->sslKeyCertPair = keyCertPair; - return this; -} - -#endif - -HttpRequest* HttpRequest::setBody(const String& body) -{ - return setBody((uint8_t*)body.c_str(), body.length()); -} - HttpRequest* HttpRequest::setBody(uint8_t* rawData, size_t length) { - MemoryDataStream* memory = new MemoryDataStream(); - int written = memory->write(rawData, length); + auto memory = new MemoryDataStream(); + auto written = memory->write(rawData, length); if(written < length) { debug_e("HttpRequest::setBody: Unable to store the complete body"); } @@ -240,41 +126,25 @@ HttpRequest* HttpRequest::setBody(uint8_t* rawData, size_t length) HttpRequest* HttpRequest::setBody(ReadWriteStream* stream) { - if(this->stream != nullptr) { + if(bodyStream != nullptr) { debug_e("HttpRequest::setBody: Discarding already set stream!"); - delete this->stream; - this->stream = nullptr; + delete bodyStream; + bodyStream = nullptr; } - this->stream = stream; - return this; -} - -HttpRequest* HttpRequest::onBody(RequestBodyDelegate delegateFunction) -{ - requestBodyDelegate = delegateFunction; - return this; -} - -HttpRequest* HttpRequest::onHeadersComplete(RequestHeadersCompletedDelegate delegateFunction) -{ - this->headersCompletedDelegate = delegateFunction; - return this; -} - -HttpRequest* HttpRequest::onRequestComplete(RequestCompletedDelegate delegateFunction) -{ - this->requestCompletedDelegate = delegateFunction; + bodyStream = stream; return this; } void HttpRequest::reset() { delete queryParams; - delete stream; - delete responseStream; queryParams = nullptr; - stream = nullptr; + + delete bodyStream; + bodyStream = nullptr; + + delete responseStream; responseStream = nullptr; postParams.clear(); @@ -289,7 +159,7 @@ void HttpRequest::reset() #ifndef SMING_RELEASE String HttpRequest::toString() { - String content = ""; + String content; #ifdef ENABLE_SSL content += F("> SSL options: ") + String(sslOptions) + '\n'; content += @@ -307,8 +177,8 @@ String HttpRequest::toString() content += headers[i]; } - if(stream != nullptr && stream->available() >= 0) { - content += headers.toString(HTTP_HEADER_CONTENT_LENGTH, String(stream->available())); + if(bodyStream != nullptr && bodyStream->available() >= 0) { + content += headers.toString(HTTP_HEADER_CONTENT_LENGTH, String(bodyStream->available())); } return content; diff --git a/Sming/SmingCore/Network/Http/HttpRequest.h b/Sming/SmingCore/Network/Http/HttpRequest.h index ff5736329a..73e39f8be6 100644 --- a/Sming/SmingCore/Network/Http/HttpRequest.h +++ b/Sming/SmingCore/Network/Http/HttpRequest.h @@ -21,6 +21,7 @@ #include "Data/Stream/DataSourceStream.h" #include "Data/Stream/MultipartStream.h" #include "Network/Http/HttpHeaders.h" +#include "HttpParams.h" class HttpClient; class HttpServerConnection; @@ -30,6 +31,9 @@ typedef Delegate RequestHea typedef Delegate RequestBodyDelegate; typedef Delegate RequestCompletedDelegate; +/* + * Encapsulates an incoming or outgoing request + */ class HttpRequest { friend class HttpClient; @@ -37,50 +41,111 @@ class HttpRequest friend class HttpServerConnection; public: - HttpRequest(const URL& uri); + HttpRequest() + { + } + + HttpRequest(const URL& uri) : uri(uri) + { + } + HttpRequest(const HttpRequest& value); - __forceinline HttpRequest* clone() const + + HttpRequest* clone() const { return new HttpRequest(*this); } + HttpRequest& operator=(const HttpRequest& rhs); - ~HttpRequest(); - HttpRequest* setURL(const URL& uri); + ~HttpRequest() + { + reset(); + } - HttpRequest* setMethod(const HttpMethod method); + HttpRequest* setURL(const URL& uri) + { + this->uri = uri; + return this; + } - HttpRequest* setHeaders(const HttpHeaders& headers); + HttpRequest* setMethod(HttpMethod method) + { + this->method = method; + return this; + } - HttpRequest* setHeader(const String& name, const String& value); + HttpRequest* setHeaders(const HttpHeaders& headers) + { + this->headers.setMultiple(headers); + return this; + } + + HttpRequest* setHeader(const String& name, const String& value) + { + headers[name] = value; + return this; + } + + /** + * @deprecated This method is deprecated and will be removed in the coming versions. + * Please set postParams directly, i.e. request.postParams = params + */ + HttpRequest* setPostParameters(const HttpParams& params) + { + postParams = params; + return this; + } - HttpRequest* setPostParameters(const HttpParams& params); - HttpRequest* setPostParameter(const String& name, const String& value); + HttpRequest* setPostParameter(const String& name, const String& value) + { + postParams[name] = value; + return this; + } /** * @brief Sets a file to be sent - * @param const String& name the name of the element in the form + * @param const String& formElementName the name of the element in the form * @param FileStream* stream - pointer to the file stream * * @return HttpRequest* */ - HttpRequest* setFile(const String& name, FileStream* stream); + HttpRequest* setFile(const String& formElementName, FileStream* stream) + { + if(stream) { + files[formElementName] = stream; + } + return this; + } #ifdef ENABLE_HTTP_REQUEST_AUTH // Authentication adapters set here - HttpRequest* setAuth(AuthAdapter* adapter); + HttpRequest* setAuth(AuthAdapter* adapter) + { + adapter->setRequest(this); + auth = adapter; + return this; + } #endif - String getHeader(const String& name); + const String& getHeader(const String& name) + { + return static_cast(headers)[name]; + } - String getPostParameter(const String& name); + const String& getPostParameter(const String& name) + { + return static_cast(postParams)[name]; + } - __forceinline String getPath() + /* @deprecated use uri methods */ + String getPath() { return uri.Path; } - String getQueryParameter(const String& parameterName, const String& defaultValue = ""); + /* @deprecated use uri methods */ + String getQueryParameter(const String& parameterName, const String& defaultValue = nullptr); /** * @brief Returns content from the body stream as string. @@ -88,17 +153,26 @@ class HttpRequest * * @note This method consumes the stream and it will work only with text data. * If you have binary data in the stream use getBodyStream instead. + * + * @note Allocation of String doubles amount of memory required, so use with care. */ String getBody(); /** - * @brief Returns pointer to the current body stream + * @brief Return the current body stream and pass ownership to the caller * @retval ReadWriteStream* + * @note may return null */ ReadWriteStream* getBodyStream(); - HttpRequest* setBody(const String& body); + HttpRequest* setBody(const String& body) + { + setBody((uint8_t*)body.c_str(), body.length()); + return this; + } + HttpRequest* setBody(ReadWriteStream* stream); + HttpRequest* setBody(uint8_t* rawData, size_t length); /** @@ -106,6 +180,8 @@ class HttpRequest * @param ReadWriteStream *stream * * @retval HttpRequest* + * + * @note The response to this request will be stored in the user-provided stream. */ HttpRequest* setResponseStream(ReadWriteStream* stream); @@ -117,15 +193,38 @@ class HttpRequest return responseStream; } - HttpRequest* onHeadersComplete(RequestHeadersCompletedDelegate delegateFunction); - HttpRequest* onBody(RequestBodyDelegate delegateFunction); - HttpRequest* onRequestComplete(RequestCompletedDelegate delegateFunction); + HttpRequest* onHeadersComplete(RequestHeadersCompletedDelegate delegateFunction) + { + headersCompletedDelegate = delegateFunction; + return this; + } + + HttpRequest* onBody(RequestBodyDelegate delegateFunction) + { + requestBodyDelegate = delegateFunction; + return this; + } + HttpRequest* onRequestComplete(RequestCompletedDelegate delegateFunction) + { + requestCompletedDelegate = delegateFunction; + return this; + } + + /** @brief Clear buffers and reset to default state in preparation for another request */ void reset(); #ifdef ENABLE_SSL - HttpRequest* setSslOptions(uint32_t sslOptions); - uint32_t getSslOptions(); + HttpRequest* setSslOptions(uint32_t sslOptions) + { + sslOptions = sslOptions; + return this; + } + + uint32_t getSslOptions() + { + return sslOptions; + } /** * @brief Requires(pins) the remote SSL certificate to match certain fingerprints @@ -134,7 +233,11 @@ class HttpRequest * * @return bool true of success, false or failure */ - HttpRequest* pinCertificate(const SSLFingerprints& fingerprints); + HttpRequest* pinCertificate(const SSLFingerprints& fingerprints) + { + sslFingerprint = fingerprints; + return this; + } /** * @brief Sets client private key, certificate and password from memory @@ -143,7 +246,11 @@ class HttpRequest * * @return HttpRequest pointer */ - HttpRequest* setSslKeyCert(const SSLKeyCertPair& keyCertPair); + HttpRequest* setSslKeyCert(const SSLKeyCertPair& keyCertPair) + { + sslKeyCertPair = keyCertPair; + return this; + } #endif #ifndef SMING_RELEASE @@ -169,7 +276,7 @@ class HttpRequest RequestBodyDelegate requestBodyDelegate; RequestCompletedDelegate requestCompletedDelegate; - ReadWriteStream* stream = nullptr; + ReadWriteStream* bodyStream = nullptr; ReadWriteStream* responseStream = nullptr; #ifdef ENABLE_HTTP_REQUEST_AUTH