Fix up tests and runner
[ebb.git] / test / env_test.rb
blob523af6a9f68ac766757ef29d12b01f27558d4e45
1 require File.dirname(__FILE__) + '/helper'
2 require 'socket'
3 require 'rubygems'
4 require 'json'
5 require 'test/unit'
7 def send_request(request_string)
8   socket = TCPSocket.new("0.0.0.0", TEST_PORT)
9   socket.write(request_string)
10   lines = []
11   out = socket.read(5000000)
12   raise "Connection Closed on #{request_string.inspect}" if out.nil?
13   out.each_line { |l| lines << l }
14   env = JSON.parse(lines.last)
15 rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE
16   return :fail
17 rescue RuntimeError => e
18   if e.message =~ /Connection Closed/
19     return :fail
20   else
21     raise e
22   end
23 rescue => e
24   puts "unknown exception: #{e.class}"
25   raise e
26 ensure
27   socket.close unless socket.nil?
28 end
30 def drops_request?(request_string)
31   :fail == send_request(request_string)
32 end
34 class HttpParserTest < ServerTest
35   
36   def test_parse_simple
37     env = send_request("GET / HTTP/1.1\r\n\r\n")
38     
39     assert_equal 'HTTP/1.1', env['SERVER_PROTOCOL']
40     assert_equal '/', env['REQUEST_PATH']
41     assert_equal 'HTTP/1.1', env['HTTP_VERSION']
42     assert_equal '/', env['REQUEST_URI']
43     assert_equal 'GET', env['REQUEST_METHOD']    
44     assert_nil env['FRAGMENT']
45     assert_nil env['QUERY_STRING']
46     assert_equal "", env['rack.input']
47   end
48   
49   def test_parse_dumbfuck_headers
50     should_be_good = "GET / HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n"
51     env = send_request(should_be_good)
52     assert_equal "++++++++++", env["HTTP_AAAAAAAAAAAAA"]
53     assert_equal "", env['rack.input']
54     
55     nasty_pound_header = "GET / HTTP/1.1\r\nX-SSL-Bullshit:   -----BEGIN CERTIFICATE-----\r\n\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgEBBAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n\tRA==\r\n\t-----END CERTIFICATE-----\r\n\r\n"
56     assert drops_request?(nasty_pound_header) # Correct?
57   end
58   
59   def test_parse_error
60     assert drops_request?("GET / SsUTF/1.1")
61   end
63   def test_fragment_in_uri
64     env = send_request("GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n")
65     assert_equal '/forums/1/topics/2375?page=1', env['REQUEST_URI']
66     assert_equal 'posts-17408', env['FRAGMENT']
67     assert_equal "", env['rack.input']
68   end
69   
70   # lame random garbage maker
71   def rand_data(min, max, readable=true)
72     count = min + ((rand(max)+1) *10).to_i
73     res = count.to_s + "/"
74     
75     if readable
76       res << Digest::SHA1.hexdigest(rand(count * 100).to_s) * (count / 40)
77     else
78       res << Digest::SHA1.digest(rand(count * 100).to_s) * (count / 20)
79     end
80     
81     return res
82   end
83   
84   def test_horrible_queries
85     10.times do |c|
86       req = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-#{rand_data(1024, 1024+(c*1024))}: Test\r\n\r\n"
87       assert drops_request?(req), "large header names are caught"
88     end
89     
90     # then that large mangled field values are caught
91     10.times do |c|
92       req = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-Test: #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
93       #assert drops_request?(req), "large mangled field values are caught"
94       ### XXX this is broken! fix me. this test should drop the request.
95     end
96     
97     # then large headers are rejected too
98     req = "GET /#{rand_data(10,120)} HTTP/1.1\r\n"
99     req << "X-Test: test\r\n" * (80 * 1024)
100     assert drops_request?(req), "large headers are rejected"
101     
102     # finally just that random garbage gets blocked all the time
103     10.times do |c|
104       req = "GET #{rand_data(1024, 1024+(c*1024), false)} #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
105       assert drops_request?(req), "random garbage gets blocked all the time"
106     end
107   end