Dru
Dru

Reputation: 9820

Post Data via Url with Ruby

I am developing an api-like app that allows other applications to send requests which trigger a series of actions in the api-like application. I need to find a way to send large parameters (embed code) via url. I'm using Sinatra.

My first attempt: (Doesn't work because embed code is not an acceptable url parameter)

get '/grab/:name/:bucket/:embed_code' do
  @video = Video.create(
    :name => params[:name],
    :bucket => params[:bucket],
    :embed_code => params[:embed_code],
    :created_at => Time.now
  )
  redirect "/video/#{@video.id}"
end

My second attempt: (Connection refused - connect(2) (Errno::ECONNREFUSED) Error)

# (get '/video_form') points to (post '/video') and post_form was supposed to trigger it

get '/video_form' do
  erb :new_video
end

post '/video' do
  @video = Video.create(
    :name => params[:name],
    :bucket => params[:bucket],
    :embed_code => params[:embed_code],
    :created_at => Time.now
  )
  redirect "/video/#{@video.id}"
end

Net::HTTP.post_form(URI.parse('http://localhost:4567/video_form'),{'name'=>'example_2', 'bucket' => 'bucket_name', 'embed_code' => '<iframe width="560" height="315" src="http://www.youtube.com/embed/ncL1UlvjiMQ" frameborder="0" allowfullscreen></iframe>'})

Upvotes: 0

Views: 711

Answers (1)

Phrogz
Phrogz

Reputation: 303215

A proper GET request might look like http://localhost/getit?embed=%3Ciframe%20width%3D%22560%22%20height%3D%22315%22%20src%3D%22youtube.com/embed/ncL1UlvjiMQ%22%3B%20frameborder%3D%220%22%20allowfullscreen%3E%3C/iframe%3E. For more information, read up on Encoding Query String Parameters. Quoting:

Some characters cannot be part of a URL (for example, the space) and some other characters have a special meaning in a URL: for example, the character # can be used to further specify a subsection (or fragment) of a document; the character = is used to separate a name from a value. A query string may need to be converted to satisfy these constraints. This can be done using a schema known as URL encoding.

In particular, encoding the query string uses the following rules:

  • Letters (A-Z and a-z), numbers (0-9) and the characters .,-,~ and _ are left as-is
  • SPACE is encoded as + or %20
  • All other characters are encoded as %FF hex representation with any non-ASCII characters first encoded as UTF-8 (or other specified encoding)

You can try this yourself via:

<form method="get" action="/getit">
  <input type="hidden" name="embed" value='<iframe width="560" height="315" src="youtube.com/embed/ncL1UlvjiMQ"; frameborder="0" allowfullscreen></iframe>'>
  <button>GO</button>
</form>

Notice that with this you don't have to encode the value yourself; the web browser does that when it sends the form. Alternatively, you can make this GET request via JavaScript:

var embed = '<iframe width="560" height="315" src="youtube.com/embed/ncL1UlvjiMQ"; frameborder="0" allowfullscreen></iframe>';
location.href = "http://localhost/getit?embed="+escape(embed);

A POST request doesn't show up on the query string, but is encoded by the browser. Take the same HTML as above and change the method, and watch Sinatra receive it.

To receive a complex parameter in Sinatra don't try to make it part of the path, receive it as a proper parameter on the query string:

get "/getit" do
  p params['embed']
end

Upvotes: 2

Related Questions