user2446058
user2446058

Reputation: 166

serve a single image with sinatra no matter whats asked for

I'm serving an image with sinatra, but when you go the image, I want sinatra to serve up another image. So every image that is asked for on the server, will return a static image.

%w[sintra].each{|gem| require gem}

# <img src="https://www.mywebsite.com/1234.png">
# <img src="https://www.mywebsite.com/abcd.png">

get '/:image' do 
 image = params[:image].split(".")[0]
 # image = 1234

 if image == key 
  #do stuff
 else
  #do other stuff
 end

 #this is where I'm having a problem
 special_code_that_replaces_1234.png = "static_image_on_server.png"
 #so sinatra should return "static_image_on_server.png" no matter what image is asked for. 

end

I've looked through the documentation for sinatra. This specifically. http://www.sinatrarb.com/intro.html#Accessing%20the%20Request%20Object I may be looking at the wrong part, "Triggering Another Route" I think I'm running in circles.

My app does have a "public" directory with "static_image_on_server.png"

Upvotes: 4

Views: 2060

Answers (2)

7stud
7stud

Reputation: 48599

This answer assumes you have a directory public/imgs where you store your images:

With redirect():

require 'sinatra'

get "/imgs/*.*" do
  img_name, ext = params[:splat]

  if image_name == key 
    #do stuff
  else
    #do other stuff
  end

  redirect to('/imgs/alien1.png')
end

By default, Sinatra will first check if the requested file is in the ./public folder and return it if it exists. If the file isn't in ./public, then Sinatra will try to match a route. So the code in a route cannot prevent a user from seeing existing images in your public folder.

You can add disable :static to the top of your routes file to stop Sinatra from looking in ./public for the requested file. Instead, Sinatra will go straight to route matching. In that case, the redirect() in the example WILL cause an infinite loop. So if you have images in the public folder that you don't want users to see, you can't use redirect().

With send_file():

It looks like tadman's send_file() solution requires an absolute(or relative) file system path, so you can do this:

require 'sinatra'

get "/imgs/*.*" do
  img_name, ext = params[:splat]

  if image_name == key 
    #do stuff
  else
    #do other stuff
  end

  send_file File.expand_path('imgs/alien1.png', settings.public_folder)
end

Note that with send_file(), the original url, with the originally requested image, will remain displayed in the browser, which may or may not be what you want.

Upvotes: 3

tadman
tadman

Reputation: 211590

Normally this is handled like this:

get '/*.*' do
 # ... Your code ...

 # Send static file.
 send_file 'static_image_on_server.png'
end

Upvotes: 2

Related Questions