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.



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

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.



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

def directory_index_html
  @directory_index_html
end

#document_rootObject (readonly)

Returns the value of attribute document_root.



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

def document_root
  @document_root
end

#highlightingObject (readonly)

Returns the value of attribute highlighting.



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

def highlighting
  @highlighting
end

#icon_urlObject (readonly)

Returns the value of attribute icon_url.



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

def icon_url
  @icon_url
end

#ignore_globsObject (readonly)

Returns the value of attribute ignore_globs.



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

def ignore_globs
  @ignore_globs
end

Instance Method Details

#call(env) ⇒ Object

interface to rack, env is a hash

returns [ status, headers, body ]



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/heel/rackapp.rb', line 129

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}",404).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



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

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.write( File.read( dir_index ) )
  elsif directory_listing_allowed? then
    body                       = directory_indexer.index_page_for(req)
    response['Content-Type']   = 'text/html'
    response.write( body )
  else
    return ::Heel::ErrorResponse.new(req.path_info,"Directory index is forbidden", 403).finish
  end
  return response.finish
end

#directory_index_template_fileObject



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

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

#directory_indexerObject



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

def directory_indexer
  @directory_indexer ||= DirectoryIndexer.new( directory_index_template_file, @options )
end

#directory_listing_allowed?Boolean

Returns:

  • (Boolean)


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

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.



84
85
86
87
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
# File 'lib/heel/rackapp.rb', line 84

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-alpha.css" type="text/css" />
        </head>
        <body>
  #{CodeRay.scan_file(req.request_path,:auto).html({ :wrap => :div, :line_numbers => :inline })}
        </body>
      </html>
      EOM
      response['Content-Type']    = 'text/html'
      response['Content-Length']  = body.length.to_s
      response.write( 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
  File.open( req.request_path ) do |f|
    while p = f.read( 8192 ) do
      response.write( p )
    end
  end
  return response.finish
end

#highlighting?Boolean

Returns:

  • (Boolean)


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

def highlighting?
  @highlighting
end

#mime_mapObject



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

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

#should_ignore?(fname) ⇒ Boolean

Returns:

  • (Boolean)


54
55
56
57
58
59
# File 'lib/heel/rackapp.rb', line 54

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