Я делаю это:
require 'rack/test'
data = # some binary data, for example, ZIP archive
put('/foo', data, 'content_type' => 'application/octet-stream')
Работает нормально, пока я не вставил символ %
в data
. В этом случае я получаю следующее:
Invalid query parameters: invalid %-encoding ... (long exception text)
Я не хочу кодировать свой data
в Base64 или CGI, потому что код на стороне сервера прекрасно работает и без теста. Проблема в том, как я использую Rack. Каким-то образом я должен сообщить ему, чтобы он не трогал мои данные и отправил их Синатре «как есть». Как?
Этот код воспроизводит проблему (просто запустите его как есть, и вы увидите, что напечатано):
require 'sinatra'
require 'minitest/autorun'
require 'rack/test'
put '/foo' do
'OK'
end
class FooTest < Minitest::Test
include Rack::Test::Methods
def app
Sinatra::Application
end
def test_me
put('/foo', 'hello % world')
assert_equal(200, last_response.status, last_response.body)
end
end
Я получаю это:
1) Failure:
FooTest#test_me [a.rb:18]:
Invalid query parameters: invalid %-encoding (hello % world).
Expected: 200
Actual: 400
Однако если я удалю символ %
, тест пройдет.
Вы можете добиться прохождения теста, указав заголовок Content-Type:
def test_me
put('/foo', 'hello % world', 'CONTENT_TYPE' => 'application/octet-stream')
assert_equal(200, last_response.status, last_response.body)
end
Обратите внимание, что ключ должен быть в верхнем регистре, как показано в примерах для Rack::Test.
В нижнем примере вы не задаете тип контента, поэтому предполагается
application/x-www-form-urlencoded
, что требует правильного процентного кодирования значений. Вероятно, это можно исправить, установив правильный тип контента.