dnsbty
Only get response headers with Req?
I’m currently using Req in an application, and as I’m thinking about potential security concerns, I have two scenarios in mind where I would like to check the response headers before getting the full body.
For webhooks, I really only care about the headers. If, for example, someone were to sign up and respond to my webhook request with a large payload, I would rather not load the full response payload into memory. Since all I really care about is the HTTP response status code, is it possible to get only that? I was looking at doing something like this, but wondered if there’s a better way:
resp = Req.get!(endpoint.url, into: :self)
Req.cancel_async_response(resp)
For downloading files from URLs sent to my API, I would like to check that the file size and mime type are within our expected parameters before downloading the body. Is this the best way to do that?
resp = Req.get!(file.url, into: :self)
mime_type = Req.Response.get_header(resp, "content-type")
content_length = Req.Response.get_header(resp, "content-length")
cond do
mime_type not in @supported_mime_types ->
Req.cancel_async_response(resp)
{:error, :unsupported_file_type}
content_length > @max_file_size ->
Req.cancel_async_response(resp)
{:error, :file_too_big}
true ->
{:ok, resp.body}
end
Thanks!
Marked As Solved
wojtekmach
I think making a HEAD request is the most straightforward. Other than that, either into: :self + cancel (though you’d probably have received some messages by then) or into: fun:
iex> Req.get!("https://httpbin.org/status/201", into: fn {req, resp}, acc -> {:halt, {req, resp}} end)
%Req.Response{
status: 201,
headers: %{
"access-control-allow-credentials" => ["true"],
"access-control-allow-origin" => ["*"],
"connection" => ["keep-alive"],
"content-length" => ["0"],
"content-type" => ["text/html; charset=utf-8"],
"date" => ["Fri, 08 Nov 2024 19:55:52 GMT"],
"server" => ["gunicorn/19.9.0"]
},
body: "",
trailers: %{},
private: %{}
}
Also Liked
mayel
wojtekmach
Oh, for checking content-type, file size, etc, I’d use into: fun too. It’s more efficient than into: :self in that it uses the socket in passive mode so you can easily halt before reading any body part.







