0

PHP has a built in webserver (Example #3) where you can pass in a router file as an argument. Every request will go through that router file where you can do all kinds of things with the request.

php -S localhost:8000 router.php

The router file could look like this:

<?php
// router.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
   return false;    // serve the requested resource as-is.
} else { 
   echo "<p>Welcome to PHP</p>";
}
?>

Is that also possible with a Ruby webserver like Thin?

Thanks!

Frank Levering
  • 401
  • 3
  • 16

2 Answers2

2

This sounds a lot like sinatra, which is a very lightweight web framework for ruby.

For example, in a ruby file (say it's called server.rb):

require 'sinatra'
get "/" do
  "hello world"
end
get "/:foo" do
  "you typed #{params[:foo]}"
end

and in the terminal:

ruby server.rb
# => listening on port 4567

You can test it by going to localhost:4567 in the browser.

max pleaner
  • 26,189
  • 9
  • 66
  • 118
  • Yeah, I know about Sinatra. However, what I'm trying to achieve is to catch all those requests and based on the URI I want to run a Rack application dynamically. Sinatra is awesome for the web, but I don't think it's smart to use it for this specific task. – Frank Levering May 07 '16 at 21:26
  • @FrankLevering im not sure about running Rack applications "dynamically" except for dishing out shell commands. Have you taken a look at the [rack docs](http://rack.github.io/). Not trying to be pedantic, just saying throwing ideas i suppose. I wonder if you can use the " handle an app directly" example and add some sinatra routes in that file? – max pleaner May 07 '16 at 21:36
  • @FrankLevering You can also "mount" rack applications at specific endpoints. See [multiple-sinatra-apps-using-rack-mount](http://stackoverflow.com/questions/6496433/multiple-sinatra-apps-using-rack-mount) – max pleaner May 07 '16 at 21:40
  • 1
    Thanks for pointing me in the right direction. I kinda figured out a way of doing it. I created a config.ru that runs an app. Inside that app I am able to run other Rack apps based on for example the URI. – Frank Levering May 07 '16 at 22:02
  • @FrankLevering glad to hear that. I'd be interested to take a look at a gist of your code if you can – max pleaner May 07 '16 at 22:39
  • Sinatra is just a minimal Rack application, but if you want you can work with Rack directly if you need a more generic solution. – tadman May 08 '16 at 02:02
1

In your case I will use rack, this is a ruby:

  1. Rack includes handlers that connect Rack to all these web application servers (WEBrick, Mongrel etc.).
  2. Rack includes adapters that connect Rack to various web frameworks (Sinatra, Rails etc.).
  3. Between the server and the framework, Rack can be customized to your applications needs using middleware.

In order to use rack you must create rack application:

  1. must answer call method.
  2. The call mehtod is called by the server and must recevive an env variable with the CGI information.
  3. Must return an array with 3 elements: a) status: integer b) headers: hash c) body: An object that responds to each and for every call to each retuns a String.

The fundamental idea behind Rack middleware is – come between the calling client and the server, process the HTTP request before sending it to the server, and processing the HTTP response before returning it to the client.

this is the basic, answer of your question:

test_rack.rb

class MyApp
  def call env
        [200, {"Content-Type" => "text/html"}, ["Hello Rack Participants"]]
  end
end

config.ru

require './test_rack.rb'
run MyApp.new

then start up the application, and make a call to localhost:9292/anything

╭─toni@Antonios-MBP  ~/learn/ruby/stackoverflow/scripting ‹ruby-2.2.3@stackoverflow› ‹1.7› ‹SBCL 1.3.5›
╰─$ rackup config.ru
[2016-05-08 11:17:41] INFO  WEBrick 1.3.1
[2016-05-08 11:17:41] INFO  ruby 2.2.3 (2015-08-18) [x86_64-darwin15]
[2016-05-08 11:17:41] INFO  WEBrick::HTTPServer#start: pid=2610 port=9292
::1 - - [08/May/2016:11:18:04 +0200] "GET /patata HTTP/1.1" 200 - 0.0010
::1 - - [08/May/2016:11:18:04 +0200] "GET /favicon.ico HTTP/1.1" 200 - 0.0005
::1 - - [08/May/2016:11:18:09 +0200] "GET /patata/calimero HTTP/1.1" 200 - 0.0003

let's see rack working in console, see the multiple webservers and pass lambda for create the call function

require 'rack'
=> true
irb(main):010:0> Rack::Handler::constants
=> [:CGI, :FastCGI, :Mongrel, :EventedMongrel, :SwiftipliedMongrel, :WEBrick, :LSWS, :SCGI, :Thin]
irb(main):026:0> Rack::Handler::WEBrick.run lambda { |env| [200,{"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
[2016-05-08 11:22:39] INFO  WEBrick 1.3.1
[2016-05-08 11:22:39] INFO  ruby 2.2.3 (2015-08-18) [x86_64-darwin15]
[2016-05-08 11:22:39] INFO  WEBrick::HTTPServer#start: pid=1798 port=8080

to go further:

https://blog.engineyard.com/2015/understanding-rack-apps-and-middleware

https://github.com/rack/rack

anquegi
  • 11,125
  • 4
  • 51
  • 67