11

I'm migrating servers but unfortunately the old server IP is hardcoded inside my iPhone app. Obviously I'm going to submit an update that sets the API endpoint to my new server, but in the meantime I need to setup an app on the old server that redirects all the requests to the new server. I've heard Sinatra would be perfect for this.

require 'sinatra'

get "/foo/bar" do
    redirect "http://new-server.com/foo/bar", 303
end

post "/foo/bar" do
    redirect "http://new-server.com/foo/bar", 303
end

The problem is that these do not forward the GET or POST parameters along with the request. I read on the Sinatra doc that you can do that by putting them in the URL directly (works for GET requests), or by setting session variables.

Is manually parsing and formatting the GET params to put them back into the redirect URL the only way to go for GET redirects? How are you supposed to forward POST parameters?

Nakilon
  • 34,866
  • 14
  • 107
  • 142
samvermette
  • 40,269
  • 27
  • 112
  • 144
  • See [this post](http://stackoverflow.com/questions/798710/how-to-turn-a-ruby-hash-into-http-params) to ease the parsing and formatting. As for POST, you could always turn them into GET params, and change your server side logic to accept either. I'm not sure if there's a better way for your use-case. – Jonah Aug 13 '12 at 01:46

2 Answers2

12

For GET requests, use request.fullpath or request.query_string. For POST request, use status code 307, so the subsequent request will be a POST with the same parameters.

helpers do
  def new_url
    "http://new-server.com" + request.fullpath
  end
end

get "/foo/bar" do
  redirect new_url
end

post "/foo/bar" do
  redirect new_url, 307
end
Konstantin Haase
  • 25,687
  • 2
  • 57
  • 59
2

I would overload the Hash class in lib/overload_hash.rb, like so:

class Hash
  def to_url_params
    elements = []
    keys.size.times do |i|
      elements << "#{keys[i]}=#{values[i]}"
    end
    elements.join('&')
  end
end

EDIT (Better solution using net / http)

Place a require "lib/overload_hash", require "net/http" and require "uri" under require 'sinatra'. The following example can be translated into GET easily.

post '/foo/bar' do
  uri = URI.parse("http://example.com/search")
  response = Net::HTTP.post_form(uri, params.to_ur_params) 
  response
end
briangonzalez
  • 1,606
  • 16
  • 21
  • Thanks, that really helps for GET request redirection. But what about POST redirection? I read at a couple of places that you can't redirect POST requests, but I also saw that status codes 303, 307 and 308 redirect a request **without** changing the HTTP method... – samvermette Aug 17 '12 at 22:35
  • 1
    303 changes the request, you need to use 307 (see my answer) – Konstantin Haase Aug 20 '12 at 10:37