Subsecciones

Analizando env con pry-debugger

Introducción

Tenemos esta sencilla aplicación:

~/local/src/ruby/sinatra/rack/rack-debugging]$ cat hello.rb 
require 'rack'
require 'pry-debugger'

class HelloWorld
  def call env
    binding.pry
    [200, {"Content-Type" => "text/plain"}, ["Hello world"]]
  end
end

Arrancamos un servidor:

[~/local/src/ruby/sinatra/rack/rack-debugging]$ pry
[1] pry(main)> require './hello'
=> true
[6] pry(main)> Rack::Handler::WEBrick.run HelloWorld.new
[2013-09-23 12:36:21] INFO  WEBrick 1.3.1
[2013-09-23 12:36:21] INFO  ruby 1.9.3 (2013-02-22) [x86_64-darwin11.4.2]
[2013-09-23 12:36:21] INFO  WEBrick::HTTPServer#start: pid=9458 port=8080

En otra ventana arrancamos un cliente:

[~/local/src/ruby/sinatra/rack/rack-testing/bindaddress(master)]$ curl -v localhost:8080
* About to connect() to localhost port 8080 (#0)
*   Trying ::1... connected
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5
> Host: localhost:8080
> Accept: */*
>

En la ventana del servidor ahora aparece:

From: /Users/casiano/local/src/ruby/sinatra/rack/rack-debugging/hello.rb @ line 6 HelloWorld#call:

    5: def call env
 => 6:   binding.pry
    7:   [200, {"Content-Type" => "text/plain"}, ["Hello world"]]
    8: end
Ahora podemos inspeccionar las variables:
[1] pry(#<HelloWorld>)> env
=> {"GATEWAY_INTERFACE"=>"CGI/1.1",
 "PATH_INFO"=>"/",
 "QUERY_STRING"=>"",
 "REMOTE_ADDR"=>"::1",
 "REMOTE_HOST"=>"localhost",
 "REQUEST_METHOD"=>"GET",
 "REQUEST_URI"=>"http://localhost:8080/",
 "SCRIPT_NAME"=>"",
 "SERVER_NAME"=>"localhost",
 "SERVER_PORT"=>"8080",
 "SERVER_PROTOCOL"=>"HTTP/1.1",
 "SERVER_SOFTWARE"=>"WEBrick/1.3.1 (Ruby/1.9.3/2013-02-22)",
 "HTTP_USER_AGENT"=>
  "curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5",
 "HTTP_HOST"=>"localhost:8080",
 "HTTP_ACCEPT"=>"*/*",
 "rack.version"=>[1, 2],
 "rack.input"=>#<StringIO:0x007fbba40263b0>,
 "rack.errors"=>#<IO:<STDERR>>,
 "rack.multithread"=>true,
 "rack.multiprocess"=>false,
 "rack.run_once"=>false,
 "rack.url_scheme"=>"http",
 "HTTP_VERSION"=>"HTTP/1.1",
 "REQUEST_PATH"=>"/"}
[2] pry(#<HelloWorld>)>
Hay tres categorías de variables en env:

  1. Variables CGI
  2. Variables específicas de Rack (empiezan por rack.)
  3. Un tercer tipo de variables son las de la aplicación y/o el servidor. En este ejemplo no aparecen
Véase la especificación Rack.

Le indicamos al servidor que continue:

[2] pry(#<HelloWorld>)> co<TABULADOR>
cohen-poem  continue    
[2] pry(#<HelloWorld>)> continue
localhost - - [23/Sep/2013:12:36:48 WEST] "GET / HTTP/1.1" 200 11
- -> /
después de entregar la respuesta el servidor cierra la conexión HTTP. Esto es así porque HTTP es un protocolo sin estado, esto es, no se mantiene información de la conexión entre transacciones. En la ventana del cliente obtenemos la siguiente salida:
[~/local/src/ruby/sinatra/rack/rack-testing/bindaddress(master)]$ curl -v localhost:8080
* About to connect() to localhost port 8080 (#0)
*   Trying ::1... connected
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 200 OK 
< Content-Type: text/plain
< Server: WEBrick/1.3.1 (Ruby/1.9.3/2013-02-22)
< Date: Mon, 23 Sep 2013 11:45:00 GMT
< Content-Length: 11
< Connection: Keep-Alive
< 
* Connection #0 to host localhost left intact
* Closing connection #0
Hello world

REQUEST_METHOD, QUERY_STRING y PATH_INFO

[~/local/src/ruby/sinatra/rack/rack-env]$ cat app.rb 
require 'rack'
require 'thin'

cgi_inspector = lambda do |env|
  [200, #status
    { 'Content-Type' => 'text/html' }, #headers
    ["<h1>
        Your request:<br>
       <ul>
         <li>http method is: #{env['REQUEST_METHOD']}
         <li>path is: #{env['PATH_INFO']}
         <li>Query string is: #{env['QUERY_STRING']}
       </ul>
      </h1>
     "
    ]
  ]
end

Rack::Handler::Thin.run cgi_inspector, :Port => 3000

Visite la página localhost:3000/camino?var=4.

Esta es la salida:

[~/local/src/ruby/sinatra/rack/rack-env]$ curl -v localhost:3000/camino?var=4
* About to connect() to localhost port 3000 (#0)
*   Trying ::1... Connection refused
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /camino?var=4 HTTP/1.1
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5
> Host: localhost:3000
> Accept: */*
> 
< HTTP/1.1 200 OK
< Content-Type: text/html
< Connection: close
< Server: thin 1.5.1 codename Straight Razor
< 
<h1>
        Your request:<br>
       <ul>
         <li>http method is: GET
         <li>path is: /camino
         <li>Query string is: var=4
       </ul>
      </h1>
* Closing connection #0

Casiano Rodríguez León
2015-01-25