daurnimator / lua-http

HTTP Library for Lua. Supports HTTP(S) 1.0, 1.1 and 2.0; client and server.
https://daurnimator.github.io/lua-http/
MIT License
778 stars 80 forks source link

Unable to specify headers #169

Closed jcoetzee closed 4 years ago

jcoetzee commented 4 years ago

I get an error whenever I try specify headers to be used in new_from_uri()

local gz_headers = http_headers.new()
gz_headers:append(":method", "GET")
gz_headers:append("accept-encoding","gzip")
gz_headers:append("connection", "close")

local headers, stream = assert(http_request.new_from_uri(self.url, gz_headers):go(20 * second))

local headers, stream = assert(http_request.new_from_uri(self.url, gz_headers):go(20 * second))

Error:

error: PROTOCOL_ERROR(0x1): Protocol error detected: All pseudo-header fields MUST appear in the header block before regular header fields

stack traceback:
    /usr/local/share/lua/5.1/http/h2_stream.lua:396: in function 'validate_headers'
    /usr/local/share/lua/5.1/http/h2_stream.lua:1321: in function 'write_headers'
    /usr/local/share/lua/5.1/http/request.lua:519: in function 'go'
    ../Blocklist.lua:116: in function 'get_blocklist'
    ../Blocklist.lua:143: in function <../Blocklist.lua:129> stack traceback:
    [C]: in function 'error'
    /usr/local/share/lua/5.1/compat53/module.lua:159: in function 'assert'
    /usr/local/share/lua/5.1/http/h2_stream.lua:1321: in function 'write_headers'
    /usr/local/share/lua/5.1/http/request.lua:519: in function 'go'
    ../Blocklist.lua:116: in function 'get_blocklist'
    ../Blocklist.lua:143: in function <../Blocklist.lua:129>

The way I understand I am specifying pseudo-header fields before regular header fields?

daurnimator commented 4 years ago

When you provide a headers object to new_from_uri you should provide one with :authority :path and :scheme pseudo header fields.

Perhaps this can be improved on if it can be lightweight enough.

jcoetzee commented 4 years ago

Okay, I see. Looking at the code now I see that the values are upserted, so it would be sufficient to supply placeholder headers for these fields that will be replaced during the call?

I'm guessing that the problem lies with upserting appending if header doesn't exist.

daurnimator commented 4 years ago

Okay, I see. Looking at the code now I see that the values are upserted, so it would be sufficient to supply placeholder headers for these fields that will be replaced during the call?

I'm guessing that the problem lies with upserting appending if header doesn't exist.

yep. though I'm undecided if that's intentional behaviour or not.... The whole "pass a own header object" API is undocumented because I didn't want to commit to some of these decisions.

You're better off using new_from_uri with just a uri and then using :upsert afterwards.

jcoetzee commented 4 years ago

Ah, yes. That way is better. Thanks, working now.