HttpService: Support multiple headers

The HTTP protocol allows headers to be specified multiple times. HTTPService, on the other hand, does not.

Currently, the request headers table must be a dictionary, where each entry is a string (header name) mapped to a string (header value). Likewise, the response headers table is a dictionary of the same constraints; if a header is received multiple times, the value of the latest header is selected.

This topic proposes to extend these header tables to allow multiple headers to be sent and received, by allowing an entry in a header table to be either a string, or a table of strings.

Requests

The Headers field is a Dictionary, where an entry value may be a string, or a table of strings. When building the request, an entry with a table value repeats the header for each string in the table.

Responses

When constructing the Headers table, the header value being processed is compared to its current entry in the table:

  • If the entry value is nil, the received value is added to the Headers table as a string.
  • If the entry value is a table, the received value is appended to that table.
  • If the entry value is a string, the entry value is replaced with a table containing the original value, along with the received value.

This produces a Headers table where single-header entries are strings, and multi-header entries are tables of strings.

Example

The following example sends multiple headers to a theoretical endpoint that responds with the headers sent by the request:

local resp = game.HttpService:RequestAsync({
	Url = "https://example.com/bounce_headers",
	Headers = {
		["x-foobar"] = {"One", "Two", "Three", "Four"},
	},
})

This would send the following headers:

x-foobar: One
x-foobar: Two
x-foobar: Three
x-foobar: Four

The following example would print the response headers:

for name, value in pairs(resp.Headers) do
	if type(value) == "table" then
		for _, value in pairs(value) do
			print("Header: " .. name .. " = " .. value)
		end
	else
		print("Header: " .. name .. " = " .. value)
	end
end

This would print the following:

Header: x-foobar = One
Header: x-foobar = Two
Header: x-foobar = Three
Header: x-foobar = Four
6 Likes

What development use cases do you need this for? I understand the protocol allows this and ideally they should support this just to be in line with the protocol, but for Roblox to prioritize implementing it, they would need to know your use cases so they can justify the effort. It might be useful to add a few to your topic.

4 Likes

This topic is merely highlighting the incompatibility with the HTTP protocol. Personally, I have no use cases. Obviously multi-headers do not appear often enough for this to have any sort of priority.

Inevitably, some developer will come across the one 3rd party service that uses multi-headers, then be woefully delayed by Roblox’s lack of support for them. The goal of this topic is to outline the solution to point where it’s easy enough to implement within a single release cycle, hopefully keeping that poor developer’s inconvenience to a minimum.

1 Like

Thank you for the feedback, but given the lack of use cases fixing this will be low priority. We prefer to work on things which we know will have impact. :slight_smile:

3 Likes

this should also be extended to response headers, set-cookie uses multiple response headers but since it keeps overriding the same index on the headers it only gives the last value


image

2 Likes

for example, like in other languages, make headers with multiple values into an array with every header value