27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

538 CHAPTER 18 Rack-based applications<br />

def directory_exist?(path)<br />

full_path = File.join(@file_server.root, ::Rack::Utils.unescape(path))<br />

File.directory?(full_path) && File.readable?(full_path)<br />

end<br />

It performs basically the same function as the file_exist? method, except that it uses<br />

File.directory? to check for the directory rather than File.file?. If this directory<br />

does exist, then the cached_path variable is set to /projects/index in your case. The<br />

second line in this else references the ::ActionController::Base.page_cache<br />

_extension, which is a string that defaults to .html and makes your cached_path variable<br />

now projects/index.html, the alternate path where the page for /projects may be<br />

cached.<br />

If this file exists, then the middleware sets env["PATH_INFO"] to be this path so<br />

that the Rack::File instance knows what’s being requested, and then it makes a call<br />

to the @fileserver.call method and returns the response it gives back.<br />

If everything fails and there’s no file at the path you’ve requested, the middleware<br />

gives up and passes the request to the next piece of middleware by using this line:<br />

@app.call(env)<br />

The request then continues on down the chain of middleware until it hits a middleware<br />

that serves that request or the Ticketee::Application.routes endpoint. Either<br />

way, the browser (or whatever makes the request) is basically guaranteed to get a<br />

response from a piece of middleware or the application itself. For the first situation, a<br />

middleware can return a response itself:<br />

return [200, { "Content-Type" => "text/html" }, ["Oh happy day!"]]<br />

Or it can pass the buck to the next piece with the call method, passing through the<br />

(possibly modified) env variable representing this request’s environment:<br />

@app.call(env)<br />

Now that you’ve got a nice grasp of how one piece of middleware works, let’s build<br />

your own!<br />

18.4.3 Crafting middleware<br />

Soon you’ll have your own piece of middleware that you can put into the middleware<br />

stack of a Rails or Rack application. This middleware will allow the request to run all<br />

the way down the chain to the application and then will modify the body, replacing<br />

specific letters in the text for links with other, equally specific letters. Create a new file<br />

for your middleware at lib/link_jumbler.rb and fill it with the content shown in the following<br />

listing.<br />

Listing 18.11 lib/link_jumbler.rb<br />

require 'nokogiri'<br />

class LinkJumbler<br />

def initialize(app, letters)

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!