Closed LianYangCn closed 2 years ago
I guess you could ask the same thing about delete: why no http.delete()
? @tomsci obviously saw no need for that when he contributed the module.
As PUT is almost identical to POST apart from the method designator in the header it should be little effort to port https://github.com/nodemcu/nodemcu-firmware/blob/dev-esp32/components/modules/http.c#L745 I assume. Also, note that there's a constant HTTP_METHOD_PUT
in the ESP-IDF that we have not mapped yet at https://github.com/nodemcu/nodemcu-firmware/blob/dev-esp32/components/modules/http.c#L786.
It's possible to specify a custom request method to http.createConnection()
without there needing to be an explicit http.put()
function. http.post()
is just a convenience function to save you having to use the more complex createConnection()
API. I didn't add convenience functions for anything except get and post, since those are by far the most commonly used ones.
However, as noted we haven't defined a http.PUT
constant. We should definitely fix that, it was an oversight on my part not to have added it.
If you really want a convenience put method, you could write something like the following, no need to add any native code. Although we should fix the lack of http.PUT
- the or 2
below accounts for this such that when we do add it, it'll be used, and until then it uses the underlying esp_http_client_method_t
value directly (which is ok so long as we don't upgrade to a new SDK version that renumbers esp_http_client_method_t without first adding http.PUT
).
Note this is completely untested and only handles the synchronous case, and ignores what data the server may return (if any) - see the http docs (in particular connection:on()
) for how to make things callback-based.
function http_put(url, options, body)
local PUT = http.PUT or 2 -- handle http.PUT potentially not being defined yet
options = options or {}
options.async = false
local conn = http.createConnection(url, PUT, options)
conn:setpostdata(body) -- is this still the correct format for a PUT request?
conn:setmethod(PUT) -- because setpostdata resets this
conn:setheader("Connection", "close") -- we aren't reusing conn
local response_headers = nil
conn:on("headers", function(_, h) response_headers = h end)
local status_code = conn:request()
return status_code, response_headers
end
It's possible to specify a custom request method to
http.createConnection()
Absolutely, I didn't mention it because I was too lazy to provide an example. Thanks a lot! Besides, I made a mental note that if we start changing/amending the module I'd prefer to
:setpostdata(body)
to setbody(body)
as POST isn't the only method that can have or does require a bodysetpostdata/setbody
as a consequenceAgreed, both of those sound like a good idea 👍 I only named it setpostdata because that's what the ESP SDK calls it (and I clearly wasn't thinking much about put!)
It's possible to specify a custom request method to
http.createConnection()
without there needing to be an explicithttp.put()
function.http.post()
is just a convenience function to save you having to use the more complexcreateConnection()
API. I didn't add convenience functions for anything except get and post, since those are by far the most commonly used ones.However, as noted we haven't defined a
http.PUT
constant. We should definitely fix that, it was an oversight on my part not to have added it.If you really want a convenience put method, you could write something like the following, no need to add any native code. Although we should fix the lack of
http.PUT
- theor 2
below accounts for this such that when we do add it, it'll be used, and until then it uses the underlyingesp_http_client_method_t
value directly (which is ok so long as we don't upgrade to a new SDK version that renumbers esp_http_client_method_t without first addinghttp.PUT
).Note this is completely untested and only handles the synchronous case, and ignores what data the server may return (if any) - see the http docs (in particular
connection:on()
) for how to make things callback-based.function http_put(url, options, body) local PUT = http.PUT or 2 -- handle http.PUT potentially not being defined yet options = options or {} options.async = false local conn = http.createConnection(url, PUT, options) conn:setpostdata(body) -- is this still the correct format for a PUT request? conn:setmethod(PUT) -- because setpostdata resets this conn:setheader("Connection", "close") -- we aren't reusing conn local response_headers = nil conn:on("headers", function(_, h) response_headers = h end) local status_code = conn:request() return status_code, response_headers end
Great! It's simple and works.
http module miss PUT
why miss PUT?
Justification
We need PUT to upload objects to the Object Storage Service
Workarounds
POST works, but it will take more time to convert the object to the "POST" format