3 require File.dirname(__FILE__) + '/../config/boot'
4 require RAILS_ROOT + "/config/environment"
10 $logger = Logger.new(RAILS_ROOT + "/log/fuzed.#{Process.pid}.log")
28 log "Waiting for connections"
32 receive(IO.new(3), IO.new(4)) do
33 match(:request, list(:request)) do
35 log('------------MATCH------------')
37 res = me.service(request)
39 log(">> Total in " + (Time.now - $t).to_s + " sec\n")
49 log('------------NO-MATCH------------')
57 request = vars.inject({}) { |a, x| a[x[0]] = x[1]; a }
59 method = request[:method]
60 version = request[:http_version] # => e.g. [1, 1]
61 path = request[:querypath]
62 query = request[:querydata]
63 server = request[:servername]
64 headers = request[:headers]
65 cookies = request[:cookies]
66 postdata = request[:postdata] == :undefined ? '' : request[:postdata]
68 translate = {:content_type => 'CONTENT_TYPE',
69 :content_length => 'CONTENT_LENGTH',
70 :accept => 'HTTP_ACCEPT',
71 :'Accept-Charset' => 'HTTP_ACCEPT_CHARSET',
72 :'Accept-Encoding' => 'HTTP_ACCEPT_ENCODING',
73 :'Accept-Language' => 'HTTP_ACCEPT_LANGUAGE',
74 :connection => 'HTTP_CONNECTION',
75 :keep_alive => 'HTTP_KEEP_ALIVE',
77 :referer => 'HTTP_REFERER',
78 :user_agent => 'HTTP_USER_AGENT',
79 'X-Prototype-Version' => 'HTTP_X_PROTOTYPE_VERSION',
80 'X-Requested-With' => 'HTTP_X_REQUESTED_WITH'}
83 env['REQUEST_METHOD'] = method.to_s
84 env['QUERY_STRING'] = query
85 env["PATH_INFO"] = path == '/' ? '' : path
86 env = headers.inject(env) { |a, x| a[translate[x[0]] || x[0].to_s] = x[1]; a }
87 env.delete_if { |k, v| v.nil? }
89 env.update({"rack.version" => [0,2],
90 "rack.input" => StringIO.new(postdata),
91 "rack.errors" => STDERR,
93 "rack.multithread" => true,
94 "rack.multiprocess" => false,
95 "rack.run_once" => false,
97 "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
100 env['SERVER_NAME'] = server.split(':')[0]
101 env['SERVER_PORT'] = server.split(':')[1]
102 env['HTTP_VERSION'] = version.join('.')
104 env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
105 env["QUERY_STRING"] ||= ""
106 env["REQUEST_PATH"] ||= "/"
107 env.delete "PATH_INFO" if env["PATH_INFO"] == ""
109 cookies.each do |cookie|
110 env["HTTP_COOKIE"] = cookie.to_s
113 log('------------IN------------')
118 status, headers, body = @app.call(env)
119 log(">> Rails in " + (Time.now - t1).to_s + " sec")
126 headers['Server'] = 'YAWS + Fuzed 0.0.1'
127 headers['Connection'] = 'close'
129 cookies = headers.delete('cookie')
130 #cookies.map! {|c| c.include?('path=') ? c : c + "; path=/"}
131 headers['Set-Cookie'] = cookies if cookies
137 [[:status, status.to_i],
138 [:allheaders, headers.inject([]) { |a, x| a += x[1].map { |y| [:header, x[0], y] } }],
145 [:header, "Content-Type", "text/plain; charset=utf-8"],
146 [:header, "Cache-Control", "no-cache"]]],
147 [:html, "500 Internal Error\n\n#{e}\n\n#{e.backtrace}"]]]
150 log('-----------OUT------------')
159 ###############################################################################
161 unless defined? RAILS_ROOT
162 raise "Rails' environment has to be loaded before using Rack::Adapter::Rails"
165 require "rack/request"
166 require "rack/response"
173 request = Request.new(env)
174 response = Response.new
176 cgi = CGIStub.new(request, response)
178 Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, response)
185 class CGIStub < ::CGI
187 def initialize(request, response, *args)
191 @input = request.body
195 IGNORED_HEADERS = [ "Status" ]
197 def header(options = "text/html")
198 # puts 'header---------------'
200 # puts '---------------------'
202 if options.instance_of?(String)
203 @response['Content-Type'] = options unless @response['Content-Type']
205 @response['Content-Length'] = options.delete('Content-Length').to_s if options['Content-Length']
207 @response['Content-Type'] = options.delete('type') || "text/html"
208 @response['Content-Type'] += "; charset=" + options.delete('charset') if options['charset']
210 @response['Status'] = options.delete('status') if options['status']
211 @response['Content-Language'] = options.delete('language') if options['language']
212 @response['Expires'] = options.delete('expires') if options['expires']
214 IGNORED_HEADERS.each {|k| options.delete(k) }
216 options.each{|k,v| @response[k] = v}
218 # convert 'cookie' header to 'Set-Cookie' headers
219 if cookie = @response['cookie']
222 cookie.each {|c| @response['Set-Cookie'] = c.to_s }
224 cookie.each_value {|c| @response['Set-Cookie'] = c.to_s}
226 @response['Set-Cookie'] = options['cookie'].to_s
229 @output_cookies.each { |c| @response['Set-Cookie'] = c.to_s } if @output_cookies
245 @request.query_string
248 # Used to wrap the normal args variable used inside CGI.
253 # Used to wrap the normal env_table variable used inside CGI.
258 # Used to wrap the normal stdinput variable used inside CGI.
264 STDERR.puts "stdoutput should not be used."
272 ###############################################################################
275 require 'rack/cascade'
276 require 'rack/showexceptions'
277 # Rack::Handler::Fuzed.run \
278 # Rack::ShowExceptions.new(Rack::Lint.new(Rack::Adapter::Rails.new))
280 if ARGV.first != 'test'
281 Rack::Handler::Fuzed.run(Rack::Adapter::Rails.new)
284 [[:method, :POST], [:http_version, [1, 1]], [:querypath, "/main/go"], [:querydata, ""], [:servername, "testing:8002"], [:headers, [[:connection, "keep-alive"], [:accept, "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"], [:host, "localhost:8002"], [:referer, "http://localhost:8002/main/ready"], [:user_agent, "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"], [:keep_alive, "300"], [:content_length, "7"], [:content_type, "application/x-www-form-urlencoded"], [:"Cache-Control", "max-age=0"], [:"Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7"], [:"Accept-Encoding", "gzip,deflate"], [:"Accept-Language", "en-us,en;q=0.5"]]], [:cookies, ["_helloworld_session_id=d3eae987aab3230377abc433b7a8d7c1"]], [:pathinfo, "/Users/tom/dev/fuzed/helloworld/public"], [:postdata, "val=foo"]]
286 # [[:method, :GET], [:http_version, [1, 1]], [:querypath, "/main/say"], [:querydata, ""], [:servername, "testing:8002"], [:headers, [[:connection, "keep-alive"], [:accept, "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"], [:host, "localhost:8002"], [:user_agent, "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3"], [:keep_alive, "300"], [:"Cache-Control", "max-age=0"], [:"Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7"], [:"Accept-Encoding", "gzip,deflate"], [:"Accept-Language", "en-us,en;q=0.5"]]], [:cookies, ["_helloworld_session_id=166098a3c3f702698d0529c6148c6164"]], [:pathinfo, "/Users/tom/dev/fuzed/helloworld/public"], [:postdata, :undefined]]
288 p Rack::Handler::Fuzed.new(Rack::Adapter::Rails.new).service(req)