ebb 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,53 +0,0 @@
1
- /**
2
- * Copyright (c) 2005 Zed A. Shaw
3
- * You can redistribute it and/or modify it under the same terms as Ruby.
4
- */
5
-
6
- #ifndef http11_parser_h
7
- #define http11_parser_h
8
-
9
- #include <sys/types.h>
10
-
11
- #if defined(_WIN32)
12
- #include <stddef.h>
13
- #endif
14
-
15
- enum { MONGREL_CONTENT_LENGTH
16
- , MONGREL_CONTENT_TYPE
17
- , MONGREL_FRAGMENT
18
- , MONGREL_HTTP_VERSION
19
- , MONGREL_QUERY_STRING
20
- , MONGREL_REQUEST_PATH
21
- , MONGREL_REQUEST_METHOD
22
- , MONGREL_REQUEST_URI
23
- };
24
-
25
- typedef void (*field_cb)(void *data, const char *field, size_t flen, const char *value, size_t vlen);
26
- typedef void (*element_cb)(void *data, int type, const char *at, size_t length);
27
-
28
- typedef struct http_parser {
29
- int cs;
30
- int overflow_error;
31
- size_t body_start;
32
- size_t content_length;
33
- size_t nread;
34
- size_t mark;
35
- size_t field_start;
36
- size_t field_len;
37
- size_t query_start;
38
-
39
- void *data;
40
-
41
- field_cb http_field;
42
- element_cb on_element;
43
- } http_parser;
44
-
45
- void http_parser_init(http_parser *parser);
46
- int http_parser_finish(http_parser *parser);
47
- size_t http_parser_execute(http_parser *parser, const char *data, size_t len, size_t off);
48
- int http_parser_has_error(http_parser *parser);
49
- int http_parser_is_finished(http_parser *parser);
50
-
51
- #define http_parser_nread(parser) (parser)->nread
52
-
53
- #endif
@@ -1,46 +0,0 @@
1
- require File.dirname(__FILE__) + '/helper'
2
-
3
- module BasicTests
4
- def test_get_bytes
5
- [1,10,1000].each do |i|
6
- response = get("/bytes/#{i}")
7
- assert_equal "#{'C'*i.to_i}", response['output']
8
- end
9
- end
10
-
11
- def test_get_unknown
12
- response = get('/blah')
13
- assert_equal "Undefined url", response['output']
14
- end
15
-
16
- def test_small_posts
17
- [1,10,321,123,1000].each do |i|
18
- response = post("/test_post_length", 'C'*i)
19
- assert_equal 200, response['status']
20
- end
21
- end
22
-
23
- def test_large_post
24
- [50,60,100].each do |i|
25
- response = post("/test_post_length", 'C'*1024*i)
26
- assert_equal 200, response['status']
27
- end
28
- end
29
- end
30
-
31
- class BasicTest < ServerTest
32
- include BasicTests
33
- end
34
-
35
- class BasicTestFD < ServerTestFD
36
- include BasicTests
37
- end
38
-
39
- class BasicTestUnixSocket < ServerTestSocket
40
- include BasicTests
41
-
42
- def test_socket_file_exists
43
- assert File.exists?(@socketfile)
44
- assert File.readable?(@socketfile)
45
- end
46
- end
@@ -1,34 +0,0 @@
1
- require File.dirname(__FILE__) + '/helper'
2
-
3
- APP_DIR = File.dirname(__FILE__) + "/rails_app"
4
- EBB_RAILS = "#{Ebb::LIBDIR}/../bin/ebb_rails"
5
- class EbbRailsTest < Test::Unit::TestCase
6
- # just to make sure there isn't some load error
7
- def test_version
8
- out = %x{ruby #{EBB_RAILS} -v}
9
- assert_match %r{Ebb #{Ebb::VERSION}}, out
10
- end
11
-
12
- def test_parser
13
- runner = Ebb::Runner::Rails.new
14
- runner.parse_options("start -c #{APP_DIR} -p #{TEST_PORT}".split)
15
- assert_equal TEST_PORT, runner.options[:port].to_i
16
- assert_equal APP_DIR, runner.options[:root]
17
- end
18
-
19
-
20
- def test_start_app
21
- Thread.new do
22
- runner = Ebb::Runner::Rails.new
23
- runner.run("start -c #{APP_DIR} -p #{TEST_PORT}".split)
24
- end
25
- sleep 0.1 until Ebb.running?
26
-
27
- response = get '/'
28
- assert_equal 200, response.code.to_i
29
-
30
- ensure
31
- Ebb.stop_server
32
- sleep 0.1 while Ebb.running?
33
- end
34
- end
@@ -1,110 +0,0 @@
1
- require File.dirname(__FILE__) + '/helper'
2
- require 'socket'
3
- require 'rubygems'
4
- require 'json'
5
- require 'test/unit'
6
- require 'digest/sha1'
7
-
8
- def send_request(request_string)
9
- socket = TCPSocket.new("0.0.0.0", TEST_PORT)
10
- socket.write(request_string)
11
- lines = []
12
- out = socket.read(5000000)
13
- raise "Connection Closed on #{request_string.inspect}" if out.nil?
14
- out.each_line { |l| lines << l }
15
- env = JSON.parse(lines.last)
16
- rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE
17
- return :fail
18
- rescue RuntimeError => e
19
- if e.message =~ /Connection Closed/
20
- return :fail
21
- else
22
- raise e
23
- end
24
- rescue => e
25
- puts "unknown exception: #{e.class}"
26
- raise e
27
- ensure
28
- socket.close unless socket.nil?
29
- end
30
-
31
- def drops_request?(request_string)
32
- :fail == send_request(request_string)
33
- end
34
-
35
- class HttpParserTest < ServerTest
36
-
37
- def test_parse_simple
38
- env = send_request("GET / HTTP/1.0\r\n\r\n")
39
-
40
- assert_equal 'HTTP/1.1', env['SERVER_PROTOCOL']
41
- assert_equal '/', env['REQUEST_PATH']
42
- assert_equal 'HTTP/1.0', env['HTTP_VERSION']
43
- assert_equal '/', env['REQUEST_URI']
44
- assert_equal 'GET', env['REQUEST_METHOD']
45
- assert_nil env['FRAGMENT']
46
- assert_nil env['QUERY_STRING']
47
- assert_equal "", env['rack.input']
48
- assert_equal '127.0.0.1', env['HTTP_CLIENT_IP']
49
- end
50
-
51
- def test_parse_dumbfuck_headers
52
- should_be_good = "GET / HTTP/1.0\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n"
53
- env = send_request(should_be_good)
54
- assert_equal "++++++++++", env["HTTP_AAAAAAAAAAAAA"]
55
- assert_equal "", env['rack.input']
56
-
57
- 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"
58
- assert drops_request?(nasty_pound_header) # Correct?
59
- end
60
-
61
- def test_parse_error
62
- assert drops_request?("GET / SsUTF/1.1")
63
- end
64
-
65
- def test_fragment_in_uri
66
- env = send_request("GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.0\r\n\r\n")
67
- assert_equal '/forums/1/topics/2375?page=1', env['REQUEST_URI']
68
- assert_equal 'posts-17408', env['FRAGMENT']
69
- assert_equal "", env['rack.input']
70
- end
71
-
72
- # lame random garbage maker
73
- def rand_data(min, max, readable=true)
74
- count = min + ((rand(max)+1) *10).to_i
75
- res = count.to_s + "/"
76
-
77
- if readable
78
- res << Digest::SHA1.hexdigest(rand(count * 100).to_s) * (count / 40)
79
- else
80
- res << Digest::SHA1.digest(rand(count * 100).to_s) * (count / 20)
81
- end
82
-
83
- return res
84
- end
85
-
86
- def test_horrible_queries
87
- 10.times do |c|
88
- req = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-#{rand_data(1024, 1024+(c*1024))}: Test\r\n\r\n"
89
- assert drops_request?(req), "large header names are caught"
90
- end
91
-
92
- # then that large mangled field values are caught
93
- 10.times do |c|
94
- req = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-Test: #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
95
- assert drops_request?(req), "large mangled field values are caught"
96
- ### XXX this is broken! fix me. this test should drop the request.
97
- end
98
-
99
- # then large headers are rejected too
100
- req = "GET /#{rand_data(10,120)} HTTP/1.1\r\n"
101
- req << "X-Test: test\r\n" * (80 * 1024)
102
- assert drops_request?(req), "large headers are rejected"
103
-
104
- # finally just that random garbage gets blocked all the time
105
- 10.times do |c|
106
- req = "GET #{rand_data(1024, 1024+(c*1024), false)} #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
107
- assert drops_request?(req), "random garbage gets blocked all the time"
108
- end
109
- end
110
- end
@@ -1,138 +0,0 @@
1
- require 'rubygems'
2
- require File.dirname(__FILE__) + '/../ruby_lib/ebb'
3
- require 'test/unit'
4
- require 'net/http'
5
- require 'socket'
6
- require 'rubygems'
7
- require 'json'
8
-
9
-
10
- Ebb.log = File.open('/dev/null','w')
11
-
12
- TEST_PORT = 4044
13
-
14
-
15
- class HelperApp
16
- def call(env)
17
- commands = env['PATH_INFO'].split('/')
18
-
19
- if commands.include?('bytes')
20
- n = commands.last.to_i
21
- raise "bytes called with n <= 0" if n <= 0
22
- body = "C"*n
23
- status = 200
24
-
25
- elsif commands.include?('test_post_length')
26
- input_body = env['rack.input'].read
27
-
28
- content_length_header = env['CONTENT_LENGTH'].to_i
29
-
30
- if content_length_header == input_body.length
31
- body = "Content-Length matches input length"
32
- status = 200
33
- else
34
- body = "Content-Length header is #{content_length_header} but body length is #{input_body.length}"
35
- status = 500
36
- end
37
-
38
- else
39
- status = 404
40
- body = "Undefined url"
41
- end
42
-
43
- env['rack.input'] = env['rack.input'].read
44
- env.delete('rack.errors')
45
- env['output'] = body
46
- env['status'] = status
47
-
48
- [status, {'Content-Type' => 'text/json'}, env.to_json]
49
- end
50
- end
51
-
52
- class Test::Unit::TestCase
53
- def get(path)
54
- response = Net::HTTP.get_response(URI.parse("http://0.0.0.0:#{TEST_PORT}#{path}"))
55
- end
56
-
57
- def post(path, data)
58
- response = Net::HTTP.post_form(URI.parse("http://0.0.0.0:#{TEST_PORT}#{path}"), data)
59
- end
60
- end
61
-
62
- class ServerTest < Test::Unit::TestCase
63
- def get(path)
64
- response = Net::HTTP.get_response(URI.parse("http://0.0.0.0:#{TEST_PORT}#{path}"))
65
- env = JSON.parse(response.body)
66
- end
67
-
68
- def post(path, data)
69
- response = Net::HTTP.post_form(URI.parse("http://0.0.0.0:#{TEST_PORT}#{path}"), data)
70
- env = JSON.parse(response.body)
71
- end
72
-
73
- def setup
74
- Thread.new { Ebb.start_server(HelperApp.new, :port => TEST_PORT) }
75
- sleep 0.1 until Ebb.running?
76
- end
77
-
78
- def teardown
79
- Ebb.stop_server
80
- sleep 0.1 while Ebb.running?
81
- end
82
-
83
- def default_test
84
- assert true
85
- end
86
- end
87
-
88
- class ServerTestFD < ServerTest
89
- def setup
90
- @tcp_server = TCPServer.new('0.0.0.0', TEST_PORT);
91
- Thread.new { Ebb.start_server(HelperApp.new, :fileno => @tcp_server.fileno) }
92
- sleep 0.1 until Ebb.running?
93
- end
94
-
95
- def teardown
96
- super
97
- @tcp_server = nil
98
- end
99
- end
100
-
101
- class ServerTestSocket < ServerTest
102
- def get(path)
103
- socket = UNIXSocket.open(@socketfile)
104
- socket.write("GET #{path} HTTP/1.0\r\n\r\n")
105
- response = ""
106
- while chunk = socket.read(100)
107
- response << chunk
108
- end
109
- body = response.split("\r\n\r\n")[1]
110
- env = JSON.parse(body)
111
- ensure
112
- socket.close if socket
113
- end
114
-
115
- def post(path, data)
116
- socket = UNIXSocket.open(@socketfile)
117
- socket.write("POST #{path} HTTP/1.0\r\nContent-Length: #{data.length}\r\n\r\n#{data}")
118
- response = ""
119
- while chunk = socket.read(100)
120
- response << chunk
121
- end
122
- body = response.split("\r\n\r\n")[1]
123
- env = JSON.parse(body)
124
- ensure
125
- socket.close if socket
126
- end
127
-
128
- def setup
129
- @socketfile = '/tmp/ebb_unittest.sock'
130
- Thread.new { Ebb.start_server(HelperApp.new, :unix_socket => @socketfile) }
131
- sleep 0.1 until Ebb.running?
132
- end
133
-
134
- def teardown
135
- super
136
- end
137
- end
138
-