-
Notifications
You must be signed in to change notification settings - Fork 194
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
Set negative value to second argument of esp_http_client_open
method if request header has Transfer-Encoding: chunked
#310
Set negative value to second argument of esp_http_client_open
method if request header has Transfer-Encoding: chunked
#310
Conversation
I will test it more and ask someone to review it later. |
I don't get it. Do you want to implement chunked encoding yourself? Because the built-in ESP IDF HTTP client does not support it. |
Actually I stand corrected. Chunked encoding DOES seems to be supported, after all. |
yeah we just need to make sure to then not set the content-length header ourself. Also we might need to check if the chunked support is only for the latest master / 5.1 or also included inside the 4.4.6 client so @ysak-y if you would check if it would work on both versions |
@ysak-y if you plan to finish this, you need to address the CI build errors. |
Thank you for your feedbacks. I'll try to implement it soon. Please just a while.
Yes, I know. I'll try to pass the CI later. |
9bd5ba6
to
0da0e59
Compare
UPDATEI investigated a86d5f7Convert type of 0da0e59Implement I thought ExampleI implement example code as follows (This is only HTTP part, not full example), and then got 200 response, and server accepted let payload = b"Hello";
let payload2 = b" World!!";
let headers = vec![
("Content-Type", "plain/text"),
("Transfer-Encoding", "chunked"),
];
let mut request = clinet.post(URL, &headers).unwrap();
// Write payload
request
.write(format!("{:X}", payload.len()).as_bytes())
.unwrap();
request.write(b"\r\n").unwrap();
request.write(payload).unwrap();
request.write(b"\r\n").unwrap();
// Write payload2
request
.write(format!("{:X}", payload2.len()).as_bytes())
.unwrap();
request.write(b"\r\n").unwrap();
request.write(payload2).unwrap();
request.write(b"\r\n").unwrap();
// Write ending
request.write(b"0\r\n\r\n").unwrap();
request.flush().unwrap();
let response = request.submit().unwrap(); Please refer following documents if you don't know how to write chunked data with streaming post. |
I think |
UPDATE: Let me look at the whole patch first. |
Ah, make sense. I agree with your opinion. I'll consider better way. |
…esp_http_client_open
esp_http_client_open
method if request header has Transfer-Encoding: chunked
Don't forget to handle the case when transfer-encoding chunked is set alongside with Content-Length. While the HTTP spec discourage it, to have both set, the client driver wouldn't probably complain. So we should cover that by either emitting a warning to the user or forbid it |
Ah... nice catch. My idea is just emit a warning or throw error. But, it may be server's responsibility. Actually, in NodeJS, built-in http server throws error when request has both ( I think basically client doesn't validate header values because there are some specification differences between server. We can notice mistakes if we get 400 BAD REQUEST error from server. What do you think? |
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.
Assuming you do the small changes suggested below, I think can merge.
What I actually STILL don't like in this approach is that the chunked encoding is left to the user. I get it that the ESP IDF client does not do it by default, but this is still annoying. For one, the ESP IDF server automatically decodes/encodes in chunked encoding, which is asymmetric to their client. I think also the ESP IDF client automatically decodes chunked encoding, so it is weird that it cannot encode it, no?
src/http/client.rs
Outdated
@@ -442,6 +451,18 @@ impl EspHttpConnection { | |||
panic!("connection is not in response phase"); | |||
} | |||
} | |||
|
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.
I think you don't need this method at all. This post says, that as long as you pass -1
to esp_http_client_open
, the client would assume chunked encoding.
@@ -399,7 +408,7 @@ impl EspHttpConnection { | |||
})?; | |||
esp!(unsafe { esp_http_client_set_redirection(self.raw_client) })?; | |||
esp!(unsafe { | |||
esp_http_client_open(self.raw_client, self.request_content_len as _) | |||
esp_http_client_open(self.raw_client, self.request_content_len as i32) |
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.
Please just change the type of EspHttpConnection::request_content_len
to i64
, as you originally started doing. Sorry for asking you to do other stuff - I did not realize, that request_content_len
is a private field which is not visible to the user.
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.
Okay, change type to i64
.
a7d084c
src/http/client.rs
Outdated
@@ -248,7 +248,16 @@ impl EspHttpConnection { | |||
|
|||
self.request_content_len = content_len.unwrap_or(0); |
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.
Assuming you'll change request_content_len
to i64
, as suggested below, just do here unwrap_or(-1)
src/http/client.rs
Outdated
esp!(unsafe { | ||
esp_http_client_open( | ||
self.raw_client, | ||
if self.is_chunked_streaming_request(headers) { |
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.
Remove the if
. Assuming is_chunked_streaming_request
is removed, and then unwrapping content-len
just sets request_content_len
to -1 if content_len
is None
, you'll no longer need it.
As you commented, change type of
I agree with it. But as you say, original |
This maybe your first impression, but we often have an opinionated implementation over the original raw idf api to make it first and foremost a good rust api. In fact the goal is to have our api stable compared to idf versions like between 4.4 and 5.1 and don't leak the original api out. Though in reality its not always so simple, so good compromises will win in the end. |
@ysak-y @Vollbrecht The crate now supports automatic chunked encoding (user does not have to do it herself, unless that's explicitly requested using the new Also I had to fix a buglet from this PR whereas if no |
What
Set nevative value to
request_content_len
property if can't unwrapcontent_len
somehow.Why
Ref: #309
I want to implement streaming http post that sets
Transfer-Encoding: chunked
to the header and doesn't setContent-Length
. But this library setsContent-Length: 0
if I don't setContent-Length
to the header and got 400 error (Please read above issue description).As I investigate, I can avoid this behavior and can get what I'm looking for if set negative value to the second argument of
esp_http_client_open
method.#309 (comment)
So I want to set negative value if can't fetch correct value from
content_len
.How
Set
request_content_len
type to i64 because I want to set negative value to it, and setrequest_content_len
property to -1 (Some negative value) if can't unwrapcontent_len
.