public
Description: A very fast & simple Ruby web server
Homepage: http://code.macournoyer.com/thin/
Clone URL: git://github.com/macournoyer/thin.git
Search Repo:
add tests from mongrel for the C parser - one test expected to throw an 
error isn't throwing
kevwil (author)
Mon Jan 14 18:00:38 -0800 2008
commit  a4b49dc9ce34af6473bad89dac4be1aa8366dd46
tree    5a6267ae6fdaa227b8508d40a766728ec8a32e73
parent  2f1599b662bbd4356f32c2ebc79b8d976456c0cb
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
0
@@ -1 +1,116 @@
0
+require File.dirname(__FILE__) + '/spec_helper'
0
+
0
+require 'digest/sha1'
0
+
0
+describe HttpParser do
0
+ before do
0
+ @parser = HttpParser.new
0
+ @req = {}
0
+ end
0
+
0
+ it "should parse a simple GET" do
0
+ http = "GET / HTTP/1.1\r\n\r\n"
0
+ nread = @parser.execute(@req, http, 0)
0
+
0
+ http.length.should == nread
0
+ @parser.should be_finished
0
+ @parser.should_not be_error
0
+ @parser.nread.should == nread
0
+
0
+ @req['SERVER_PROTOCOL'].should == 'HTTP/1.1'
0
+ @req['REQUEST_PATH'].should == '/'
0
+ @req['HTTP_VERSION'].should == 'HTTP/1.1'
0
+ @req['REQUEST_URI'].should == '/'
0
+ @req['GATEWAY_INTERFACE'].should == 'CGI/1.2'
0
+ @req['REQUEST_METHOD'].should == 'GET'
0
+ @req['FRAGMENT'].should be_nil
0
+ @req['QUERY_STRING'].should be_empty
0
+
0
+ @parser.reset
0
+ @parser.nread.should == 0
0
+ end
0
+
0
+ it "should handle bad headers properly" do
0
+ expected = "GET / HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n"
0
+ nread = @parser.execute(@req, expected, 0)
0
+ expected.length.should == nread
0
+ @parser.should be_finished
0
+ @parser.should_not be_error
0
+ end
0
+
0
+ it "should handle nasty pound header properly" do
0
+ 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"
0
+
0
+ lambda{@parser.execute(@req, nasty_pound_header, 0)}.should raise_error(InvalidRequest)
0
+ # nasty_pound_header.length.should == nread
0
+ # @parser.should be_finished
0
+ # @parser.should_not be_error
0
+ end
0
+
0
+ it "should raise parse errors properly" do
0
+ bad_http = "GET / SsUTF/1.1"
0
+
0
+ error = false
0
+ begin
0
+ nread = @parser.execute(@req, bad_http, 0)
0
+ rescue => details
0
+ error = true
0
+ end
0
+
0
+ error.should be_true
0
+ @parser.should_not be_finished
0
+ @parser.should be_error
0
+ end
0
+
0
+ it "should handle fragments in url" do
0
+ get = "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n"
0
+ lambda{@parser.execute(@req, get, 0)}.should_not raise_error(InvalidRequest)
0
+ @parser.should be_finished
0
+ @req['REQUEST_URI'].should == '/forums/1/topics/2375?page=1'
0
+ @req['FRAGMENT'].should == 'posts-17408'
0
+ end
0
+
0
+ # lame random garbage maker
0
+ def rand_data(min, max, readable=true)
0
+ count = min + ((rand(max)+1) *10).to_i
0
+ res = count.to_s + "/"
0
+
0
+ if readable
0
+ res << Digest::SHA1.hexdigest(rand(count * 100).to_s) * (count / 40)
0
+ else
0
+ res << Digest::SHA1.digest(rand(count * 100).to_s) * (count / 20)
0
+ end
0
+
0
+ return res
0
+ end
0
+
0
+ it "should raise errors for bad queries" do
0
+ # then that large header names are caught
0
+ 10.times do |c|
0
+ get = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-#{rand_data(1024, 1024+(c*1024))}: Test\r\n\r\n"
0
+ lambda{@parser.execute({}, get, 0)}.should raise_error(InvalidRequest)
0
+ @parser.reset
0
+ end
0
+
0
+ # then that large mangled field values are caught
0
+ 10.times do |c|
0
+ get = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-Test: #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
0
+ lambda{@parser.execute({}, get, 0)}.should raise_error(InvalidRequest)
0
+ @parser.reset
0
+ end
0
+
0
+ # then large headers are rejected too
0
+ get = "GET /#{rand_data(10,120)} HTTP/1.1\r\n"
0
+ get << "X-Test: test\r\n" * (80 * 1024)
0
+ lambda{@parser.execute({}, get, 0)}.should raise_error(InvalidRequest)
0
+ @parser.reset
0
+
0
+ # finally just that random garbage gets blocked all the time
0
+ 10.times do |c|
0
+ get = "GET #{rand_data(1024, 1024+(c*1024), false)} #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
0
+ lambda{@parser.execute({}, get, 0)}.should raise_error(InvalidRequest)
0
+ @parser.reset
0
+ end
0
+ end
0
+end

Comments

    No one has commented yet.