Class: Heel::RackApp

Inherits:
Object
  • Object
show all
Defined in:
lib/heel/rackapp.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ RackApp

Returns a new instance of RackApp.



23
24
25
26
27
28
29
30
31
32
# File 'lib/heel/rackapp.rb', line 23

def initialize(options = {}) 
  @ignore_globs               = options[:ignore_globs] ||= %w( *~ .htaccess . )
  @document_root              = options[:document_root] ||= Dir.pwd
  @directory_listing_allowed  = options[:directory_listing_allowed] ||= true
  @directory_index_html       = options[:directory_index_html] ||= "index.html"
  @using_icons                = options[:using_icons] ||= true
  @icon_url                   = options[:icon_url] ||= "/heel_icons"
  @highlighting               = options[:highlighting] ||= false
  @options                    = options
end

Instance Attribute Details

#directory_index_htmlObject (readonly)

Returns the value of attribute directory_index_html.



17
18
19
# File 'lib/heel/rackapp.rb', line 17

def directory_index_html
  @directory_index_html
end

#document_rootObject (readonly)

Returns the value of attribute document_root.



16
17
18
# File 'lib/heel/rackapp.rb', line 16

def document_root
  @document_root
end

#highlightingObject (readonly)

Returns the value of attribute highlighting.



19
20
21
# File 'lib/heel/rackapp.rb', line 19

def highlighting
  @highlighting
end

#icon_urlObject (readonly)

Returns the value of attribute icon_url.



18
19
20
# File 'lib/heel/rackapp.rb', line 18

def icon_url
  @icon_url
end

#ignore_globsObject (readonly)

Returns the value of attribute ignore_globs.



20
21
22
# File 'lib/heel/rackapp.rb', line 20

def ignore_globs
  @ignore_globs
end

Instance Method Details

#call(env) ⇒ Object

interface to rack, env is a hash

returns [ status, headers, body ]



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/heel/rackapp.rb', line 142

def call(env)
  req = Heel::Request.new(env, document_root)
  if req.get? then
    if req.forbidden? or should_ignore?(req.request_path) then
      return ErrorResponse.new(req.path_info,"You do not have permissionto view #{req.path_info}",403).finish 
    end
    return ErrorResponse.new(req.path_info, "File not found: #{req.path_info}",403).finish unless req.found?
    return directory_index_response(req)                           if req.for_directory?
    return file_response(req)                                      if req.for_file?
  else
    return ErrorResponse.new(req.path_info,
                             "Method #{req.request_method} Not Allowed. Only GET is honored.", 
                             405, 
                             { "Allow" => "GET" }).finish
  end
end

#directory_index_response(req) ⇒ Object

formulate a directory index response



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/heel/rackapp.rb', line 65

def directory_index_response(req)
  response = ::Rack::Response.new
  dir_index = File.join(req.request_path, directory_index_html) 
  if File.file?(dir_index) and File.readable?(dir_index) then
    response['Content-Type']   = mime_map.mime_type_of(dir_index).to_s
    response['Content-Length'] = File.size(dir_index).to_s
    response.body              = File.open(dir_index)
  elsif directory_listing_allowed? then
    body                       = directory_indexer.index_page_for(req)
    response['Content-Type']   = 'text/html'
    response['Content-Length'] = body.length.to_s
    response.body             << body
  else
    return ::Heel::ErrorResponse.new(req.path_info,"Directory index is forbidden", 403).finish
  end
  return response.finish
end

#directory_index_template_fileObject



46
47
48
# File 'lib/heel/rackapp.rb', line 46

def directory_index_template_file
  @directory_index_template_file ||= Heel::Configuration.data_path("listing.rhtml")
end

#directory_indexerObject



50
51
52
53
# File 'lib/heel/rackapp.rb', line 50

def directory_indexer
  indexer_ignore = ( ignore_globs + [ document_root] ).flatten
  @directory_indexer ||= DirectoryIndexer.new( directory_index_template_file, @options )
end

#directory_listing_allowed?Boolean

Returns:

  • (Boolean)


34
35
36
# File 'lib/heel/rackapp.rb', line 34

def directory_listing_allowed?
  @directory_listing_allowed
end

#file_response(req) ⇒ Object

formulate a file content response. Possibly a coderay highlighted file if it is a type that code ray can deal with and the file is not already an html file.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/heel/rackapp.rb', line 88

def file_response(req)
  response = ::Rack::Response.new

  response['Last-Modified'] = req.stat.mtime.rfc822

  if highlighting? and req.highlighting? then 
    # only do a coderay type check if we are going to use coderay in the
    # response
    code_ray_type = CodeRay::FileType[req.request_path, true] 
    if code_ray_type and (code_ray_type != :html) then
      body = <<-EOM
      <html>
        <head>
        <title>#{req.path_info}</title>
        <!-- CodeRay syntax highlighting CSS -->
        <link rel="stylesheet" href="/heel_css/coderay-cycnus.css" type="text/css" />
        </head>
        <body>
          <div class="CodeRay">
            <pre>
  #{CodeRay.scan_file(req.request_path,:auto).html({:line_numbers => :inline})}
            </pre>
          </div>
        </body>
      </html>
      EOM
      response['Content-Type']    = 'text/html'
      response['Content-Length']  = body.length.to_s
      response.body << body
      return response.finish
    end
  end

  # fall through to a default file return
  # 

  file_type                   = mime_map.mime_type_of(req.request_path)
  response['Content-Type']    = file_type.to_s
  response['Content-Length']  = req.stat.size.to_s

  return response.finish do 
    File.open(req.request_path) do |f|
      while p = f.read(8192)
        response.write p
      end
    end
  end

end

#highlighting?Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/heel/rackapp.rb', line 38

def highlighting?
  @highlighting
end

#mime_mapObject



42
43
44
# File 'lib/heel/rackapp.rb', line 42

def mime_map
  @mime_map ||= Heel::MimeMap.new
end

#should_ignore?(fname) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
60
61
# File 'lib/heel/rackapp.rb', line 56

def should_ignore?(fname)
  ignore_globs.each do |glob|
    return true if ::File.fnmatch(glob,fname)
  end
  false 
end