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:
Refactor/reformat a bit and add doc.
macournoyer (author)
Mon Jan 28 17:47:09 -0800 2008
commit  e94bf798052d2a1171789e0a95fa049ccc4d9ddd
tree    59ce5852c6c31ce983c4e637fce31ebd1bf6bc24
parent  5d29f05e15440c52447a12262de9450adcf8761b
...
25
26
27
28
29
30
31
 
32
33
34
 
35
36
37
...
46
47
48
49
 
50
51
52
53
54
55
 
 
56
57
58
...
25
26
27
 
 
28
 
29
30
31
 
32
33
34
35
...
44
45
46
 
47
48
49
50
51
 
 
52
53
54
55
56
0
@@ -25,13 +25,11 @@ module Thin
0
     end
0
     
0
     def process
0
- env = @request.env
0
-
0
       # Add client info to the request env
0
- env[Request::REMOTE_ADDR] = remote_address(env)
0
+ @request.env[Request::REMOTE_ADDR] = remote_address
0
       
0
       # Process the request
0
- @response.status, @response.headers, @response.body = @app.call(env)
0
+ @response.status, @response.headers, @response.body = @app.call(@request.env)
0
       
0
       # Send the response
0
       @response.each do |chunk|
0
@@ -46,13 +44,13 @@ module Thin
0
       log_error e
0
       close_connection rescue nil
0
     ensure
0
- @request.close rescue nil
0
+ @request.close rescue nil
0
       @response.close rescue nil
0
     end
0
     
0
     protected
0
- def remote_address(env)
0
- if remote_addr = env[Request::FORWARDED_FOR]
0
+ def remote_address
0
+ if remote_addr = @request.env[Request::FORWARDED_FOR]
0
           remote_addr
0
         elsif @unix_socket
0
           # FIXME not sure about this, does it even make sense on a UNIX socket?
...
10
11
12
 
 
 
13
14
 
15
16
17
...
10
11
12
13
14
15
16
 
17
18
19
20
0
@@ -10,8 +10,11 @@ module Thin
0
       @out = ''
0
     end
0
     
0
+ # Add <tt>key: value</tt> pair to the headers.
0
+ # Ignore if already sent and no duplicates are allowed
0
+ # for this +key+.
0
     def []=(key, value)
0
- if !@sent[key] || ALLOWED_DUPLICATES.include?(key)
0
+ if !@sent.has_key?(key) || ALLOWED_DUPLICATES.include?(key)
0
         @sent[key] = true
0
         @out << HEADER_FORMAT % [key, value]
0
       end
...
16
17
18
 
19
20
21
...
16
17
18
19
20
21
22
0
@@ -16,6 +16,7 @@ module Thin
0
         puts msg || yield if ($DEBUG || $TRACE) && !@silent
0
       end
0
       
0
+ # Log an error backtrace if tracing is activated
0
       def log_error(e)
0
         trace { "#{e}\n\t" + e.backtrace.join("\n\t") }
0
       end
...
62
63
64
65
66
67
 
 
 
68
 
69
70
71
72
73
74
75
76
77
78
79
 
 
 
 
 
 
 
 
 
 
 
80
81
82
...
84
85
86
 
87
88
89
90
 
91
92
93
...
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
...
90
91
92
93
94
95
 
 
96
97
98
99
0
@@ -62,21 +62,27 @@ module Thin
0
     def parse(data)
0
       @data << data
0
       
0
- if @parser.finished? # Header finished, can only be some more body
0
- body << data
0
- else # Parse more header using the super parser
0
+ if @parser.finished? # Header finished, can only be some more body
0
+ body << data
0
+ else # Parse more header using the super parser
0
         @nparsed = @parser.execute(@env, @data, @nparsed)
0
+
0
         # Transfert to a tempfile if body is very big
0
         move_body_to_tempfile if @parser.finished? && content_length > MAX_BODY
0
       end
0
       
0
- # Check if header and body are complete
0
- if @parser.finished? && @body.size >= content_length
0
- @body.rewind
0
- return true # Request is fully parsed
0
- end
0
       
0
- false # Not finished, need more data
0
+ if finished? # Check if header and body are complete
0
+ @body.rewind
0
+ true # Request is fully parsed
0
+ else
0
+ false # Not finished, need more data
0
+ end
0
+ end
0
+
0
+ # +true+ if headers and body are finished parsing
0
+ def finished?
0
+ @parser.finished? && @body.size >= content_length
0
     end
0
     
0
     # Expected size of the body
0
@@ -84,10 +90,10 @@ module Thin
0
       @env[CONTENT_LENGTH].to_i
0
     end
0
     
0
+ # Close any resource used by the response
0
     def close
0
       @body.close if @body === Tempfile
0
- end
0
-
0
+ end
0
     
0
     private
0
       def move_body_to_tempfile
...
1
2
3
4
5
6
 
 
 
7
8
9
...
23
24
25
26
 
27
28
29
...
35
36
37
 
 
 
38
39
40
41
42
 
43
 
44
45
46
...
55
56
57
 
58
59
60
...
1
2
3
 
 
 
4
5
6
7
8
9
...
23
24
25
 
26
27
28
29
...
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
...
60
61
62
63
64
65
66
0
@@ -1,9 +1,9 @@
0
 module Thin
0
   # A response sent to the client.
0
   class Response
0
- CONNECTION = 'Connection'.freeze
0
- SERVER = 'Server'.freeze
0
- CLOSE = 'close'.freeze
0
+ CONNECTION = 'Connection'.freeze
0
+ SERVER = 'Server'.freeze
0
+ CLOSE = 'close'.freeze
0
     
0
     # Status code
0
     attr_accessor :status
0
@@ -23,7 +23,7 @@ module Thin
0
     # to be sent in the response.
0
     def headers_output
0
       @headers[CONNECTION] = CLOSE
0
- @headers[SERVER] = Thin::SERVER
0
+ @headers[SERVER] = Thin::SERVER
0
       
0
       @headers.to_s
0
     end
0
@@ -35,12 +35,17 @@ module Thin
0
     end
0
     
0
     if Thin.ruby_18?
0
+
0
+ # Ruby 1.8 implementation.
0
+ # Respects Rack specs.
0
       def headers=(key_value_pairs)
0
         key_value_pairs.each do |k, vs|
0
           vs.each { |v| @headers[k] = v.chomp }
0
         end
0
       end
0
+
0
     else
0
+
0
       # Ruby 1.9 doesn't have a String#each anymore.
0
       # Rack spec doesn't take care of that yet, for now we just use
0
       # +each+ but fallback to +each_line+ on strings.
0
@@ -55,6 +60,7 @@ module Thin
0
           end
0
         end
0
       end
0
+
0
     end
0
     
0
     # Close any resource used by the response
...
1
2
3
4
5
 
6
7
8
...
1
2
3
 
4
5
6
7
8
0
@@ -1,8 +1,8 @@
0
 require 'erb'
0
 
0
 module Thin
0
- # Rack adapter to log stats to a Rack application
0
   module Stats
0
+ # Rack adapter to log stats about a Rack application.
0
     class Adapter
0
       include ERB::Util
0
       
...
1
 
 
2
3
4
...
1
2
3
4
5
6
0
@@ -1,4 +1,6 @@
0
 module Thin
0
+ # Raised when a feature is not supported on the
0
+ # current platform.
0
   class PlatformNotSupported < RuntimeError; end
0
   
0
   module VERSION #:nodoc:
...
19
20
21
 
22
23
24
...
19
20
21
22
23
24
25
0
@@ -19,6 +19,7 @@ describe 'Daemonizing' do
0
       sleep 1
0
     end
0
     
0
+ sleep 1
0
     Process.wait(@pid)
0
     File.exist?(@server.pid_file).should be_true
0
     @pid = @server.pid
...
52
53
54
55
 
56
57
58
...
60
61
62
63
 
64
65
66
...
52
53
54
 
55
56
57
58
...
60
61
62
 
63
64
65
66
0
@@ -52,7 +52,7 @@ describe Response do
0
     out.should include("\r\n\r\n<html></html>")
0
   end
0
   
0
- it "should be faster then #{max_parsing_time = 0.00011} RubySecond" do
0
+ it "should be fast" do
0
     @response.body << <<-EOS
0
 <html><head><title>Dir listing</title></head>
0
 <body><h1>Listing stuff</h1><ul>
0
@@ -60,7 +60,7 @@ describe Response do
0
 </ul></body></html>
0
 EOS
0
     
0
- proc { @response.each { |l| l } }.should be_faster_then(max_parsing_time)
0
+ proc { @response.each { |l| l } }.should be_faster_then(0.00011)
0
   end
0
   
0
   it "should be closeable" do

Comments

    No one has commented yet.