Skip to content

Commit

Permalink
Add ability to set Content-Type and Content-Length HTTP headers
Browse files Browse the repository at this point in the history
According to the Rack documentation, those headers are not supported through the HTTP_ variables:
https://www.rubydoc.info/github/rack/rack/file/SPEC#The_Environment
  • Loading branch information
mateusg committed May 24, 2018
1 parent 28fe619 commit 4bf1e14
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [1.4.0] - unreleased
- Support non-GET requests via REQUEST_METHOD and setting body via REQUEST_BODY
- Add ability to set Content-Type and Content-Length headers via CONTENT_TYPE and CONTENT_LENGTH env vars (they don't work with HTTP_ variables)


## [1.3.4]
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ $ HTTP_AUTHORIZATION="Basic YWRtaW46c2VjcmV0\n" \
PATH_TO_HIT=/foo_secret bundle exec derailed exec perf:ips
```

The `Content-Type` and `Content-Length` headers are a bit different. To set those, ignore the HTTP_ prefix, use the `CONTENT_TYPE` and `CONTENT_LENGTH` variables.

### Performing non-GET requests

If the endpoint being tested is not a GET request, you can set the `REQUEST_METHOD` variable with the HTTP method you want (e.g. POST, PUT, PATCH, DELETE).
Expand All @@ -446,7 +448,8 @@ To set the request body, you can use the `REQUEST_BODY`.

```
$ REQUEST_METHOD=POST \
REQUEST_BODY="user%5Bemail%5D=foo%40bar.com&user%password%5D=123456&user%password_confirmation%5D=123456" \
REQUEST_BODY="{\"user\":{\"email\":\"foo@bar.com\",\"password\":\"123456\",\"password_confirmation\":\"123456\"}}" \
CONTENT_TYPE="application/json" \
PATH_TO_HIT=/users \
bundle exec derailed exec perf:test
```
Expand Down
14 changes: 12 additions & 2 deletions lib/derailed_benchmarks/tasks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,22 @@
puts "Endpoint: #{ PATH_TO_HIT.inspect }"

# See https://www.rubydoc.info/github/rack/rack/file/SPEC#The_Environment
# All HTTP_ variables are accepted in the Rack environment hash, except HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH.
# For those, the HTTP_ prefix has to be removed.
HTTP_HEADER_PREFIX = "HTTP_".freeze
RACK_ENV_HASH = ENV.select { |key| key.start_with?(HTTP_HEADER_PREFIX) }
HTTP_HEADER_REGEXP = /^#{HTTP_HEADER_PREFIX}.+|CONTENT_(TYPE|LENGTH)$/
RACK_ENV_HASH = ENV.select { |key| key =~ HTTP_HEADER_REGEXP }

HTTP_HEADERS = RACK_ENV_HASH.keys.inject({}) do |hash, rack_header_name|
# e.g. "HTTP_ACCEPT_CHARSET" -> "Accept-Charset"
header_name = rack_header_name[HTTP_HEADER_PREFIX.size..-1].split("_").map(&:downcase).map(&:capitalize).join("-")
upper_case_header_name =
if rack_header_name.start_with?(HTTP_HEADER_PREFIX)
rack_header_name[HTTP_HEADER_PREFIX.size..-1]
else
rack_header_name
end

header_name = upper_case_header_name.split("_").map(&:downcase).map(&:capitalize).join("-")

hash[header_name] = RACK_ENV_HASH[rack_header_name]
hash
Expand Down
19 changes: 19 additions & 0 deletions test/integration/tasks_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,25 @@ def rake(cmd, options = {})
assert_match 'HTTP headers: {"Authorization"=>"Basic YWRtaW46c2VjcmV0\n", "Cache-Control"=>"no-cache"}', result
end

test 'CONTENT_TYPE' do
env = {
"REQUEST_METHOD" => "POST",
"PATH_TO_HIT" => "users",
"CONTENT_TYPE" => "application/json",
"REQUEST_BODY" => '{"user":{"email":"foo@bar.com","password":"123456","password_confirmation":"123456"}}',
"TEST_COUNT" => "2"
}

result = rake "perf:test", env: env
assert_match 'Body: {"user":{"email":"foo@bar.com","password":"123456","password_confirmation":"123456"}}', result
assert_match 'HTTP headers: {"Content-Type"=>"application/json"}', result

env["USE_SERVER"] = "webrick"
result = rake "perf:test", env: env
assert_match 'Body: {"user":{"email":"foo@bar.com","password":"123456","password_confirmation":"123456"}}', result
assert_match 'HTTP headers: {"Content-Type"=>"application/json"}', result
end

test 'REQUEST_METHOD and REQUEST_BODY' do
env = {
"REQUEST_METHOD" => "POST",
Expand Down

0 comments on commit 4bf1e14

Please sign in to comment.