mongrel2 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
 - data/ChangeLog +36 -1
 - data/History.rdoc +6 -0
 - data/Manifest.txt +1 -0
 - data/README.rdoc +52 -21
 - data/bin/m2sh.rb +55 -1
 - data/data/mongrel2/config.rb.in +71 -0
 - data/examples/.env +1 -0
 - data/examples/Procfile +1 -1
 - data/examples/config.rb +1 -1
 - data/examples/ws-echo.rb +12 -0
 - data/lib/mongrel2.rb +2 -2
 - data/lib/mongrel2/config.rb +3 -8
 - data/lib/mongrel2/connection.rb +1 -1
 - data/lib/mongrel2/constants.rb +12 -0
 - data/lib/mongrel2/control.rb +1 -1
 - data/lib/mongrel2/handler.rb +21 -8
 - data/lib/mongrel2/httpresponse.rb +6 -5
 - data/lib/mongrel2/testing.rb +52 -8
 - data/lib/mongrel2/websocket.rb +101 -5
 - data/spec/lib/constants.rb +48 -0
 - data/spec/lib/helpers.rb +50 -4
 - data/spec/mongrel2/handler_spec.rb +36 -0
 - data/spec/mongrel2/httpresponse_spec.rb +4 -3
 - data/spec/mongrel2/websocket_spec.rb +64 -0
 - metadata +3 -2
 - metadata.gz.sig +0 -0
 
    
        data.tar.gz.sig
    CHANGED
    
    | 
         Binary file 
     | 
    
        data/ChangeLog
    CHANGED
    
    | 
         @@ -1,5 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            2012-06-30  Michael Granger  <ged@FaerieMUD.org>
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            	* Manifest.txt, README.rdoc, bin/m2sh.rb, data/mongrel2/config.rb.in,
         
     | 
| 
      
 4 
     | 
    
         
            +
            	lib/mongrel2/config.rb, lib/mongrel2/constants.rb:
         
     | 
| 
      
 5 
     | 
    
         
            +
            	Adding 'bootstrap' and 'quickstart' commands to m2sh.rb.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            	Also adding documentation for them to the README, and moved the
         
     | 
| 
      
 8 
     | 
    
         
            +
            	DATA_DIR constants into mongrel2/constants.
         
     | 
| 
      
 9 
     | 
    
         
            +
            	[2f2b9b4bc86f] [tip]
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            2012-06-27  Michael Granger  <ged@FaerieMUD.org>
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            	* examples/.env, examples/Procfile, examples/config.rb, examples/ws-
         
     | 
| 
      
 14 
     | 
    
         
            +
            	echo.rb, lib/mongrel2/handler.rb, lib/mongrel2/httpresponse.rb,
         
     | 
| 
      
 15 
     | 
    
         
            +
            	lib/mongrel2/testing.rb, lib/mongrel2/websocket.rb,
         
     | 
| 
      
 16 
     | 
    
         
            +
            	spec/lib/constants.rb, spec/lib/helpers.rb,
         
     | 
| 
      
 17 
     | 
    
         
            +
            	spec/mongrel2/handler_spec.rb, spec/mongrel2/httpresponse_spec.rb,
         
     | 
| 
      
 18 
     | 
    
         
            +
            	spec/mongrel2/websocket_spec.rb:
         
     | 
| 
      
 19 
     | 
    
         
            +
            	Updating websocket support for recent Mongrel2 changes
         
     | 
| 
      
 20 
     | 
    
         
            +
            	[c17bbae10985]
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
       1 
22 
     | 
    
         
             
            2012-06-26  Michael Granger  <ged@FaerieMUD.org>
         
     | 
| 
       2 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            	* .hgtags:
         
     | 
| 
      
 25 
     | 
    
         
            +
            	Added tag v0.26.0 for changeset 7fb25e6e09bc
         
     | 
| 
      
 26 
     | 
    
         
            +
            	[1cf11a8e5402]
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            	* .hgsigs:
         
     | 
| 
      
 29 
     | 
    
         
            +
            	Added signature for changeset c2eac469ca66
         
     | 
| 
      
 30 
     | 
    
         
            +
            	[7fb25e6e09bc] [v0.26.0]
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            	* History.rdoc, lib/mongrel2.rb, spec/lib/helpers.rb,
         
     | 
| 
      
 33 
     | 
    
         
            +
            	spec/mongrel2/handler_spec.rb, spec/mongrel2/request_spec.rb:
         
     | 
| 
      
 34 
     | 
    
         
            +
            	Fix the specs broken by the async upload changes, bump minor
         
     | 
| 
      
 35 
     | 
    
         
            +
            	version, update history.
         
     | 
| 
      
 36 
     | 
    
         
            +
            	[c2eac469ca66]
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       3 
38 
     | 
    
         
             
            	* lib/mongrel2/config/handler.rb, lib/mongrel2/config/host.rb,
         
     | 
| 
       4 
39 
     | 
    
         
             
            	lib/mongrel2/config/route.rb, lib/mongrel2/config/server.rb,
         
     | 
| 
       5 
40 
     | 
    
         
             
            	lib/mongrel2/connection.rb, lib/mongrel2/handler.rb,
         
     | 
| 
         @@ -7,7 +42,7 @@ 
     | 
|
| 
       7 
42 
     | 
    
         
             
            	spec/mongrel2/handler_spec.rb, spec/mongrel2/httprequest_spec.rb,
         
     | 
| 
       8 
43 
     | 
    
         
             
            	spec/mongrel2/request_spec.rb:
         
     | 
| 
       9 
44 
     | 
    
         
             
            	Fix the async upload body path
         
     | 
| 
       10 
     | 
    
         
            -
            	[782174dcba2e] 
     | 
| 
      
 45 
     | 
    
         
            +
            	[782174dcba2e]
         
     | 
| 
       11 
46 
     | 
    
         | 
| 
       12 
47 
     | 
    
         
             
            2012-06-21  Michael Granger  <ged@FaerieMUD.org>
         
     | 
| 
       13 
48 
     | 
    
         | 
    
        data/History.rdoc
    CHANGED
    
    | 
         @@ -1,3 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            == v0.27.0 [2012-07-02] Michael Granger <ged@FaerieMUD.org>
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            - Adds support for websocket handshake in 'develop' branch.
         
     | 
| 
      
 4 
     | 
    
         
            +
            - Adds 'bootstrap' and 'quickstart' commands to m2sh.rb.
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       1 
7 
     | 
    
         
             
            == v0.26.0 [2012-06-26] Michael Granger <ged@FaerieMUD.org>
         
     | 
| 
       2 
8 
     | 
    
         | 
| 
       3 
9 
     | 
    
         
             
            - Fix the derived path to the async upload body
         
     | 
    
        data/Manifest.txt
    CHANGED
    
    
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -17,29 +17,36 @@ databases in pure Ruby, a Control port interface object, and handler classes 
     | 
|
| 
       17 
17 
     | 
    
         
             
            for creating applications or higher-level frameworks.
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
            == Installation
         
     | 
| 
      
 20 
     | 
    
         
            +
            == Installation and Setup
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
            Install mongrel2:
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
              $ {brew,port,portmaster,apt-get install,etc} mongrel2
         
     | 
| 
       24 
25 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            classes, but it will also fall back to using the sqlite3 library instead:
         
     | 
| 
      
 26 
     | 
    
         
            +
            Install the mongrel2 gem:
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                $ rspec -rsqlite3 -cfp spec
         
     | 
| 
       30 
     | 
    
         
            -
                >>> Using SQLite3 1.3.4 for DB access.
         
     | 
| 
       31 
     | 
    
         
            -
                .....[...]
         
     | 
| 
      
 28 
     | 
    
         
            +
              $ gem install mongrel2
         
     | 
| 
       32 
29 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                102 examples, 0 failures
         
     | 
| 
      
 30 
     | 
    
         
            +
            Dump a config database generation script into the current working directory:
         
     | 
| 
       35 
31 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                $ rspec -cfp spec
         
     | 
| 
       38 
     | 
    
         
            -
                >>> Using Amalgalite 1.1.2 for DB access.
         
     | 
| 
       39 
     | 
    
         
            -
                .....[...]
         
     | 
| 
      
 32 
     | 
    
         
            +
              $ m2sh.rb bootstrap
         
     | 
| 
       40 
33 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
      
 34 
     | 
    
         
            +
            Edit the generated file:
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              $ $EDITOR config.rb
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            Create a config database from the Ruby config:
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              $ m2sh.rb load config.rb
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            Start the server:
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              $ m2sh.rb start
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            Or combine <tt>bootstrap</tt>, <tt>load</tt>, and <tt>start</tt> all into one
         
     | 
| 
      
 47 
     | 
    
         
            +
            command:
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              $ m2sh.rb quickstart
         
     | 
| 
       43 
50 
     | 
    
         | 
| 
       44 
51 
     | 
    
         | 
| 
       45 
52 
     | 
    
         
             
            == Usage
         
     | 
| 
         @@ -54,6 +61,26 @@ for adding the Ruby configuration DSL to your namespace, and the top-level 
     | 
|
| 
       54 
61 
     | 
    
         
             
            Mongrel2::Config class, which manages the database connection, installs the
         
     | 
| 
       55 
62 
     | 
    
         
             
            schema, etc.
         
     | 
| 
       56 
63 
     | 
    
         | 
| 
      
 64 
     | 
    
         
            +
            The ORM classes use Jeremy Hinegardner's 'amalgalite' library, but it will
         
     | 
| 
      
 65 
     | 
    
         
            +
            also fall back to using the sqlite3 library instead:
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                # Loading the sqlite3 library explicitly
         
     | 
| 
      
 68 
     | 
    
         
            +
                $ rspec -rsqlite3 -cfp spec
         
     | 
| 
      
 69 
     | 
    
         
            +
                >>> Using SQLite3 1.3.4 for DB access.
         
     | 
| 
      
 70 
     | 
    
         
            +
                .....[...]
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                Finished in 5.53 seconds
         
     | 
| 
      
 73 
     | 
    
         
            +
                102 examples, 0 failures
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                # No -rsqlite3 means amalgalite loads first.
         
     | 
| 
      
 76 
     | 
    
         
            +
                $ rspec -cfp spec
         
     | 
| 
      
 77 
     | 
    
         
            +
                >>> Using Amalgalite 1.1.2 for DB access.
         
     | 
| 
      
 78 
     | 
    
         
            +
                .....[...]
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                Finished in 3.67 seconds
         
     | 
| 
      
 81 
     | 
    
         
            +
                102 examples, 0 failures
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
       57 
84 
     | 
    
         
             
            * Mongrel2::Config
         
     | 
| 
       58 
85 
     | 
    
         
             
              * Mongrel2::Config::DSL
         
     | 
| 
       59 
86 
     | 
    
         
             
              * Mongrel2::Config::Server
         
     | 
| 
         @@ -82,6 +109,7 @@ Mongrel2 sends: 
     | 
|
| 
       82 
109 
     | 
    
         
             
            * Mongrel2::HTTPRequest
         
     | 
| 
       83 
110 
     | 
    
         
             
            * Mongrel2::JSONRequest
         
     | 
| 
       84 
111 
     | 
    
         
             
            * Mongrel2::XMLRequest
         
     | 
| 
      
 112 
     | 
    
         
            +
            * Mongrel2::WebSocket::ClientHandshake
         
     | 
| 
       85 
113 
     | 
    
         
             
            * Mongrel2::WebSocket::Frame
         
     | 
| 
       86 
114 
     | 
    
         | 
| 
       87 
115 
     | 
    
         
             
            These are all {overridable}[rdoc-ref:Mongrel2::Request.register_request_type]
         
     | 
| 
         @@ -94,17 +122,20 @@ handlers. 
     | 
|
| 
       94 
122 
     | 
    
         
             
            === The Control Class
         
     | 
| 
       95 
123 
     | 
    
         | 
| 
       96 
124 
     | 
    
         
             
            The Mongrel2::Control class is an object interface to {the Mongrel2 control
         
     | 
| 
       97 
     | 
    
         
            -
            port}[http://mongrel2.org/static/ 
     | 
| 
      
 125 
     | 
    
         
            +
            port}[http://mongrel2.org/static/book-finalch4.html#x6-390003.8]. It can be
         
     | 
| 
       98 
126 
     | 
    
         
             
            used to stop and restart the server, check its status, etc.
         
     | 
| 
       99 
127 
     | 
    
         | 
| 
       100 
128 
     | 
    
         | 
| 
       101 
129 
     | 
    
         
             
            === Other Classes
         
     | 
| 
       102 
130 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
            There are a few other classes and modules  
     | 
| 
      
 131 
     | 
    
         
            +
            There are a few other classes and modules worth checking out, too:
         
     | 
| 
       104 
132 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
      
 133 
     | 
    
         
            +
            Mongrel2::Table::
         
     | 
| 
      
 134 
     | 
    
         
            +
              A hash-like data structure for headers, etc.
         
     | 
| 
      
 135 
     | 
    
         
            +
            Mongrel2::Constants::
         
     | 
| 
      
 136 
     | 
    
         
            +
              A collection of convenience constants for Mongrel2 handlers.
         
     | 
| 
      
 137 
     | 
    
         
            +
            Mongrel2::RequestFactory::
         
     | 
| 
      
 138 
     | 
    
         
            +
              A factory for generating fixtured requests of various types for testing.
         
     | 
| 
       108 
139 
     | 
    
         | 
| 
       109 
140 
     | 
    
         | 
| 
       110 
141 
     | 
    
         
             
            == Contributing
         
     | 
    
        data/bin/m2sh.rb
    CHANGED
    
    | 
         @@ -186,7 +186,7 @@ class Mongrel2::M2SHCommand 
     | 
|
| 
       186 
186 
     | 
    
         
             
            				text ''
         
     | 
| 
       187 
187 
     | 
    
         | 
| 
       188 
188 
     | 
    
         
             
            				text 'Global Options'
         
     | 
| 
       189 
     | 
    
         
            -
            				opt :config, "Specify the  
     | 
| 
      
 189 
     | 
    
         
            +
            				opt :config, "Specify the config database to use.",
         
     | 
| 
       190 
190 
     | 
    
         
             
            					:default => DEFAULT_CONFIG_URI
         
     | 
| 
       191 
191 
     | 
    
         
             
            				opt :sudo, "Use 'sudo' to run the mongrel2 server."
         
     | 
| 
       192 
192 
     | 
    
         
             
            				opt :port, "Reset the server port to <i> before starting it.",
         
     | 
| 
         @@ -588,6 +588,43 @@ class Mongrel2::M2SHCommand 
     | 
|
| 
       588 
588 
     | 
    
         
             
            	usage :running, "[server]"
         
     | 
| 
       589 
589 
     | 
    
         | 
| 
       590 
590 
     | 
    
         | 
| 
      
 591 
     | 
    
         
            +
            	### The 'bootstrap' command.
         
     | 
| 
      
 592 
     | 
    
         
            +
            	def bootstrap_command( *args )
         
     | 
| 
      
 593 
     | 
    
         
            +
            		scriptname = args.shift || DEFAULT_CONFIG_SCRIPT
         
     | 
| 
      
 594 
     | 
    
         
            +
            		template   = Mongrel2::DATA_DIR + 'config.rb.in'
         
     | 
| 
      
 595 
     | 
    
         
            +
            		data       = template.read
         
     | 
| 
      
 596 
     | 
    
         
            +
             
     | 
| 
      
 597 
     | 
    
         
            +
            		data.gsub!( /%% PWD %%/, Dir.pwd )
         
     | 
| 
      
 598 
     | 
    
         
            +
             
     | 
| 
      
 599 
     | 
    
         
            +
            		header "Writing a config-generation script to %s" % [ scriptname ]
         
     | 
| 
      
 600 
     | 
    
         
            +
            		File.open( scriptname, File::WRONLY|File::EXCL|File::CREAT, 0755, encoding: 'utf-8' ) do |fh|
         
     | 
| 
      
 601 
     | 
    
         
            +
            			fh.print( data )
         
     | 
| 
      
 602 
     | 
    
         
            +
            		end
         
     | 
| 
      
 603 
     | 
    
         
            +
            		message "Done."
         
     | 
| 
      
 604 
     | 
    
         
            +
            	end
         
     | 
| 
      
 605 
     | 
    
         
            +
            	help :bootstrap, "Generate a basic config-generation script."
         
     | 
| 
      
 606 
     | 
    
         
            +
            	usage :boostrap, "[scriptname]"
         
     | 
| 
      
 607 
     | 
    
         
            +
             
     | 
| 
      
 608 
     | 
    
         
            +
             
     | 
| 
      
 609 
     | 
    
         
            +
            	### The 'quickstart' command.
         
     | 
| 
      
 610 
     | 
    
         
            +
            	def quickstart_command( *args )
         
     | 
| 
      
 611 
     | 
    
         
            +
            		configfile = 'config.rb'
         
     | 
| 
      
 612 
     | 
    
         
            +
             
     | 
| 
      
 613 
     | 
    
         
            +
            		header "Quickstart!"
         
     | 
| 
      
 614 
     | 
    
         
            +
            		self.bootstrap_command( configfile )
         
     | 
| 
      
 615 
     | 
    
         
            +
            		edit( configfile )
         
     | 
| 
      
 616 
     | 
    
         
            +
            		self.load_command( configfile )
         
     | 
| 
      
 617 
     | 
    
         
            +
             
     | 
| 
      
 618 
     | 
    
         
            +
            		message '---'
         
     | 
| 
      
 619 
     | 
    
         
            +
            		header "Point a browser at: "
         
     | 
| 
      
 620 
     | 
    
         
            +
            		message '---'
         
     | 
| 
      
 621 
     | 
    
         
            +
             
     | 
| 
      
 622 
     | 
    
         
            +
            		self.start_command()
         
     | 
| 
      
 623 
     | 
    
         
            +
            	end
         
     | 
| 
      
 624 
     | 
    
         
            +
            	help :quickstart, "Set up a basic mongrel2 server and run it."
         
     | 
| 
      
 625 
     | 
    
         
            +
            	usage :quickstart
         
     | 
| 
      
 626 
     | 
    
         
            +
             
     | 
| 
      
 627 
     | 
    
         
            +
             
     | 
| 
       591 
628 
     | 
    
         
             
            	### The 'version' command
         
     | 
| 
       592 
629 
     | 
    
         
             
            	def version_command( *args )
         
     | 
| 
       593 
630 
     | 
    
         
             
            		message( "<%= color 'Version:', :header %> " + Mongrel2.version_string(true) )
         
     | 
| 
         @@ -599,6 +636,10 @@ class Mongrel2::M2SHCommand 
     | 
|
| 
       599 
636 
     | 
    
         
             
            	# Utility methods
         
     | 
| 
       600 
637 
     | 
    
         
             
            	#
         
     | 
| 
       601 
638 
     | 
    
         | 
| 
      
 639 
     | 
    
         
            +
            	#######
         
     | 
| 
      
 640 
     | 
    
         
            +
            	private
         
     | 
| 
      
 641 
     | 
    
         
            +
            	#######
         
     | 
| 
      
 642 
     | 
    
         
            +
             
     | 
| 
       602 
643 
     | 
    
         
             
            	### Output normal output
         
     | 
| 
       603 
644 
     | 
    
         
             
            	def message( *parts )
         
     | 
| 
       604 
645 
     | 
    
         
             
            		self.prompt.say( parts.map(&:to_s).join($/) )
         
     | 
| 
         @@ -676,6 +717,19 @@ class Mongrel2::M2SHCommand 
     | 
|
| 
       676 
717 
     | 
    
         
             
            		return server
         
     | 
| 
       677 
718 
     | 
    
         
             
            	end
         
     | 
| 
       678 
719 
     | 
    
         | 
| 
      
 720 
     | 
    
         
            +
             
     | 
| 
      
 721 
     | 
    
         
            +
            	### Invoke the user's editor on the given +filename+ and return the exit code
         
     | 
| 
      
 722 
     | 
    
         
            +
            	### from doing so.
         
     | 
| 
      
 723 
     | 
    
         
            +
            	def edit( filename )
         
     | 
| 
      
 724 
     | 
    
         
            +
            		editor = ENV['EDITOR'] || ENV['VISUAL'] || DEFAULT_EDITOR
         
     | 
| 
      
 725 
     | 
    
         
            +
            		system editor, filename.to_s
         
     | 
| 
      
 726 
     | 
    
         
            +
            		unless $?.success? || editor =~ /vim/i
         
     | 
| 
      
 727 
     | 
    
         
            +
            			raise "Editor exited with an error status (%d)" % [ $?.exitstatus ]
         
     | 
| 
      
 728 
     | 
    
         
            +
            		end
         
     | 
| 
      
 729 
     | 
    
         
            +
            	end
         
     | 
| 
      
 730 
     | 
    
         
            +
             
     | 
| 
      
 731 
     | 
    
         
            +
             
     | 
| 
      
 732 
     | 
    
         
            +
             
     | 
| 
       679 
733 
     | 
    
         
             
            end # class Mongrel2::M2SHCommand
         
     | 
| 
       680 
734 
     | 
    
         | 
| 
       681 
735 
     | 
    
         | 
| 
         @@ -0,0 +1,71 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            #encoding: utf-8
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'pathname'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'tmpdir'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            # This is a Ruby script that will *generate* the SQLite database
         
     | 
| 
      
 8 
     | 
    
         
            +
            # that Mongrel2 uses for its configuration. You can just as easily
         
     | 
| 
      
 9 
     | 
    
         
            +
            # use Mongrel2's 'm2sh' and the Pythonish config syntax described
         
     | 
| 
      
 10 
     | 
    
         
            +
            # in the manual if you prefer that.
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            # See the "Mongrel2 Config DSL" section of the API docs, and the "How A
         
     | 
| 
      
 13 
     | 
    
         
            +
            # Config Is Structured" section of the manual for details
         
     | 
| 
      
 14 
     | 
    
         
            +
            # on specific items:
         
     | 
| 
      
 15 
     | 
    
         
            +
            #
         
     | 
| 
      
 16 
     | 
    
         
            +
            # Mongrel2 Config DSL::
         
     | 
| 
      
 17 
     | 
    
         
            +
            #   http://deveiate.org/code/mongrel2/DSL_rdoc.html
         
     | 
| 
      
 18 
     | 
    
         
            +
            #
         
     | 
| 
      
 19 
     | 
    
         
            +
            # How A Config Is Structured::
         
     | 
| 
      
 20 
     | 
    
         
            +
            #   http://mongrel2.org/static/book-finalch4.html#x6-260003.4
         
     | 
| 
      
 21 
     | 
    
         
            +
            #
         
     | 
| 
      
 22 
     | 
    
         
            +
            # You can load this via the 'm2sh.rb' tool that comes with the 'mongrel2'
         
     | 
| 
      
 23 
     | 
    
         
            +
            # gem:
         
     | 
| 
      
 24 
     | 
    
         
            +
            #
         
     | 
| 
      
 25 
     | 
    
         
            +
            #   m2sh.rb -c config.sqlite load config.rb
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            # Establish some directories
         
     | 
| 
      
 28 
     | 
    
         
            +
            base_dir   = Pathname( '%% PWD %%' )
         
     | 
| 
      
 29 
     | 
    
         
            +
            upload_dir = Pathname( Dir.tmpdir ) + 'm2spool'
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            # Main Mongrel2 server config
         
     | 
| 
      
 32 
     | 
    
         
            +
            main = server 'main' do
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            	name         'Main'
         
     | 
| 
      
 35 
     | 
    
         
            +
            	default_host 'localhost'
         
     | 
| 
      
 36 
     | 
    
         
            +
            	chroot       base_dir
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            	# All of these values are relative to the 'chroot' value if Mongrel2
         
     | 
| 
      
 39 
     | 
    
         
            +
            	# is started as root. If it's not, they're relative to the directory
         
     | 
| 
      
 40 
     | 
    
         
            +
            	# it's started in.
         
     | 
| 
      
 41 
     | 
    
         
            +
            	access_log   '/logs/access.log'
         
     | 
| 
      
 42 
     | 
    
         
            +
            	error_log    '/logs/error.log'
         
     | 
| 
      
 43 
     | 
    
         
            +
            	pid_file     '/var/run/mongrel2.pid'
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            	# This the address and port the server will listen on. You can
         
     | 
| 
      
 46 
     | 
    
         
            +
            	# use '0.0.0.0' as the bind_addr to listen on all interfaces/IPs.
         
     | 
| 
      
 47 
     | 
    
         
            +
            	bind_addr    '127.0.0.1'
         
     | 
| 
      
 48 
     | 
    
         
            +
            	port         8113
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            	host 'localhost' do
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            		# Serve static content out of a 'public' subdirectory
         
     | 
| 
      
 53 
     | 
    
         
            +
            		route '/', directory( "public/", 'index.html', 'text/html' )
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            		# Dynamic content is served via handler routes
         
     | 
| 
      
 56 
     | 
    
         
            +
            		route '/hello', handler( 'tcp://127.0.0.1:9999',  'helloworld' )
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            	end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            setting 'limits.content_length', 512 * 1024
         
     | 
| 
      
 63 
     | 
    
         
            +
            setting 'control_port', 'ipc://var/run/mongrel2.sock'
         
     | 
| 
      
 64 
     | 
    
         
            +
            setting 'upload.temp_store', upload_dir + 'mongrel2.upload.XXXXXX'
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            # Make relative directories so that starting as a regular user works
         
     | 
| 
      
 67 
     | 
    
         
            +
            (base_dir + "./#{main.access_log}").dirname.mkpath
         
     | 
| 
      
 68 
     | 
    
         
            +
            (base_dir + "./#{main.error_log}").dirname.mkpath
         
     | 
| 
      
 69 
     | 
    
         
            +
            (base_dir + "./#{main.pid_file}").dirname.mkpath
         
     | 
| 
      
 70 
     | 
    
         
            +
            mkdir_p( upload_dir )
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
    
        data/examples/.env
    CHANGED
    
    
    
        data/examples/Procfile
    CHANGED
    
    
    
        data/examples/config.rb
    CHANGED
    
    
    
        data/examples/ws-echo.rb
    CHANGED
    
    | 
         @@ -86,6 +86,18 @@ class WebSocketEchoServer < Mongrel2::Handler 
     | 
|
| 
       86 
86 
     | 
    
         
             
            	end
         
     | 
| 
       87 
87 
     | 
    
         | 
| 
       88 
88 
     | 
    
         | 
| 
      
 89 
     | 
    
         
            +
            	# Handle the initial handshake. Assumes no sub-protocols or protocol version
         
     | 
| 
      
 90 
     | 
    
         
            +
            	# checks are necessary.
         
     | 
| 
      
 91 
     | 
    
         
            +
            	def handle_websocket_handshake( handshake )
         
     | 
| 
      
 92 
     | 
    
         
            +
            		self.log.info "Handshake from %s" % [ handshake.remote_ip ]
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            		response = handshake.response( handshake.protocols.first )
         
     | 
| 
      
 95 
     | 
    
         
            +
            		@connections[ [handshake.sender_id, handshake.conn_id] ] = Time.now
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            		return response
         
     | 
| 
      
 98 
     | 
    
         
            +
            	end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
       89 
101 
     | 
    
         
             
            	# This is the main handler for WebSocket requests. Each frame comes in as a
         
     | 
| 
       90 
102 
     | 
    
         
             
            	# Mongrel::WebSocket::Frame object, and then is dispatched according to what
         
     | 
| 
       91 
103 
     | 
    
         
             
            	# opcode it has.
         
     | 
    
        data/lib/mongrel2.rb
    CHANGED
    
    | 
         @@ -20,10 +20,10 @@ module Mongrel2 
     | 
|
| 
       20 
20 
     | 
    
         
             
            	abort "\n\n>>> Mongrel2 requires Ruby 1.9.2 or later. <<<\n\n" if RUBY_VERSION < '1.9.2'
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            	# Library version constant
         
     | 
| 
       23 
     | 
    
         
            -
            	VERSION = '0. 
     | 
| 
      
 23 
     | 
    
         
            +
            	VERSION = '0.27.0'
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
            	# Version-control revision constant
         
     | 
| 
       26 
     | 
    
         
            -
            	REVISION = %q$Revision:  
     | 
| 
      
 26 
     | 
    
         
            +
            	REVISION = %q$Revision: 6de3cbe2409c $
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            	require 'mongrel2/constants'
         
     | 
    
        data/lib/mongrel2/config.rb
    CHANGED
    
    | 
         @@ -28,6 +28,7 @@ end 
     | 
|
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            require 'mongrel2' unless defined?( Mongrel2 )
         
     | 
| 
       30 
30 
     | 
    
         
             
            require 'mongrel2/table'
         
     | 
| 
      
 31 
     | 
    
         
            +
            require 'mongrel2/constants'
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
33 
     | 
    
         
             
            module Mongrel2
         
     | 
| 
       33 
34 
     | 
    
         | 
| 
         @@ -42,10 +43,11 @@ module Mongrel2 
     | 
|
| 
       42 
43 
     | 
    
         
             
            	# plugins.
         
     | 
| 
       43 
44 
     | 
    
         
             
            	#
         
     | 
| 
       44 
45 
     | 
    
         
             
            	# == References
         
     | 
| 
       45 
     | 
    
         
            -
            	# * http://mongrel2.org/static/ 
     | 
| 
      
 46 
     | 
    
         
            +
            	# * http://mongrel2.org/static/book-finalch4.html#x6-260003.4
         
     | 
| 
       46 
47 
     | 
    
         
             
            	#
         
     | 
| 
       47 
48 
     | 
    
         
             
            	class Config < Sequel::Model
         
     | 
| 
       48 
49 
     | 
    
         
             
            		extend Loggability
         
     | 
| 
      
 50 
     | 
    
         
            +
            		include Mongrel2::Constants
         
     | 
| 
       49 
51 
     | 
    
         | 
| 
       50 
52 
     | 
    
         
             
            		# Loggability API -- set up logging under the 'mongrel2' log host
         
     | 
| 
       51 
53 
     | 
    
         
             
            		log_to :mongrel2
         
     | 
| 
         @@ -63,13 +65,6 @@ module Mongrel2 
     | 
|
| 
       63 
65 
     | 
    
         
             
            		}
         
     | 
| 
       64 
66 
     | 
    
         
             
            		DEFAULTS = CONFIG_DEFAULTS
         
     | 
| 
       65 
67 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
            		# The Pathname of the data directory
         
     | 
| 
       67 
     | 
    
         
            -
            		DATA_DIR = if Gem.datadir( 'mongrel2' )
         
     | 
| 
       68 
     | 
    
         
            -
            				Pathname( Gem.datadir('mongrel2') )
         
     | 
| 
       69 
     | 
    
         
            -
            			else
         
     | 
| 
       70 
     | 
    
         
            -
            				Pathname( __FILE__ ).dirname.parent.parent + 'data/mongrel2'
         
     | 
| 
       71 
     | 
    
         
            -
            			end
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
68 
     | 
    
         
             
            		# The Pathname of the SQL file used to create the config database
         
     | 
| 
       74 
69 
     | 
    
         
             
            		CONFIG_SQL    = DATA_DIR + 'config.sql'
         
     | 
| 
       75 
70 
     | 
    
         | 
    
        data/lib/mongrel2/connection.rb
    CHANGED
    
    | 
         @@ -15,7 +15,7 @@ require 'mongrel2' unless defined?( Mongrel2 ) 
     | 
|
| 
       15 
15 
     | 
    
         
             
            # then encodes and sends Mongrel2::Response objects back to the server.
         
     | 
| 
       16 
16 
     | 
    
         
             
            #
         
     | 
| 
       17 
17 
     | 
    
         
             
            # == References
         
     | 
| 
       18 
     | 
    
         
            -
            # * http://mongrel2.org/static/ 
     | 
| 
      
 18 
     | 
    
         
            +
            # * http://mongrel2.org/static/book-finalch6.html#x8-710005.3
         
     | 
| 
       19 
19 
     | 
    
         
             
            class Mongrel2::Connection
         
     | 
| 
       20 
20 
     | 
    
         
             
            	extend Loggability
         
     | 
| 
       21 
21 
     | 
    
         | 
    
        data/lib/mongrel2/constants.rb
    CHANGED
    
    | 
         @@ -8,9 +8,21 @@ require 'mongrel2' unless defined?( Mongrel2 ) 
     | 
|
| 
       8 
8 
     | 
    
         
             
            # A collection of constants that are shared across the library
         
     | 
| 
       9 
9 
     | 
    
         
             
            module Mongrel2::Constants
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
            	# The Pathname of the data directory
         
     | 
| 
      
 12 
     | 
    
         
            +
            	DATA_DIR = if ENV['MONGREL2_DATADIR']
         
     | 
| 
      
 13 
     | 
    
         
            +
            			Pathname( ENV['MONGREL2_DATADIR'] )
         
     | 
| 
      
 14 
     | 
    
         
            +
            		elsif Gem.datadir( 'mongrel2' )
         
     | 
| 
      
 15 
     | 
    
         
            +
            			Pathname( Gem.datadir('mongrel2') )
         
     | 
| 
      
 16 
     | 
    
         
            +
            		else
         
     | 
| 
      
 17 
     | 
    
         
            +
            			Pathname( __FILE__ ).dirname.parent.parent + 'data/mongrel2'
         
     | 
| 
      
 18 
     | 
    
         
            +
            		end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       11 
20 
     | 
    
         
             
            	# The path to the default Sqlite configuration database
         
     | 
| 
       12 
21 
     | 
    
         
             
            	DEFAULT_CONFIG_URI = 'config.sqlite'
         
     | 
| 
       13 
22 
     | 
    
         | 
| 
      
 23 
     | 
    
         
            +
            	# The default name of the config-generation script
         
     | 
| 
      
 24 
     | 
    
         
            +
            	DEFAULT_CONFIG_SCRIPT = 'config.rb'
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       14 
26 
     | 
    
         
             
            	# The default URI of the control socket
         
     | 
| 
       15 
27 
     | 
    
         
             
            	DEFAULT_CONTROL_SOCKET = 'ipc://run/control'
         
     | 
| 
       16 
28 
     | 
    
         | 
    
        data/lib/mongrel2/control.rb
    CHANGED
    
    | 
         @@ -11,7 +11,7 @@ require 'mongrel2' unless defined?( Mongrel2 ) 
     | 
|
| 
       11 
11 
     | 
    
         
             
            # An interface to the Mongrel2 control port.
         
     | 
| 
       12 
12 
     | 
    
         
             
            #
         
     | 
| 
       13 
13 
     | 
    
         
             
            # == References
         
     | 
| 
       14 
     | 
    
         
            -
            # (http://mongrel2.org/static/ 
     | 
| 
      
 14 
     | 
    
         
            +
            # (http://mongrel2.org/static/book-finalch4.html#x6-390003.8)
         
     | 
| 
       15 
15 
     | 
    
         
             
            class Mongrel2::Control
         
     | 
| 
       16 
16 
     | 
    
         
             
            	extend Loggability
         
     | 
| 
       17 
17 
     | 
    
         | 
    
        data/lib/mongrel2/handler.rb
    CHANGED
    
    | 
         @@ -207,19 +207,18 @@ class Mongrel2::Handler 
     | 
|
| 
       207 
207 
     | 
    
         
             
            			return self.handle_async_upload_start( request )
         
     | 
| 
       208 
208 
     | 
    
         | 
| 
       209 
209 
     | 
    
         
             
            		else
         
     | 
| 
      
 210 
     | 
    
         
            +
            			self.log.debug "%s request." % [ request.headers['METHOD'] ]
         
     | 
| 
       210 
211 
     | 
    
         
             
            			case request
         
     | 
| 
      
 212 
     | 
    
         
            +
            			when Mongrel2::WebSocket::ClientHandshake
         
     | 
| 
      
 213 
     | 
    
         
            +
            				return self.handle_websocket_handshake( request )
         
     | 
| 
      
 214 
     | 
    
         
            +
            			when Mongrel2::WebSocket::Frame
         
     | 
| 
      
 215 
     | 
    
         
            +
            				return self.handle_websocket( request )
         
     | 
| 
       211 
216 
     | 
    
         
             
            			when Mongrel2::HTTPRequest
         
     | 
| 
       212 
     | 
    
         
            -
            				self.log.debug "HTTP request."
         
     | 
| 
       213 
217 
     | 
    
         
             
            				return self.handle( request )
         
     | 
| 
       214 
218 
     | 
    
         
             
            			when Mongrel2::JSONRequest
         
     | 
| 
       215 
     | 
    
         
            -
            				self.log.debug "JSON message request."
         
     | 
| 
       216 
219 
     | 
    
         
             
            				return self.handle_json( request )
         
     | 
| 
       217 
220 
     | 
    
         
             
            			when Mongrel2::XMLRequest
         
     | 
| 
       218 
     | 
    
         
            -
            				self.log.debug "XML message request."
         
     | 
| 
       219 
221 
     | 
    
         
             
            				return self.handle_xml( request )
         
     | 
| 
       220 
     | 
    
         
            -
            			when Mongrel2::WebSocket::Frame
         
     | 
| 
       221 
     | 
    
         
            -
            				self.log.debug "WEBSOCKET message request."
         
     | 
| 
       222 
     | 
    
         
            -
            				return self.handle_websocket( request )
         
     | 
| 
       223 
222 
     | 
    
         
             
            			else
         
     | 
| 
       224 
223 
     | 
    
         
             
            				self.log.error "Unhandled request type %s (%p)" %
         
     | 
| 
       225 
224 
     | 
    
         
             
            					[ request.headers['METHOD'], request.class ]
         
     | 
| 
         @@ -279,10 +278,24 @@ class Mongrel2::Handler 
     | 
|
| 
       279 
278 
     | 
    
         
             
            	### Handle a WebSocket frame in +request+. If not overridden, WebSocket connections are
         
     | 
| 
       280 
279 
     | 
    
         
             
            	### closed with a policy error status.
         
     | 
| 
       281 
280 
     | 
    
         
             
            	def handle_websocket( request )
         
     | 
| 
       282 
     | 
    
         
            -
            		self.log.warn "Unhandled WEBSOCKET  
     | 
| 
      
 281 
     | 
    
         
            +
            		self.log.warn "Unhandled WEBSOCKET frame (%p)" % [ request.headers.path ]
         
     | 
| 
       283 
282 
     | 
    
         
             
            		res = request.response
         
     | 
| 
       284 
283 
     | 
    
         
             
            		res.make_close_frame( WebSocket::CLOSE_POLICY_VIOLATION )
         
     | 
| 
       285 
     | 
    
         
            -
            		 
     | 
| 
      
 284 
     | 
    
         
            +
            		self.conn.reply( res)
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
            		self.conn.reply_close( request )
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
            		return nil
         
     | 
| 
      
 289 
     | 
    
         
            +
            	end
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
            	### Handle a WebSocket handshake HTTP +request+. If not overridden, this method drops
         
     | 
| 
      
 293 
     | 
    
         
            +
            	### the connection.
         
     | 
| 
      
 294 
     | 
    
         
            +
            	def handle_websocket_handshake( handshake )
         
     | 
| 
      
 295 
     | 
    
         
            +
            		self.log.warn "Unhandled WEBSOCKET_HANDSHAKE request (%p)" % [ request.headers.path ]
         
     | 
| 
      
 296 
     | 
    
         
            +
            		self.conn.reply_close( request )
         
     | 
| 
      
 297 
     | 
    
         
            +
             
     | 
| 
      
 298 
     | 
    
         
            +
            		return nil
         
     | 
| 
       286 
299 
     | 
    
         
             
            	end
         
     | 
| 
       287 
300 
     | 
    
         | 
| 
       288 
301 
     | 
    
         | 
| 
         @@ -169,12 +169,13 @@ class Mongrel2::HTTPResponse < Mongrel2::Response 
     | 
|
| 
       169 
169 
     | 
    
         
             
            		headers = self.headers.dup
         
     | 
| 
       170 
170 
     | 
    
         | 
| 
       171 
171 
     | 
    
         
             
            		headers[:date] ||= Time.now.httpdate
         
     | 
| 
       172 
     | 
    
         
            -
            		headers[:content_length] ||= self.get_content_length
         
     | 
| 
       173 
172 
     | 
    
         | 
| 
       174 
173 
     | 
    
         
             
            		if self.bodiless?
         
     | 
| 
      
 174 
     | 
    
         
            +
            			headers.delete( :content_length )
         
     | 
| 
       175 
175 
     | 
    
         
             
            			headers.delete( :content_type )
         
     | 
| 
       176 
176 
     | 
    
         
             
            		else
         
     | 
| 
       177 
     | 
    
         
            -
            			headers[: 
     | 
| 
      
 177 
     | 
    
         
            +
            			headers[:content_length] ||= self.get_content_length
         
     | 
| 
      
 178 
     | 
    
         
            +
            			headers[:content_type]   ||= DEFAULT_CONTENT_TYPE.dup
         
     | 
| 
       178 
179 
     | 
    
         
             
            		end
         
     | 
| 
       179 
180 
     | 
    
         | 
| 
       180 
181 
     | 
    
         
             
            		return headers
         
     | 
| 
         @@ -184,11 +185,11 @@ class Mongrel2::HTTPResponse < Mongrel2::Response 
     | 
|
| 
       184 
185 
     | 
    
         
             
            	### Get the length of the body IO. If the IO's offset is somewhere other than
         
     | 
| 
       185 
186 
     | 
    
         
             
            	### the beginning or end, the size of the remainder is used.
         
     | 
| 
       186 
187 
     | 
    
         
             
            	def get_content_length
         
     | 
| 
       187 
     | 
    
         
            -
            		if self. 
     | 
| 
       188 
     | 
    
         
            -
            			 
     | 
| 
       189 
     | 
    
         
            -
            		elsif self.body.pos.nonzero? && !self.body.eof?
         
     | 
| 
      
 188 
     | 
    
         
            +
            		if self.body.pos.nonzero? && !self.body.eof?
         
     | 
| 
      
 189 
     | 
    
         
            +
            			self.log.info "Calculating content length based on an offset of %d" % [ self.body.pos ]
         
     | 
| 
       190 
190 
     | 
    
         
             
            			return self.body.size - self.body.pos
         
     | 
| 
       191 
191 
     | 
    
         
             
            		else
         
     | 
| 
      
 192 
     | 
    
         
            +
            			self.log.debug "Calculating body size via %p" % [ self.body.method(:size) ]
         
     | 
| 
       192 
193 
     | 
    
         
             
            			return self.body.size
         
     | 
| 
       193 
194 
     | 
    
         
             
            		end
         
     | 
| 
       194 
195 
     | 
    
         
             
            	end
         
     | 
    
        data/lib/mongrel2/testing.rb
    CHANGED
    
    | 
         @@ -12,13 +12,38 @@ require 'mongrel2/request' 
     | 
|
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            module Mongrel2
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
            	 
     | 
| 
       16 
     | 
    
         
            -
            	 
     | 
| 
      
 15 
     | 
    
         
            +
            	# A collection of helper functions that are generally useful
         
     | 
| 
      
 16 
     | 
    
         
            +
            	# for testing Mongrel2::Handlers.
         
     | 
| 
       17 
17 
     | 
    
         
             
            	module SpecHelpers
         
     | 
| 
       18 
18 
     | 
    
         
             
            	end # module SpecHelpers
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            	 
     | 
| 
      
 21 
     | 
    
         
            +
            	# A factory for generating Mongrel2::Request objects for testing.
         
     | 
| 
      
 22 
     | 
    
         
            +
            	#
         
     | 
| 
      
 23 
     | 
    
         
            +
            	# Usage:
         
     | 
| 
      
 24 
     | 
    
         
            +
            	#
         
     | 
| 
      
 25 
     | 
    
         
            +
            	#   require 'mongrel2/testing'
         
     | 
| 
      
 26 
     | 
    
         
            +
            	#
         
     | 
| 
      
 27 
     | 
    
         
            +
            	#   describe "MyHandler" do
         
     | 
| 
      
 28 
     | 
    
         
            +
            	#       before( :all ) do
         
     | 
| 
      
 29 
     | 
    
         
            +
            	#           @factory = Mongrel2::RequestFactory.
         
     | 
| 
      
 30 
     | 
    
         
            +
            	#               new( sender_id: 'my-handler',
         
     | 
| 
      
 31 
     | 
    
         
            +
            	#                    route: '/api/v1',
         
     | 
| 
      
 32 
     | 
    
         
            +
            	#                    headers: {accept: 'application/json'} )
         
     | 
| 
      
 33 
     | 
    
         
            +
            	#       end
         
     | 
| 
      
 34 
     | 
    
         
            +
            	#
         
     | 
| 
      
 35 
     | 
    
         
            +
            	#       before( :each ) do
         
     | 
| 
      
 36 
     | 
    
         
            +
            	#           @app = MyHandler.new( 'my-handler', 'tcp://0.0.0.0:5556',
         
     | 
| 
      
 37 
     | 
    
         
            +
            	#                                 'tcp://0.0.0.0:5555' )
         
     | 
| 
      
 38 
     | 
    
         
            +
            	#       end
         
     | 
| 
      
 39 
     | 
    
         
            +
            	#
         
     | 
| 
      
 40 
     | 
    
         
            +
            	#       it "handles a JSON request for GET /" do
         
     | 
| 
      
 41 
     | 
    
         
            +
            	#           request = @factory.get( '/api/v1' )
         
     | 
| 
      
 42 
     | 
    
         
            +
            	#           response = @app.dispatch_request( request )
         
     | 
| 
      
 43 
     | 
    
         
            +
            	#           #...
         
     | 
| 
      
 44 
     | 
    
         
            +
            	#       end
         
     | 
| 
      
 45 
     | 
    
         
            +
            	#   end
         
     | 
| 
      
 46 
     | 
    
         
            +
            	#
         
     | 
| 
       22 
47 
     | 
    
         
             
            	class RequestFactory
         
     | 
| 
       23 
48 
     | 
    
         
             
            		extend Loggability
         
     | 
| 
       24 
49 
     | 
    
         | 
| 
         @@ -218,14 +243,11 @@ module Mongrel2 
     | 
|
| 
       218 
243 
     | 
    
         
             
            	end # RequestFactory
         
     | 
| 
       219 
244 
     | 
    
         | 
| 
       220 
245 
     | 
    
         | 
| 
       221 
     | 
    
         
            -
            	 
     | 
| 
      
 246 
     | 
    
         
            +
            	# A factory for generating WebSocket request objects for testing.
         
     | 
| 
      
 247 
     | 
    
         
            +
            	#
         
     | 
| 
       222 
248 
     | 
    
         
             
            	class WebSocketFrameFactory < Mongrel2::RequestFactory
         
     | 
| 
       223 
     | 
    
         
            -
            		extend Loggability
         
     | 
| 
       224 
249 
     | 
    
         
             
            		include Mongrel2::Constants
         
     | 
| 
       225 
250 
     | 
    
         | 
| 
       226 
     | 
    
         
            -
            		# Loggability API -- set up logging under the 'mongrel2' log host
         
     | 
| 
       227 
     | 
    
         
            -
            		log_to :mongrel2
         
     | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
251 
     | 
    
         
             
            		# The default host
         
     | 
| 
       230 
252 
     | 
    
         
             
            		DEFAULT_TESTING_HOST  = 'localhost'
         
     | 
| 
       231 
253 
     | 
    
         
             
            		DEFAULT_TESTING_PORT  = '8113'
         
     | 
| 
         @@ -261,6 +283,8 @@ module Mongrel2 
     | 
|
| 
       261 
283 
     | 
    
         
             
            			:headers       => DEFAULT_TESTING_HEADERS,
         
     | 
| 
       262 
284 
     | 
    
         
             
            		}
         
     | 
| 
       263 
285 
     | 
    
         | 
| 
      
 286 
     | 
    
         
            +
            		DEFAULT_HANDSHAKE_BODY = 'GR7M5bFPiY2GvVc5a7CIMErQ18Q='
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
       264 
288 
     | 
    
         
             
            		# Freeze all testing constants
         
     | 
| 
       265 
289 
     | 
    
         
             
            		constants.each do |cname|
         
     | 
| 
       266 
290 
     | 
    
         
             
            			const_get(cname).freeze
         
     | 
| 
         @@ -285,6 +309,26 @@ module Mongrel2 
     | 
|
| 
       285 
309 
     | 
    
         
             
            		public
         
     | 
| 
       286 
310 
     | 
    
         
             
            		######
         
     | 
| 
       287 
311 
     | 
    
         | 
| 
      
 312 
     | 
    
         
            +
            		### Create an initial websocket handshake request and return it.
         
     | 
| 
      
 313 
     | 
    
         
            +
            		def handshake( uri, *subprotocols )
         
     | 
| 
      
 314 
     | 
    
         
            +
            			raise "Request doesn't route through %p" % [ self.route ] unless
         
     | 
| 
      
 315 
     | 
    
         
            +
            				uri.start_with?( self.route )
         
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
      
 317 
     | 
    
         
            +
            			headers = if subprotocols.last.is_a?( Hash ) then subprotocols.pop else {} end
         
     | 
| 
      
 318 
     | 
    
         
            +
            			headers = self.make_merged_headers( uri, 0, headers )
         
     | 
| 
      
 319 
     | 
    
         
            +
            			headers.delete( :flags )
         
     | 
| 
      
 320 
     | 
    
         
            +
             
     | 
| 
      
 321 
     | 
    
         
            +
            			unless subprotocols.empty?
         
     | 
| 
      
 322 
     | 
    
         
            +
            				protos = subprotocols.map( &:to_s ).join( ', ' )
         
     | 
| 
      
 323 
     | 
    
         
            +
            				headers.sec_websocket_protocol = protos
         
     | 
| 
      
 324 
     | 
    
         
            +
            			end
         
     | 
| 
      
 325 
     | 
    
         
            +
             
     | 
| 
      
 326 
     | 
    
         
            +
            			rclass = Mongrel2::Request.subclass_for_method( :WEBSOCKET_HANDSHAKE )
         
     | 
| 
      
 327 
     | 
    
         
            +
             
     | 
| 
      
 328 
     | 
    
         
            +
            			return rclass.new( self.sender_id, self.conn_id.to_s, self.route, headers, DEFAULT_HANDSHAKE_BODY.dup )
         
     | 
| 
      
 329 
     | 
    
         
            +
            		end
         
     | 
| 
      
 330 
     | 
    
         
            +
             
     | 
| 
      
 331 
     | 
    
         
            +
             
     | 
| 
       288 
332 
     | 
    
         
             
            		### Create a new request with the specified +uri+, +data+, and +flags+.
         
     | 
| 
       289 
333 
     | 
    
         
             
            		def create( uri, data, *flags )
         
     | 
| 
       290 
334 
     | 
    
         
             
            			raise "Request doesn't route through %p" % [ self.route ] unless
         
     | 
    
        data/lib/mongrel2/websocket.rb
    CHANGED
    
    | 
         @@ -9,6 +9,11 @@ require 'mongrel2/constants' 
     | 
|
| 
       9 
9 
     | 
    
         
             
            #
         
     | 
| 
       10 
10 
     | 
    
         
             
            #   class WebSocketEchoServer
         
     | 
| 
       11 
11 
     | 
    
         
             
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            #       def handle_websocket_handshake( handshake )
         
     | 
| 
      
 13 
     | 
    
         
            +
            #           # :TODO: Sub-protocol/protocol version checks?
         
     | 
| 
      
 14 
     | 
    
         
            +
            #           return handshake.response
         
     | 
| 
      
 15 
     | 
    
         
            +
            #       end
         
     | 
| 
      
 16 
     | 
    
         
            +
            #
         
     | 
| 
       12 
17 
     | 
    
         
             
            #       def handle_websocket( frame )
         
     | 
| 
       13 
18 
     | 
    
         
             
            #
         
     | 
| 
       14 
19 
     | 
    
         
             
            #           # Close connections that send invalid frames
         
     | 
| 
         @@ -191,6 +196,93 @@ module Mongrel2::WebSocket 
     | 
|
| 
       191 
196 
     | 
    
         
             
            	# Exception raised when a frame is malformed, doesn't parse, or is otherwise invalid.
         
     | 
| 
       192 
197 
     | 
    
         
             
            	class FrameError < Mongrel2::WebSocket::Error; end
         
     | 
| 
       193 
198 
     | 
    
         | 
| 
      
 199 
     | 
    
         
            +
            	# Exception raised when a handshake is created with an unrequested sub-protocol.
         
     | 
| 
      
 200 
     | 
    
         
            +
            	class HandshakeError < Mongrel2::WebSocket::Error; end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
            	# The client (request) handshake for a WebSocket opening handshake.
         
     | 
| 
      
 204 
     | 
    
         
            +
            	class ClientHandshake < Mongrel2::HTTPRequest
         
     | 
| 
      
 205 
     | 
    
         
            +
            		include Mongrel2::WebSocket::Constants
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
            		# Set this class as the one that will handle WEBSOCKET_HANDSHAKE requests
         
     | 
| 
      
 208 
     | 
    
         
            +
            		register_request_type( self, :WEBSOCKET_HANDSHAKE )
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
            		### Override the type of response returned by this request type. Since
         
     | 
| 
      
 212 
     | 
    
         
            +
            		### websocket handshakes are symmetrical, responses are just new
         
     | 
| 
      
 213 
     | 
    
         
            +
            		### Mongrel2::WebSocket::Handshakes with the same Mongrel2 sender
         
     | 
| 
      
 214 
     | 
    
         
            +
            		### and connection IDs.
         
     | 
| 
      
 215 
     | 
    
         
            +
            		def self::response_class
         
     | 
| 
      
 216 
     | 
    
         
            +
            			return Mongrel2::WebSocket::ServerHandshake
         
     | 
| 
      
 217 
     | 
    
         
            +
            		end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
            		######
         
     | 
| 
      
 221 
     | 
    
         
            +
            		public
         
     | 
| 
      
 222 
     | 
    
         
            +
            		######
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            		### The list of protocols in the handshake's Sec-WebSocket-Protocol header
         
     | 
| 
      
 225 
     | 
    
         
            +
            		### as an Array of Strings.
         
     | 
| 
      
 226 
     | 
    
         
            +
            		def protocols
         
     | 
| 
      
 227 
     | 
    
         
            +
            			return ( self.headers.sec_websocket_protocol || '' ).split( /\s*,\s*/ )
         
     | 
| 
      
 228 
     | 
    
         
            +
            		end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
            		### Create a Mongrel2::WebSocket::Handshake that will respond to the same server/connection as
         
     | 
| 
      
 232 
     | 
    
         
            +
            		### the receiver.
         
     | 
| 
      
 233 
     | 
    
         
            +
            		def response( protocol=nil )
         
     | 
| 
      
 234 
     | 
    
         
            +
            			@response = super() unless @response
         
     | 
| 
      
 235 
     | 
    
         
            +
            			if protocol
         
     | 
| 
      
 236 
     | 
    
         
            +
            				raise Mongrel2::WebSocket::HandshakeError,
         
     | 
| 
      
 237 
     | 
    
         
            +
            					"attempt to create a %s handshake which isn't supported by the client." %
         
     | 
| 
      
 238 
     | 
    
         
            +
            					[ protocol ] unless self.protocols.include?( protocol.to_s )
         
     | 
| 
      
 239 
     | 
    
         
            +
            				@response.protocols = protocol
         
     | 
| 
      
 240 
     | 
    
         
            +
            			end
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
            			return @response
         
     | 
| 
      
 243 
     | 
    
         
            +
            		end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
            	end # class ClientHandshake
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
            	# The server (response) handshake for a WebSocket opening handshake.
         
     | 
| 
      
 249 
     | 
    
         
            +
            	class ServerHandshake < Mongrel2::HTTPResponse
         
     | 
| 
      
 250 
     | 
    
         
            +
            		include Mongrel2::WebSocket::Constants
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
            		### Create a server handshake frame from the given client +handshake+.
         
     | 
| 
      
 253 
     | 
    
         
            +
            		def self::from_request( handshake )
         
     | 
| 
      
 254 
     | 
    
         
            +
            			self.log.debug "Creating the server handshake for client handshake %p" % [ handshake ]
         
     | 
| 
      
 255 
     | 
    
         
            +
            			response = super
         
     | 
| 
      
 256 
     | 
    
         
            +
            			response.body.truncate( 0 )
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
            			# Mongrel2 puts the negotiated key in the body of the request
         
     | 
| 
      
 259 
     | 
    
         
            +
            			response.headers.sec_websocket_accept = handshake.body.read
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
            			# Set up the other typical server handshake values
         
     | 
| 
      
 262 
     | 
    
         
            +
            			response.status = HTTP::SWITCHING_PROTOCOLS
         
     | 
| 
      
 263 
     | 
    
         
            +
            			response.header.upgrade = 'websocket'
         
     | 
| 
      
 264 
     | 
    
         
            +
            			response.header.connection = 'Upgrade'
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
      
 266 
     | 
    
         
            +
            			return response
         
     | 
| 
      
 267 
     | 
    
         
            +
            		end
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
            		### The list of protocols in the handshake's Sec-WebSocket-Protocol header
         
     | 
| 
      
 271 
     | 
    
         
            +
            		### as an Array of Strings.
         
     | 
| 
      
 272 
     | 
    
         
            +
            		def protocols
         
     | 
| 
      
 273 
     | 
    
         
            +
            			return ( self.headers.sec_websocket_protocol || '' ).split( /\s*,\s*/ )
         
     | 
| 
      
 274 
     | 
    
         
            +
            		end
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
            		### Set the list of protocols in the handshake's Sec-WebSocket-Protocol header.
         
     | 
| 
      
 278 
     | 
    
         
            +
            		def protocols=( new_protocols )
         
     | 
| 
      
 279 
     | 
    
         
            +
            			value = Array( new_protocols ).join( ', ' )
         
     | 
| 
      
 280 
     | 
    
         
            +
            			self.headers.sec_websocket_protocol = value
         
     | 
| 
      
 281 
     | 
    
         
            +
            		end
         
     | 
| 
      
 282 
     | 
    
         
            +
             
     | 
| 
      
 283 
     | 
    
         
            +
             
     | 
| 
      
 284 
     | 
    
         
            +
            	end # class ServerHandshake
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
       194 
286 
     | 
    
         | 
| 
       195 
287 
     | 
    
         
             
            	# WebSocket frame class; this is used for both requests and responses in
         
     | 
| 
       196 
288 
     | 
    
         
             
            	# WebSocket services.
         
     | 
| 
         @@ -207,7 +299,8 @@ module Mongrel2::WebSocket 
     | 
|
| 
       207 
299 
     | 
    
         | 
| 
       208 
300 
     | 
    
         
             
            		### Override the type of response returned by this request type. Since
         
     | 
| 
       209 
301 
     | 
    
         
             
            		### WebSocket connections are symmetrical, responses are just new
         
     | 
| 
       210 
     | 
    
         
            -
            		###  
     | 
| 
      
 302 
     | 
    
         
            +
            		### Mongrel2::WebSocket::Frames with the same Mongrel2 sender and
         
     | 
| 
      
 303 
     | 
    
         
            +
            		### connection IDs.
         
     | 
| 
       211 
304 
     | 
    
         
             
            		def self::response_class
         
     | 
| 
       212 
305 
     | 
    
         
             
            			return self
         
     | 
| 
       213 
306 
     | 
    
         
             
            		end
         
     | 
| 
         @@ -448,10 +541,13 @@ module Mongrel2::WebSocket 
     | 
|
| 
       448 
541 
     | 
    
         
             
            		end
         
     | 
| 
       449 
542 
     | 
    
         | 
| 
       450 
543 
     | 
    
         | 
| 
       451 
     | 
    
         
            -
            		### Create a  
     | 
| 
       452 
     | 
    
         
            -
            		###  
     | 
| 
       453 
     | 
    
         
            -
            		###  
     | 
| 
       454 
     | 
    
         
            -
            		###  
     | 
| 
      
 544 
     | 
    
         
            +
            		### Create a frame in response to the receiving Frame (i.e., with the same
         
     | 
| 
      
 545 
     | 
    
         
            +
            		### Mongrel2 connection ID and sender). This automatically sets up the correct
         
     | 
| 
      
 546 
     | 
    
         
            +
            		### status, Sec-WebSocket-Accept:, Connection, and Upgrade: headers based on the
         
     | 
| 
      
 547 
     | 
    
         
            +
            		### receiver. If +protocol+ is non-nil, and it matches one of the
         
     | 
| 
      
 548 
     | 
    
         
            +
            		### values listed in 'Sec-WebSocket-Protocol', it will be set as the
         
     | 
| 
      
 549 
     | 
    
         
            +
            		### Handshake's Sec-WebSocket-Protocol header. If it is non-nil, but doesn't
         
     | 
| 
      
 550 
     | 
    
         
            +
            		### match one of the request's values, a Mongrel2::WebSocket::Error is raised.
         
     | 
| 
       455 
551 
     | 
    
         
             
            		def response( *flags )
         
     | 
| 
       456 
552 
     | 
    
         
             
            			unless @response
         
     | 
| 
       457 
553 
     | 
    
         
             
            				@response = super()
         
     | 
    
        data/spec/lib/constants.rb
    CHANGED
    
    | 
         @@ -109,6 +109,54 @@ module Mongrel2::TestConstants # :nodoc:all 
     | 
|
| 
       109 
109 
     | 
    
         
             
            		}
         
     | 
| 
       110 
110 
     | 
    
         | 
| 
       111 
111 
     | 
    
         | 
| 
      
 112 
     | 
    
         
            +
            		#
         
     | 
| 
      
 113 
     | 
    
         
            +
            		# WebSocket frame constants
         
     | 
| 
      
 114 
     | 
    
         
            +
            		#
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            		TEST_WEBSOCKET_PATH = '/ws'
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            		TEST_WEBSOCKET_HEADERS = {
         
     | 
| 
      
 119 
     | 
    
         
            +
            			 'connection'               => 'Upgrade',
         
     | 
| 
      
 120 
     | 
    
         
            +
            			 'FLAGS'                    => '0x8A',
         
     | 
| 
      
 121 
     | 
    
         
            +
            			 'host'                     => 'host.example.com:80',
         
     | 
| 
      
 122 
     | 
    
         
            +
            			 'METHOD'                   => 'WEBSOCKET',
         
     | 
| 
      
 123 
     | 
    
         
            +
            			 'origin'                   => 'http://host.example.com:80',
         
     | 
| 
      
 124 
     | 
    
         
            +
            			 'PATH'                     => TEST_WEBSOCKET_PATH,
         
     | 
| 
      
 125 
     | 
    
         
            +
            			 'PATTERN'                  => TEST_WEBSOCKET_PATH,
         
     | 
| 
      
 126 
     | 
    
         
            +
            			 'sec-websocket-extensions' => 'x-webkit-deflate-frame',
         
     | 
| 
      
 127 
     | 
    
         
            +
            			 'sec-websocket-key'        => 'SQvDVdT2SbgTg6P/lSZo7Q==',
         
     | 
| 
      
 128 
     | 
    
         
            +
            			 'sec-websocket-protocol'   => 'echo',
         
     | 
| 
      
 129 
     | 
    
         
            +
            			 'sec-websocket-version'    => '13',
         
     | 
| 
      
 130 
     | 
    
         
            +
            			 'upgrade'                  => 'websocket',
         
     | 
| 
      
 131 
     | 
    
         
            +
            			 'URI'                      => TEST_WEBSOCKET_PATH,
         
     | 
| 
      
 132 
     | 
    
         
            +
            			 'VERSION'                  => 'HTTP/1.1',
         
     | 
| 
      
 133 
     | 
    
         
            +
            			 'x-forwarded-for'          => '127.0.0.2',
         
     | 
| 
      
 134 
     | 
    
         
            +
            		}
         
     | 
| 
      
 135 
     | 
    
         
            +
            		TEST_WEBSOCKET_HANDSHAKE_HEADERS = {
         
     | 
| 
      
 136 
     | 
    
         
            +
            			'connection'               => 'Upgrade',
         
     | 
| 
      
 137 
     | 
    
         
            +
            			'host'                     => 'host.example.com:80',
         
     | 
| 
      
 138 
     | 
    
         
            +
            			'METHOD'                   => 'WEBSOCKET_HANDSHAKE',
         
     | 
| 
      
 139 
     | 
    
         
            +
            			'origin'                   => 'http://host.example.com:80',
         
     | 
| 
      
 140 
     | 
    
         
            +
            			'PATH'                     => TEST_WEBSOCKET_PATH,
         
     | 
| 
      
 141 
     | 
    
         
            +
            			'PATTERN'                  => TEST_WEBSOCKET_PATH,
         
     | 
| 
      
 142 
     | 
    
         
            +
            			'sec-websocket-extensions' => 'x-webkit-deflate-frame',
         
     | 
| 
      
 143 
     | 
    
         
            +
            			'sec-websocket-key'        => 'SQvDVdT2SbgTg6P/lSZo7Q==',
         
     | 
| 
      
 144 
     | 
    
         
            +
            			'sec-websocket-protocol'   => 'echo',
         
     | 
| 
      
 145 
     | 
    
         
            +
            			'sec-websocket-version'    => '13',
         
     | 
| 
      
 146 
     | 
    
         
            +
            			'upgrade'                  => 'websocket',
         
     | 
| 
      
 147 
     | 
    
         
            +
            			'URI'                      => TEST_WEBSOCKET_PATH,
         
     | 
| 
      
 148 
     | 
    
         
            +
            			'VERSION'                  => 'HTTP/1.1',
         
     | 
| 
      
 149 
     | 
    
         
            +
            			'x-forwarded-for'          => '127.0.0.2',
         
     | 
| 
      
 150 
     | 
    
         
            +
            		}
         
     | 
| 
      
 151 
     | 
    
         
            +
            		TEST_WEBSOCKET_BODY = 'GR7M5bFPiY2GvVc5a7CIMErQ18Q='
         
     | 
| 
      
 152 
     | 
    
         
            +
            		TEST_WEBSOCKET_REQUEST_OPTS = {
         
     | 
| 
      
 153 
     | 
    
         
            +
            			:uuid    => TEST_UUID,
         
     | 
| 
      
 154 
     | 
    
         
            +
            			:id      => TEST_ID,
         
     | 
| 
      
 155 
     | 
    
         
            +
            			:path    => TEST_WEBSOCKET_PATH,
         
     | 
| 
      
 156 
     | 
    
         
            +
            			:body    => '',
         
     | 
| 
      
 157 
     | 
    
         
            +
            		}
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
       112 
160 
     | 
    
         
             
            		#
         
     | 
| 
       113 
161 
     | 
    
         
             
            		# HTTP constants
         
     | 
| 
       114 
162 
     | 
    
         
             
            		#
         
     | 
    
        data/spec/lib/helpers.rb
    CHANGED
    
    | 
         @@ -114,13 +114,14 @@ module Mongrel2::SpecHelpers 
     | 
|
| 
       114 
114 
     | 
    
         
             
            		bodystring = TNetstring.dump( opts[:body] || '' )
         
     | 
| 
       115 
115 
     | 
    
         | 
| 
       116 
116 
     | 
    
         
             
            		# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
         
     | 
| 
       117 
     | 
    
         
            -
            		 
     | 
| 
      
 117 
     | 
    
         
            +
            		data = "%s %d %s %s%s" % [
         
     | 
| 
       118 
118 
     | 
    
         
             
            			opts[:uuid],
         
     | 
| 
       119 
119 
     | 
    
         
             
            			opts[:id],
         
     | 
| 
       120 
120 
     | 
    
         
             
            			opts[:path],
         
     | 
| 
       121 
121 
     | 
    
         
             
            			headerstring,
         
     | 
| 
       122 
122 
     | 
    
         
             
            			bodystring,
         
     | 
| 
       123 
123 
     | 
    
         
             
            		]
         
     | 
| 
      
 124 
     | 
    
         
            +
            		return data.encode( 'binary' )
         
     | 
| 
       124 
125 
     | 
    
         
             
            	end
         
     | 
| 
       125 
126 
     | 
    
         | 
| 
       126 
127 
     | 
    
         | 
| 
         @@ -134,13 +135,14 @@ module Mongrel2::SpecHelpers 
     | 
|
| 
       134 
135 
     | 
    
         
             
            		bodystring = TNetstring.dump( opts[:body] || '' )
         
     | 
| 
       135 
136 
     | 
    
         | 
| 
       136 
137 
     | 
    
         
             
            		# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
         
     | 
| 
       137 
     | 
    
         
            -
            		 
     | 
| 
      
 138 
     | 
    
         
            +
            		data = "%s %d %s %s%s" % [
         
     | 
| 
       138 
139 
     | 
    
         
             
            			opts[:uuid],
         
     | 
| 
       139 
140 
     | 
    
         
             
            			opts[:id],
         
     | 
| 
       140 
141 
     | 
    
         
             
            			opts[:path],
         
     | 
| 
       141 
142 
     | 
    
         
             
            			headerstring,
         
     | 
| 
       142 
143 
     | 
    
         
             
            			bodystring,
         
     | 
| 
       143 
144 
     | 
    
         
             
            		]
         
     | 
| 
      
 145 
     | 
    
         
            +
            		return data.encode( 'binary' )
         
     | 
| 
       144 
146 
     | 
    
         
             
            	end
         
     | 
| 
       145 
147 
     | 
    
         | 
| 
       146 
148 
     | 
    
         | 
| 
         @@ -156,13 +158,14 @@ module Mongrel2::SpecHelpers 
     | 
|
| 
       156 
158 
     | 
    
         
             
            		bodystring = TNetstring.dump( Yajl::Encoder.encode(opts[:body] || []) )
         
     | 
| 
       157 
159 
     | 
    
         | 
| 
       158 
160 
     | 
    
         
             
            		# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
         
     | 
| 
       159 
     | 
    
         
            -
            		 
     | 
| 
      
 161 
     | 
    
         
            +
            		data = "%s %d %s %s%s" % [
         
     | 
| 
       160 
162 
     | 
    
         
             
            			opts[:uuid],
         
     | 
| 
       161 
163 
     | 
    
         
             
            			opts[:id],
         
     | 
| 
       162 
164 
     | 
    
         
             
            			opts[:path],
         
     | 
| 
       163 
165 
     | 
    
         
             
            			headerstring,
         
     | 
| 
       164 
166 
     | 
    
         
             
            			bodystring,
         
     | 
| 
       165 
167 
     | 
    
         
             
            		]
         
     | 
| 
      
 168 
     | 
    
         
            +
            		return data.encode( 'binary' )
         
     | 
| 
       166 
169 
     | 
    
         
             
            	end
         
     | 
| 
       167 
170 
     | 
    
         | 
| 
       168 
171 
     | 
    
         | 
| 
         @@ -178,13 +181,56 @@ module Mongrel2::SpecHelpers 
     | 
|
| 
       178 
181 
     | 
    
         
             
            		bodystring = TNetstring.dump( opts[:body] || "#{TEST_XML_PATH} />" )
         
     | 
| 
       179 
182 
     | 
    
         | 
| 
       180 
183 
     | 
    
         
             
            		# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
         
     | 
| 
       181 
     | 
    
         
            -
            		 
     | 
| 
      
 184 
     | 
    
         
            +
            		data = "%s %d %s %s%s" % [
         
     | 
| 
       182 
185 
     | 
    
         
             
            			opts[:uuid],
         
     | 
| 
       183 
186 
     | 
    
         
             
            			opts[:id],
         
     | 
| 
       184 
187 
     | 
    
         
             
            			opts[:path],
         
     | 
| 
       185 
188 
     | 
    
         
             
            			headerstring,
         
     | 
| 
       186 
189 
     | 
    
         
             
            			bodystring,
         
     | 
| 
       187 
190 
     | 
    
         
             
            		]
         
     | 
| 
      
 191 
     | 
    
         
            +
            		return data.encode( 'binary' )
         
     | 
| 
      
 192 
     | 
    
         
            +
            	end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            	### Make a Mongrel2 handshake request for a WebSocket route.
         
     | 
| 
      
 195 
     | 
    
         
            +
            	def make_websocket_handshake( opts={} )
         
     | 
| 
      
 196 
     | 
    
         
            +
            		opts = TEST_WEBSOCKET_REQUEST_OPTS.merge( opts )
         
     | 
| 
      
 197 
     | 
    
         
            +
            		headers = normalize_headers( opts, TEST_WEBSOCKET_HANDSHAKE_HEADERS )
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
            		Mongrel2.log.debug "WebSocket start handshake, headers = %p, opts = %p" % [ headers, opts ]
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
            		headerstring = TNetstring.dump( Yajl::Encoder.encode(headers) )
         
     | 
| 
      
 202 
     | 
    
         
            +
            		bodystring = TNetstring.dump( opts[:body] || TEST_WEBSOCKET_BODY )
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
            		# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
         
     | 
| 
      
 205 
     | 
    
         
            +
            		data = "%s %d %s %s%s" % [
         
     | 
| 
      
 206 
     | 
    
         
            +
            			opts[:uuid],
         
     | 
| 
      
 207 
     | 
    
         
            +
            			opts[:id],
         
     | 
| 
      
 208 
     | 
    
         
            +
            			opts[:path],
         
     | 
| 
      
 209 
     | 
    
         
            +
            			headerstring,
         
     | 
| 
      
 210 
     | 
    
         
            +
            			bodystring,
         
     | 
| 
      
 211 
     | 
    
         
            +
            		]
         
     | 
| 
      
 212 
     | 
    
         
            +
            		return data.encode( 'binary' )
         
     | 
| 
      
 213 
     | 
    
         
            +
            	end
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
            	### Make a Mongrel2 frame for a WebSocket route.
         
     | 
| 
      
 216 
     | 
    
         
            +
            	def make_websocket_frame( opts={} )
         
     | 
| 
      
 217 
     | 
    
         
            +
            		opts = TEST_WEBSOCKET_REQUEST_OPTS.merge( opts )
         
     | 
| 
      
 218 
     | 
    
         
            +
            		headers = normalize_headers( opts, TEST_WEBSOCKET_HEADERS )
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
            		Mongrel2.log.debug "WebSocket frame, headers = %p, opts = %p" % [ headers, opts ]
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
            		headerstring = TNetstring.dump( Yajl::Encoder.encode(headers) )
         
     | 
| 
      
 223 
     | 
    
         
            +
            		bodystring = TNetstring.dump( opts[:body] )
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
            		# UUID ID PATH SIZE:HEADERS,SIZE:BODY,
         
     | 
| 
      
 226 
     | 
    
         
            +
            		data = "%s %d %s %s%s" % [
         
     | 
| 
      
 227 
     | 
    
         
            +
            			opts[:uuid],
         
     | 
| 
      
 228 
     | 
    
         
            +
            			opts[:id],
         
     | 
| 
      
 229 
     | 
    
         
            +
            			opts[:path],
         
     | 
| 
      
 230 
     | 
    
         
            +
            			headerstring,
         
     | 
| 
      
 231 
     | 
    
         
            +
            			bodystring,
         
     | 
| 
      
 232 
     | 
    
         
            +
            		]
         
     | 
| 
      
 233 
     | 
    
         
            +
            		return data.encode( 'binary' )
         
     | 
| 
       188 
234 
     | 
    
         
             
            	end
         
     | 
| 
       189 
235 
     | 
    
         | 
| 
       190 
236 
     | 
    
         
             
            end
         
     | 
| 
         @@ -209,6 +209,42 @@ describe Mongrel2::Handler do 
     | 
|
| 
       209 
209 
     | 
    
         
             
            		response.should be_a( Mongrel2::Response )
         
     | 
| 
       210 
210 
     | 
    
         
             
            	end
         
     | 
| 
       211 
211 
     | 
    
         | 
| 
      
 212 
     | 
    
         
            +
            	it "dispatches WebSocket opening handshakes to the #handle_websocket_handshake method" do
         
     | 
| 
      
 213 
     | 
    
         
            +
            		ws_handler = Class.new( OneShotHandler ) do
         
     | 
| 
      
 214 
     | 
    
         
            +
            			def handle_websocket_handshake( handshake )
         
     | 
| 
      
 215 
     | 
    
         
            +
            				return handshake.response
         
     | 
| 
      
 216 
     | 
    
         
            +
            			end
         
     | 
| 
      
 217 
     | 
    
         
            +
            		end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
            		req = make_websocket_handshake()
         
     | 
| 
      
 220 
     | 
    
         
            +
            		@request_sock.should_receive( :recv ).and_return( req )
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
            		res = ws_handler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC ).run
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            		res.transactions.should have( 1 ).member
         
     | 
| 
      
 225 
     | 
    
         
            +
            		request, response = res.transactions.first
         
     | 
| 
      
 226 
     | 
    
         
            +
            		request.should be_a( Mongrel2::WebSocket::ClientHandshake )
         
     | 
| 
      
 227 
     | 
    
         
            +
            		response.should be_a( Mongrel2::WebSocket::ServerHandshake )
         
     | 
| 
      
 228 
     | 
    
         
            +
            	end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
            	it "dispatches WebSocket protocol frames to the #handle_websocket method" do
         
     | 
| 
      
 231 
     | 
    
         
            +
            		ws_handler = Class.new( OneShotHandler ) do
         
     | 
| 
      
 232 
     | 
    
         
            +
            			def handle_websocket( frame )
         
     | 
| 
      
 233 
     | 
    
         
            +
            				return frame.response
         
     | 
| 
      
 234 
     | 
    
         
            +
            			end
         
     | 
| 
      
 235 
     | 
    
         
            +
            		end
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
            		req = make_websocket_frame()
         
     | 
| 
      
 238 
     | 
    
         
            +
            		@request_sock.should_receive( :recv ).and_return( req )
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
      
 240 
     | 
    
         
            +
            		res = ws_handler.new( TEST_UUID, TEST_SEND_SPEC, TEST_RECV_SPEC ).run
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
            		res.transactions.should have( 1 ).member
         
     | 
| 
      
 243 
     | 
    
         
            +
            		request, response = res.transactions.first
         
     | 
| 
      
 244 
     | 
    
         
            +
            		request.should be_a( Mongrel2::WebSocket::Frame )
         
     | 
| 
      
 245 
     | 
    
         
            +
            		response.should be_a( Mongrel2::WebSocket::Frame )
         
     | 
| 
      
 246 
     | 
    
         
            +
            	end
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
       212 
248 
     | 
    
         
             
            	it "continues when a ZMQ::Error is received but the connection remains open" do
         
     | 
| 
       213 
249 
     | 
    
         
             
            		req = make_request()
         
     | 
| 
       214 
250 
     | 
    
         | 
| 
         @@ -55,7 +55,7 @@ describe Mongrel2::HTTPResponse do 
     | 
|
| 
       55 
55 
     | 
    
         
             
            	it "returns an empty response if its status is set to NO_CONTENT" do
         
     | 
| 
       56 
56 
     | 
    
         
             
            		@response.puts "The response body"
         
     | 
| 
       57 
57 
     | 
    
         
             
            		@response.status = HTTP::NO_CONTENT
         
     | 
| 
       58 
     | 
    
         
            -
            		@response.header_data. 
     | 
| 
      
 58 
     | 
    
         
            +
            		@response.header_data.should_not =~ /Content-length/i
         
     | 
| 
       59 
59 
     | 
    
         
             
            		@response.header_data.should_not =~ /Content-type/i
         
     | 
| 
       60 
60 
     | 
    
         
             
            		@response.to_s.should_not =~ /The response body/i
         
     | 
| 
       61 
61 
     | 
    
         
             
            	end
         
     | 
| 
         @@ -69,9 +69,10 @@ describe Mongrel2::HTTPResponse do 
     | 
|
| 
       69 
69 
     | 
    
         
             
            	end
         
     | 
| 
       70 
70 
     | 
    
         | 
| 
       71 
71 
     | 
    
         
             
            	it "re-calculates the automatically-added headers when re-rendered" do
         
     | 
| 
       72 
     | 
    
         
            -
            		@response.header_data.should =~ /Content-length: 0/i
         
     | 
| 
      
 72 
     | 
    
         
            +
            		@response.header_data.should =~ /Content-length: 0\b/i
         
     | 
| 
      
 73 
     | 
    
         
            +
            		@response.status = HTTP::OK
         
     | 
| 
       73 
74 
     | 
    
         
             
            		@response << "More data!"
         
     | 
| 
       74 
     | 
    
         
            -
            		@response.header_data.should =~ /Content-length: 10/i
         
     | 
| 
      
 75 
     | 
    
         
            +
            		@response.header_data.should =~ /Content-length: 10\b/i
         
     | 
| 
       75 
76 
     | 
    
         
             
            	end
         
     | 
| 
       76 
77 
     | 
    
         | 
| 
       77 
78 
     | 
    
         
             
            	it "doesn't have a body" do
         
     | 
| 
         @@ -53,6 +53,69 @@ describe Mongrel2::WebSocket do 
     | 
|
| 
       53 
53 
     | 
    
         
             
            	BINARY_DATA.force_encoding( Encoding::ASCII_8BIT )
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         | 
| 
      
 56 
     | 
    
         
            +
            	describe 'ClientHandshake' do
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            		it "is the registered request type for WEBSOCKET_HANDSHAKE requests" do
         
     | 
| 
      
 59 
     | 
    
         
            +
            			Mongrel2::Request.request_types[:WEBSOCKET_HANDSHAKE].should == Mongrel2::WebSocket::ClientHandshake
         
     | 
| 
      
 60 
     | 
    
         
            +
            		end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            		it "knows what subprotocols were requested" do
         
     | 
| 
      
 63 
     | 
    
         
            +
            			handshake = @factory.handshake( '/websock', 'echo', 'superecho' )
         
     | 
| 
      
 64 
     | 
    
         
            +
            			handshake.protocols.should == ['echo', 'superecho']
         
     | 
| 
      
 65 
     | 
    
         
            +
            		end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
            		it "doesn't error if no subprotocols were requested" do
         
     | 
| 
      
 68 
     | 
    
         
            +
            			handshake = @factory.handshake( '/websock' )
         
     | 
| 
      
 69 
     | 
    
         
            +
            			handshake.protocols.should == []
         
     | 
| 
      
 70 
     | 
    
         
            +
            		end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            		it "can create a response WebSocket::ServerHandshake for itself" do
         
     | 
| 
      
 73 
     | 
    
         
            +
            			handshake = @factory.handshake( '/websock' )
         
     | 
| 
      
 74 
     | 
    
         
            +
            			result = handshake.response
         
     | 
| 
      
 75 
     | 
    
         
            +
            			handshake.body.rewind
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            			result.should be_a( Mongrel2::WebSocket::ServerHandshake )
         
     | 
| 
      
 78 
     | 
    
         
            +
            			result.sender_id.should == handshake.sender_id
         
     | 
| 
      
 79 
     | 
    
         
            +
            			result.conn_id.should == handshake.conn_id
         
     | 
| 
      
 80 
     | 
    
         
            +
            			result.header.sec_websocket_accept.should == handshake.body.string
         
     | 
| 
      
 81 
     | 
    
         
            +
            			result.status.should == HTTP::SWITCHING_PROTOCOLS
         
     | 
| 
      
 82 
     | 
    
         
            +
            			result.header.connection.should =~ /upgrade/i
         
     | 
| 
      
 83 
     | 
    
         
            +
            			result.header.upgrade.should =~ /websocket/i
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            			result.body.rewind
         
     | 
| 
      
 86 
     | 
    
         
            +
            			result.body.read.should == ''
         
     | 
| 
      
 87 
     | 
    
         
            +
            		end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            		it "can create a response WebSocket::ServerHandshake with a valid sub-protocol for itself" do
         
     | 
| 
      
 90 
     | 
    
         
            +
            			handshake = @factory.handshake( '/websock', 'echo', 'superecho' )
         
     | 
| 
      
 91 
     | 
    
         
            +
            			result = handshake.response( :superecho )
         
     | 
| 
      
 92 
     | 
    
         
            +
            			handshake.body.rewind
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            			result.should be_a( Mongrel2::WebSocket::ServerHandshake )
         
     | 
| 
      
 95 
     | 
    
         
            +
            			result.sender_id.should == handshake.sender_id
         
     | 
| 
      
 96 
     | 
    
         
            +
            			result.conn_id.should == handshake.conn_id
         
     | 
| 
      
 97 
     | 
    
         
            +
            			result.header.sec_websocket_accept.should == handshake.body.string
         
     | 
| 
      
 98 
     | 
    
         
            +
            			result.status.should == HTTP::SWITCHING_PROTOCOLS
         
     | 
| 
      
 99 
     | 
    
         
            +
            			result.header.connection.should =~ /upgrade/i
         
     | 
| 
      
 100 
     | 
    
         
            +
            			result.header.upgrade.should =~ /websocket/i
         
     | 
| 
      
 101 
     | 
    
         
            +
            			result.protocols.should == ['superecho']
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            			result.body.rewind
         
     | 
| 
      
 104 
     | 
    
         
            +
            			result.body.read.should == ''
         
     | 
| 
      
 105 
     | 
    
         
            +
            		end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            		it "raises an exception if the specified protocol is not one of the client's advertised ones" do
         
     | 
| 
      
 108 
     | 
    
         
            +
            			handshake = @factory.handshake( '/websock', 'echo', 'superecho' )
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            			expect {
         
     | 
| 
      
 111 
     | 
    
         
            +
            				handshake.response( :map_updates )
         
     | 
| 
      
 112 
     | 
    
         
            +
            			}.to raise_error( Mongrel2::WebSocket::HandshakeError, /map_updates/i )
         
     | 
| 
      
 113 
     | 
    
         
            +
            		end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            	end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
       56 
119 
     | 
    
         
             
            	describe 'Frame' do
         
     | 
| 
       57 
120 
     | 
    
         | 
| 
       58 
121 
     | 
    
         
             
            		it "is the registered request type for WEBSOCKET requests" do
         
     | 
| 
         @@ -310,5 +373,6 @@ describe Mongrel2::WebSocket do 
     | 
|
| 
       310 
373 
     | 
    
         | 
| 
       311 
374 
     | 
    
         
             
            	end
         
     | 
| 
       312 
375 
     | 
    
         | 
| 
      
 376 
     | 
    
         
            +
             
     | 
| 
       313 
377 
     | 
    
         
             
            end
         
     | 
| 
       314 
378 
     | 
    
         | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: mongrel2
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.27.0
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       7 
7 
     | 
    
         
             
            authors:
         
     | 
| 
         @@ -36,7 +36,7 @@ cert_chain: 
     | 
|
| 
       36 
36 
     | 
    
         
             
              YUhDS0xaZFNLai9SSHVUT3QrZ2JsUmV4OEZBaDhOZUEKY21saFhlNDZwWk5K
         
     | 
| 
       37 
37 
     | 
    
         
             
              Z1dLYnhaYWg4NWpJang5NWhSOHZPSStOQU01aUg5a09xSzEzRHJ4YWNUS1Bo
         
     | 
| 
       38 
38 
     | 
    
         
             
              cWo1UGp3RgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
         
     | 
| 
       39 
     | 
    
         
            -
            date: 2012- 
     | 
| 
      
 39 
     | 
    
         
            +
            date: 2012-07-02 00:00:00.000000000 Z
         
     | 
| 
       40 
40 
     | 
    
         
             
            dependencies:
         
     | 
| 
       41 
41 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       42 
42 
     | 
    
         
             
              name: nokogiri
         
     | 
| 
         @@ -328,6 +328,7 @@ files: 
     | 
|
| 
       328 
328 
     | 
    
         
             
            - Rakefile
         
     | 
| 
       329 
329 
     | 
    
         
             
            - bin/m2sh.rb
         
     | 
| 
       330 
330 
     | 
    
         
             
            - data/mongrel2/bootstrap.html
         
     | 
| 
      
 331 
     | 
    
         
            +
            - data/mongrel2/config.rb.in
         
     | 
| 
       331 
332 
     | 
    
         
             
            - data/mongrel2/config.sql
         
     | 
| 
       332 
333 
     | 
    
         
             
            - data/mongrel2/css/master.css
         
     | 
| 
       333 
334 
     | 
    
         
             
            - data/mongrel2/js/websock-test.js
         
     | 
    
        metadata.gz.sig
    CHANGED
    
    | 
         Binary file 
     |