-
Notifications
You must be signed in to change notification settings - Fork 13.3k
HTTPClient: implement Stream class #6977
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
base: master
Are you sure you want to change the base?
Conversation
a POST example with |
No, currently the HTTPClient supports only receiving with chunked encoding, and doesn't implement the sending part; that was the case also without this Stream implementation. |
but with this PR HTTPClient has |
Actually it's not true that the payload can be sent only at once: you can start an HTTP request via |
ok. sorry. I didn't have an opportunity to use the ESP8266HTTPClient. But to send a POST request the Content-length header should be set or chunked transfer encoding should be used. And providing the Stream to a function which composes the request body usually means that we don't know the content-length before. |
These new methods will be reused in the next commit when an implementation of the Stream class will be added to the HTTPClient class. HTTPClient::writeToStream() is being refactored to use the new methods.
It is now possible to stream HTTP request data without knowing in advance the data size (using chunked transfer encoding), and to stream HTTP response data (correctly decoded according to the transfer encoding method used by the server) without requiring an output Stream implementation. (The existing getStream() method in the HTTPClient class returns the underlying WiFiClient stream which is not aware of the HTTP transfer encoding.) When using chunked encoding in an HTTP request, each call to write() results in the transmission of a separate chunk. The setting of _transferEncoding to HTTPC_TE_IDENTITY in the handleHeaderResponse() method has been removed because _transferEncoding is now used for both transmission and reception, and is reset to HTTPC_TE_IDENTITY in the clear() method.
OK, I added chunked encoding support in HTTP request transmission as well. |
This proposal
Legacy behaviour seems to be OK. |
An example where this addition would be useful is at https://github.com/francescolavra/arduino-iota-client/blob/f6ce76453cfa1984df14b3be9b6de478a44e40b6/src/IotaClient.cpp#L355, where we need to parse a JSON string coming from an HTTP response: the existing code calls the getStream() method of the HTTPClient class, but this method returns the underlying WiFiClient stream which is not aware of the HTTP transfer encoding, so the parsing will fail if the HTTP server uses chunked encoding in its response; with this addition, the above code can be changed to pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
return -1; | ||
} | ||
return _client->peek(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
peek()
is using available()
to manage chunk-encoded streams.
Can read()
do the same instead of duplicating code ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think something like below would work for read()
:
while (!available()) {
if (!connected()) {
return -1;
}
yield();
}
if (_transferEncoding == HTTPC_TE_CHUNKED) {
_chunkOffset++;
}
return _client->read();
But I'm afraid I don't have time to dig up my development environment and an ESP8266 to test this code.
Hey! What changes should be done to finally merge these? |
It is now possible to stream HTTP request data without knowing in advance the data size (using chunked transfer encoding), and to stream HTTP response data (correctly decoded according to the transfer encoding method used by the server) without requiring an output Stream implementation.
(The existing getStream() method in the HTTPClient class returns the underlying WiFiClient stream which is not aware of the HTTP transfer encoding.)
When using chunked encoding in an HTTP request, each call to write() results in the transmission of a separate chunk. An example code snippet is below:
A primary use case for using the Stream implementation to receive an HTTP response is when parsing large response data: using the HTTPClient Stream implementation, the parser does not require an in-memory buffer where the entire HTTP response data is stored.