Skip to content

Instantly share code, notes, and snippets.

@claco
Created February 7, 2012 21:57
Show Gist options
  • Save claco/f361516ee8686637ee23 to your computer and use it in GitHub Desktop.
Save claco/f361516ee8686637ee23 to your computer and use it in GitHub Desktop.
URL Mangling...
Given this url:
http://example.com/?select=a&select=b
In a real rails app, request in controller is ActionController::Request, and #url returns: http://example.com/?select=a&select=b
In Rspec "request" specs:
get "http://example.com/?select=a&select=b"
request in the spec and in the controller code is AcitonDispatch::Request, and #url (request.url in the controller) now returns "http://example.com/?select=b"
The ActionDispatch inspect yields a bogus @full_path, but REQUET_URI is in tact.
Near as I can figure, Rack::Test, or Dispatch, or something is parsing the query string as parse_nested_query, which is fine, but in the process, #url is not returning the same thing in ActionDispatch::Request that id does in a real world rails app request in ActionController::Request.
I'm stumped after looking at the source. Ideas?
-----
#<ActionDispatch::Request:0x11bb01910 @fullpath="/api/members?_signature=5ZwgwR45YruA3fBnVysWbemHPkrt12VpigT7%2F6%2FLHMg%3D&select=token", @method="GET", @filtered_parameters={"action"=>"index", "_signature"=>"5ZwgwR45YruA3fBnVysWbemHPkrt12VpigT7/6/LHMg=", "controller"=>"api/members", "select"=>"token"}, @env={"action_dispatch.request.formats"=>[#<Mime::Type:0x104df21b8 @string="application/json", @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json>], "action_dispatch.request.parameters"=>{"action"=>"index", "_signature"=>"5ZwgwR45YruA3fBnVysWbemHPkrt12VpigT7/6/LHMg=", "select"=>"token", "controller"=>"api/members"}, "rack.session"=>{}, "rack.test"=>true, "HTTP_ACCEPT"=>"application/json", "HTTP_HOST"=>"www.example.com", "SERVER_NAME"=>"www.example.com", "rack.request.cookie_hash"=>{}, "action_dispatch.remote_ip"=>#<ActionDispatch::RemoteIp::RemoteIpGetter:0x11bc4de40 @trusted_proxies=/(^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.)/i, @env={...}, @check_ip_spoofing=true>, "CONTENT_LENGTH"=>"0", "rack.url_scheme"=>"http", "action_dispatch.request.query_parameters"=>{"_signature"=>"5ZwgwR45YruA3fBnVysWbemHPkrt12VpigT7/6/LHMg=", "select"=>"token"}, "action_dispatch.request.unsigned_session_cookie"=>{}, "CONTENT_TYPE"=>"application/x-www-form-urlencoded", "HTTPS"=>"off", "rack.errors"=>#<StringIO:0x11bc612b0>, "action_dispatch.request.accepts"=>[#<Mime::Type:0x104df21b8 @string="application/json", @synonyms=["text/x-json", "application/jsonrequest"], @symbol=:json>], "action_dispatch.secret_token"=>"aa29852b13417d43f4a1b48343dcbc40f065f6e87ec1985cb038e331881a165b4b52140feac36964e32016505c02fca1e06115a7f888b2e169f3fd6e5dfebbf5", "REMOTE_ADDR"=>"127.0.0.1", "PATH_INFO"=>"/api/members", "rack.version"=>[1, 1], "rack.run_once"=>false, "action_dispatch.request.path_parameters"=>{:controller=>"api/members", :action=>"index"}, "rack.request.cookie_string"=>"", "SCRIPT_NAME"=>"", "action_dispatch.parameter_filter"=>[:password, :password, :password], "action_dispatch.show_exceptions"=>true, "HTTP_COOKIE"=>"", "rack.multithread"=>false, "action_dispatch.request.request_parameters"=>{}, "rack.request.form_vars"=>"", "action_dispatch.cookies"=>{}, "REQUEST_URI"=>"/api/members?select=id&select=guid&select=primary_email_address&select=token&_signature=5ZwgwR45YruA3fBnVysWbemHPkrt12VpigT7%2F6%2FLHMg%3D", "rack.multiprocess"=>true, "rack.request.query_hash"=>{"_signature"=>"5ZwgwR45YruA3fBnVysWbemHPkrt12VpigT7/6/LHMg=", "select"=>"token"},
@dchelimsky
Copy link

@claco I'm almost 100% certain this is not rspec, since the get method in a request spec is defined in actionpack-3.1.3/lib/action_dispatch/testing/integration.rb and rspec does not override it in any way. A quick debugging session showed that by the time we get to actionpack-3.1.3/lib/action_dispatch/http/request.rb:39, env["QUERY_STRING"] is "select=b". I'm guessing that the query string is built by converting it to hash and then back, thus overwriting the "select" key with the value "b", but I'm not sure where that happens.

@claco
Copy link
Author

claco commented Feb 10, 2012

Thanks for looking into this. I wasn't sure if Rspec was making it's own ActionDispatch or letting Rack::Test do it, since controller specs seems to work just fine.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment