Class: Yarn::RequestHandler
- Inherits:
-
Object
- Object
- Yarn::RequestHandler
show all
- Includes:
- ErrorPage, Logging
- Defined in:
- lib/yarn/request_handler.rb
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from ErrorPage
#serve_404_page, #serve_500_page
Methods included from Logging
#debug, #log, #output, #timestamp
Constructor Details
Returns a new instance of RequestHandler.
17
18
19
20
|
# File 'lib/yarn/request_handler.rb', line 17
def initialize(options={})
@parser = ParsletParser.new
@response = Response.new
end
|
Instance Attribute Details
#parser ⇒ Object
Returns the value of attribute parser.
15
16
17
|
# File 'lib/yarn/request_handler.rb', line 15
def parser
@parser
end
|
#request ⇒ Object
Returns the value of attribute request.
15
16
17
|
# File 'lib/yarn/request_handler.rb', line 15
def request
@request
end
|
#response ⇒ Object
Returns the value of attribute response.
15
16
17
|
# File 'lib/yarn/request_handler.rb', line 15
def response
@response
end
|
#session ⇒ Object
Returns the value of attribute session.
15
16
17
|
# File 'lib/yarn/request_handler.rb', line 15
def session
@session
end
|
Instance Method Details
#client_address ⇒ Object
198
199
200
|
# File 'lib/yarn/request_handler.rb', line 198
def client_address
@session.peeraddr(:numeric)[2] if @session
end
|
#close_connection ⇒ Object
93
94
95
96
97
98
99
|
# File 'lib/yarn/request_handler.rb', line 93
def close_connection
if @session @session.close
else
end
end
|
#execute_script(path) ⇒ Object
74
75
76
77
78
79
80
81
|
# File 'lib/yarn/request_handler.rb', line 74
def execute_script(path)
response = `ruby #{path}`
if !! ($?.to_s =~ /1$/)
raise ProcessingError
else
response
end
end
|
154
155
156
157
158
159
160
|
# File 'lib/yarn/request_handler.rb', line 154
def
path = @request[:uri][:path].to_s
if path[0] == "/" && path != "/"
path = path[1..-1]
end
path.gsub(/%20/, " ").strip
end
|
#get_mime_type(path) ⇒ Object
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
# File 'lib/yarn/request_handler.rb', line 173
def get_mime_type(path)
return false unless path.include? '.'
filetype = path.split('.').last
return case
when ["html", "htm"].include?(filetype)
"text/html"
when "txt" == filetype
"text/plain"
when "css" == filetype
"text/css"
when "js" == filetype
"text/javascript"
when ["png", "jpg", "jpeg", "gif", "tiff"].include?(filetype)
"image/#{filetype}"
when ["zip","pdf","postscript","x-tar","x-dvi"].include?(filetype)
"application/#{filetype}"
else false
end
end
|
#parse_request ⇒ Object
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/yarn/request_handler.rb', line 38
def parse_request
raw_request = read_request
raise EmptyRequestError if raw_request.empty?
begin
@request = @parser.run raw_request
rescue Parslet::ParseFailed => e
@response.status = 400
debug "Parse failed: #{@request}"
end
end
|
#persistent? ⇒ Boolean
110
111
112
|
# File 'lib/yarn/request_handler.rb', line 110
def persistent?
return @request[:headers]["Connection"] == "keep-alive"
end
|
#prepare_response ⇒ Object
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/yarn/request_handler.rb', line 50
def prepare_response
path =
@response.["Content-Type"] = "text/html"
begin
if File.directory? path
serve_directory path
elsif File.exists?(path)
if path =~ /.*\.rb$/
@response.body << execute_script(path)
@response.status = 200
else
serve_file(path)
end
else
serve_404_page
end
rescue ProcessingError
log "An error occured processing #{path}"
serve_500_page
end
end
|
#read_file(path) ⇒ Object
142
143
144
145
146
147
148
149
150
151
152
|
# File 'lib/yarn/request_handler.rb', line 142
def read_file(path)
file_contents = []
File.open(path, "r") do |file|
while (line = file.gets) do
file_contents << line
end
end
file_contents
end
|
#read_request ⇒ Object
101
102
103
104
105
106
107
108
|
# File 'lib/yarn/request_handler.rb', line 101
def read_request
input = []
while (line = @session.gets) do
break if line.length <= 2
input << line
end
input.join
end
|
#request_path ⇒ Object
194
195
196
|
# File 'lib/yarn/request_handler.rb', line 194
def request_path
@request[:uri][:path] if @request
end
|
#return_response ⇒ Object
83
84
85
86
87
88
89
90
91
|
# File 'lib/yarn/request_handler.rb', line 83
def return_response
@session.puts "HTTP/1.1 #{@response.status} #{STATUS_CODES[@response.status]}"
@session.puts @response..map { |k,v| "#{k}: #{v}" }
@session.puts ""
@response.body.each do |line|
@session.puts line
end
end
|
#run(session) ⇒ Object
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
# File 'lib/yarn/request_handler.rb', line 22
def run(session)
@response = Response.new
@session = session
begin
parse_request
prepare_response
return_response
log "Served (#{STATUS_CODES[@response.status]}) #{client_address} #{request_path}"
rescue EmptyRequestError
log "Empty request from #{client_address}"
ensure
close_connection
end
end
|
#serve_directory(path) ⇒ Object
130
131
132
133
134
135
136
137
138
139
140
|
# File 'lib/yarn/request_handler.rb', line 130
def serve_directory(path)
@response.status = 200
if File.exists?("index.html") || File.exists?("/index.html")
@response.body = read_file "index.html"
@response.["Content-Type"] = "text/html"
else
@response.["Content-Type"] = "text/html"
directory_lister = DirectoryLister.new
@response.body << directory_lister.list(path)
end
end
|
#serve_file(path) ⇒ Object
124
125
126
127
128
|
# File 'lib/yarn/request_handler.rb', line 124
def serve_file(path)
@response.status = 200
@response.body << read_file(path)
@response.["Content-Type"] = get_mime_type path
end
|
114
115
116
117
118
119
120
121
122
|
# File 'lib/yarn/request_handler.rb', line 114
def
@response.[:Server] = "Yarn webserver v#{VERSION}"
time = DateTime.now.new_offset(0)
@response.[:Date] = time.strftime("%a, %d %b %Y %H:%M:%S GMT")
@response.[:Connection] = "Close"
end
|