port test/unit/test_ccc.rb to Perl 5
[unicorn.git] / t / integration.ru
blobaaed60839d7f707e699ddfdb18e9cac4af1ad409
1 #!ruby
2 # frozen_string_literal: false
3 # Copyright (C) unicorn hackers <unicorn-public@80x24.org>
4 # License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
6 # this goes for t/integration.t  We'll try to put as many tests
7 # in here as possible to avoid startup overhead of Ruby.
9 def early_hints(env, val)
10   env['rack.early_hints'].call('link' => val) # val may be ary or string
11   [ 200, {}, [ val.class.to_s ] ]
12 end
14 $orig_rack_200 = nil
15 def tweak_status_code
16   $orig_rack_200 = Rack::Utils::HTTP_STATUS_CODES[200]
17   Rack::Utils::HTTP_STATUS_CODES[200] = "HI"
18   [ 200, {}, [] ]
19 end
21 def restore_status_code
22   $orig_rack_200 or return [ 500, {}, [] ]
23   Rack::Utils::HTTP_STATUS_CODES[200] = $orig_rack_200
24   [ 200, {}, [] ]
25 end
27 class WriteOnClose
28   def each(&block)
29     @callback = block
30   end
32   def close
33     @callback.call "7\r\nGoodbye\r\n0\r\n\r\n"
34   end
35 end
37 def write_on_close
38   [ 200, { 'transfer-encoding' => 'chunked' }, WriteOnClose.new ]
39 end
41 def env_dump(env)
42   require 'json'
43   h = {}
44   env.each do |k,v|
45     case v
46     when String, Integer, true, false; h[k] = v
47     else
48       case k
49       when 'rack.version', 'rack.after_reply'; h[k] = v
50       when 'rack.input'; h[k] = v.class.to_s
51       end
52     end
53   end
54   h.to_json
55 end
57 def rack_input_tests(env)
58   return [ 100, {}, [] ] if /\A100-continue\z/i =~ env['HTTP_EXPECT']
59   cap = 16384
60   require 'digest/md5'
61   dig = Digest::MD5.new
62   input = env['rack.input']
63   case env['PATH_INFO']
64   when '/rack_input/size_first'; input.size
65   when '/rack_input/rewind_first'; input.rewind
66   when '/rack_input'; # OK
67   else
68     abort "bad path: #{env['PATH_INFO']}"
69   end
70   if buf = input.read(rand(cap))
71     begin
72       raise "#{buf.size} > #{cap}" if buf.size > cap
73       dig.update(buf)
74     end while input.read(rand(cap), buf)
75     buf.clear # remove this call if Ruby ever gets escape analysis
76   end
77   h = { 'content-type' => 'text/plain' }
78   if env['HTTP_TRAILER'] =~ /\bContent-MD5\b/i
79     cmd5_b64 = env['HTTP_CONTENT_MD5'] or return [500, {}, ['No Content-MD5']]
80     cmd5_bin = cmd5_b64.unpack('m')[0]
81     if cmd5_bin != dig.digest
82       h['content-length'] = cmd5_b64.size.to_s
83       return [ 500, h, [ cmd5_b64 ] ]
84     end
85   end
86   h['content-length'] = '32'
87   [ 200, h, [ dig.hexdigest ] ]
88 end
90 $nr_aborts = 0
91 run(lambda do |env|
92   case env['REQUEST_METHOD']
93   when 'GET'
94     case env['PATH_INFO']
95     when '/rack-2-newline-headers'; [ 200, { 'X-R2' => "a\nb\nc" }, [] ]
96     when '/rack-3-array-headers'; [ 200, { 'x-r3' => %w(a b c) }, [] ]
97     when '/nil-header-value'; [ 200, { 'X-Nil' => nil }, [] ]
98     when '/unknown-status-pass-through'; [ '666 I AM THE BEAST', {}, [] ]
99     when '/env_dump'; [ 200, {}, [ env_dump(env) ] ]
100     when '/write_on_close'; write_on_close
101     when '/pid'; [ 200, {}, [ "#$$\n" ] ]
102     when '/early_hints_rack2'; early_hints(env, "r\n2")
103     when '/early_hints_rack3'; early_hints(env, %w(r 3))
104     when '/broken_app'; raise RuntimeError, 'hello'
105     when '/aborted'; $nr_aborts += 1; [ 200, {}, [] ]
106     when '/nr_aborts'; [ 200, { 'nr-aborts' => "#$nr_aborts" }, [] ]
107     when '/nil'; nil
108     when '/read_fifo'; [ 200, {}, [ File.read(env['HTTP_READ_FIFO']) ] ]
109     else '/'; [ 200, {}, [ env_dump(env) ] ]
110     end # case PATH_INFO (GET)
111   when 'POST'
112     case env['PATH_INFO']
113     when '/tweak-status-code'; tweak_status_code
114     when '/restore-status-code'; restore_status_code
115     end # case PATH_INFO (POST)
116     # ...
117   when 'PUT'
118     case env['PATH_INFO']
119     when %r{\A/rack_input}; rack_input_tests(env)
120     when '/env_dump'; [ 200, {}, [ env_dump(env) ] ]
121     end
122   when 'OPTIONS'
123     case env['REQUEST_URI']
124     when '*'; [ 200, {}, [ env_dump(env) ] ]
125     end
126   end # case REQUEST_METHOD
127 end) # run