webrick 1.3.1 → 1.5.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.
Potentially problematic release.
This version of webrick might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +63 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/webrick/accesslog.rb +9 -1
- data/lib/webrick/cgi.rb +58 -5
- data/lib/webrick/compat.rb +2 -1
- data/lib/webrick/config.rb +47 -10
- data/lib/webrick/cookie.rb +69 -7
- data/lib/webrick/htmlutils.rb +4 -2
- data/lib/webrick/httpauth/authenticator.rb +13 -8
- data/lib/webrick/httpauth/basicauth.rb +16 -8
- data/lib/webrick/httpauth/digestauth.rb +35 -32
- data/lib/webrick/httpauth/htdigest.rb +12 -8
- data/lib/webrick/httpauth/htgroup.rb +10 -6
- data/lib/webrick/httpauth/htpasswd.rb +46 -9
- data/lib/webrick/httpauth/userdb.rb +1 -0
- data/lib/webrick/httpauth.rb +6 -5
- data/lib/webrick/httpproxy.rb +93 -48
- data/lib/webrick/httprequest.rb +192 -27
- data/lib/webrick/httpresponse.rb +221 -70
- data/lib/webrick/https.rb +90 -2
- data/lib/webrick/httpserver.rb +45 -15
- data/lib/webrick/httpservlet/abstract.rb +5 -6
- data/lib/webrick/httpservlet/cgi_runner.rb +3 -2
- data/lib/webrick/httpservlet/cgihandler.rb +22 -10
- data/lib/webrick/httpservlet/erbhandler.rb +4 -3
- data/lib/webrick/httpservlet/filehandler.rb +136 -65
- data/lib/webrick/httpservlet/prochandler.rb +15 -1
- data/lib/webrick/httpservlet.rb +6 -5
- data/lib/webrick/httpstatus.rb +24 -14
- data/lib/webrick/httputils.rb +133 -13
- data/lib/webrick/httpversion.rb +28 -1
- data/lib/webrick/log.rb +25 -5
- data/lib/webrick/server.rb +234 -74
- data/lib/webrick/ssl.rb +100 -12
- data/lib/webrick/utils.rb +98 -69
- data/lib/webrick/version.rb +6 -1
- data/lib/webrick.rb +7 -7
- data/webrick.gemspec +76 -0
- metadata +70 -69
- data/README.txt +0 -21
- data/sample/webrick/demo-app.rb +0 -66
- data/sample/webrick/demo-multipart.cgi +0 -12
- data/sample/webrick/demo-servlet.rb +0 -6
- data/sample/webrick/demo-urlencoded.cgi +0 -12
- data/sample/webrick/hello.cgi +0 -11
- data/sample/webrick/hello.rb +0 -8
- data/sample/webrick/httpd.rb +0 -23
- data/sample/webrick/httpproxy.rb +0 -25
- data/sample/webrick/httpsd.rb +0 -33
- data/test/openssl/utils.rb +0 -313
- data/test/ruby/envutil.rb +0 -208
- data/test/webrick/test_cgi.rb +0 -134
- data/test/webrick/test_cookie.rb +0 -131
- data/test/webrick/test_filehandler.rb +0 -285
- data/test/webrick/test_httpauth.rb +0 -167
- data/test/webrick/test_httpproxy.rb +0 -282
- data/test/webrick/test_httprequest.rb +0 -411
- data/test/webrick/test_httpresponse.rb +0 -49
- data/test/webrick/test_httpserver.rb +0 -305
- data/test/webrick/test_httputils.rb +0 -96
- data/test/webrick/test_httpversion.rb +0 -40
- data/test/webrick/test_server.rb +0 -67
- data/test/webrick/test_utils.rb +0 -64
- data/test/webrick/utils.rb +0 -58
- data/test/webrick/webrick.cgi +0 -36
- data/test/webrick/webrick_long_filename.cgi +0 -36
| @@ -1,167 +0,0 @@ | |
| 1 | 
            -
            require "test/unit"
         | 
| 2 | 
            -
            require "net/http"
         | 
| 3 | 
            -
            require "tempfile"
         | 
| 4 | 
            -
            require "webrick"
         | 
| 5 | 
            -
            require "webrick/httpauth/basicauth"
         | 
| 6 | 
            -
            require_relative "utils"
         | 
| 7 | 
            -
             | 
| 8 | 
            -
            class TestWEBrickHTTPAuth < Test::Unit::TestCase
         | 
| 9 | 
            -
              def test_basic_auth
         | 
| 10 | 
            -
                TestWEBrick.start_httpserver{|server, addr, port, log|
         | 
| 11 | 
            -
                  realm = "WEBrick's realm"
         | 
| 12 | 
            -
                  path = "/basic_auth"
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  server.mount_proc(path){|req, res|
         | 
| 15 | 
            -
                    WEBrick::HTTPAuth.basic_auth(req, res, realm){|user, pass|
         | 
| 16 | 
            -
                      user == "webrick" && pass == "supersecretpassword"
         | 
| 17 | 
            -
                    }
         | 
| 18 | 
            -
                    res.body = "hoge"
         | 
| 19 | 
            -
                  }
         | 
| 20 | 
            -
                  http = Net::HTTP.new(addr, port)
         | 
| 21 | 
            -
                  g = Net::HTTP::Get.new(path)
         | 
| 22 | 
            -
                  g.basic_auth("webrick", "supersecretpassword")
         | 
| 23 | 
            -
                  http.request(g){|res| assert_equal("hoge", res.body, log.call)}
         | 
| 24 | 
            -
                  g.basic_auth("webrick", "not super")
         | 
| 25 | 
            -
                  http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
         | 
| 26 | 
            -
                }
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              def test_basic_auth2
         | 
| 30 | 
            -
                TestWEBrick.start_httpserver{|server, addr, port, log|
         | 
| 31 | 
            -
                  realm = "WEBrick's realm"
         | 
| 32 | 
            -
                  path = "/basic_auth2"
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                  tmpfile = Tempfile.new("test_webrick_auth")
         | 
| 35 | 
            -
                  tmpfile.close
         | 
| 36 | 
            -
                  tmp_pass = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
         | 
| 37 | 
            -
                  tmp_pass.set_passwd(realm, "webrick", "supersecretpassword")
         | 
| 38 | 
            -
                  tmp_pass.set_passwd(realm, "foo", "supersecretpassword")
         | 
| 39 | 
            -
                  tmp_pass.flush
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                  htpasswd = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
         | 
| 42 | 
            -
                  users = []
         | 
| 43 | 
            -
                  htpasswd.each{|user, pass| users << user }
         | 
| 44 | 
            -
                  assert_equal(2, users.size, log.call)
         | 
| 45 | 
            -
                  assert(users.member?("webrick"), log.call)
         | 
| 46 | 
            -
                  assert(users.member?("foo"), log.call)
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                  server.mount_proc(path){|req, res|
         | 
| 49 | 
            -
                    auth = WEBrick::HTTPAuth::BasicAuth.new(
         | 
| 50 | 
            -
                      :Realm => realm, :UserDB => htpasswd,
         | 
| 51 | 
            -
                      :Logger => server.logger
         | 
| 52 | 
            -
                    )
         | 
| 53 | 
            -
                    auth.authenticate(req, res)
         | 
| 54 | 
            -
                    res.body = "hoge"
         | 
| 55 | 
            -
                  }
         | 
| 56 | 
            -
                  http = Net::HTTP.new(addr, port)
         | 
| 57 | 
            -
                  g = Net::HTTP::Get.new(path)
         | 
| 58 | 
            -
                  g.basic_auth("webrick", "supersecretpassword")
         | 
| 59 | 
            -
                  http.request(g){|res| assert_equal("hoge", res.body, log.call)}
         | 
| 60 | 
            -
                  g.basic_auth("webrick", "not super")
         | 
| 61 | 
            -
                  http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
         | 
| 62 | 
            -
                }
         | 
| 63 | 
            -
              end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
              def test_basic_auth3
         | 
| 66 | 
            -
                tmpfile = Tempfile.new("test_webrick_auth")
         | 
| 67 | 
            -
                tmpfile.puts("webrick:{SHA}GJYFRpBbdchp595jlh3Bhfmgp8k=")
         | 
| 68 | 
            -
                tmpfile.flush
         | 
| 69 | 
            -
                assert_raise(NotImplementedError){
         | 
| 70 | 
            -
                  WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
         | 
| 71 | 
            -
                }
         | 
| 72 | 
            -
                tmpfile.close(true)
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                tmpfile = Tempfile.new("test_webrick_auth")
         | 
| 75 | 
            -
                tmpfile.puts("webrick:$apr1$IOVMD/..$rmnOSPXr0.wwrLPZHBQZy0")
         | 
| 76 | 
            -
                tmpfile.flush
         | 
| 77 | 
            -
                assert_raise(NotImplementedError){
         | 
| 78 | 
            -
                  WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
         | 
| 79 | 
            -
                }
         | 
| 80 | 
            -
                tmpfile.close(true)
         | 
| 81 | 
            -
              end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
              DIGESTRES_ = /
         | 
| 84 | 
            -
                ([a-zA-z\-]+)
         | 
| 85 | 
            -
                  [\s\t]*(?:\r\n[\s\t]*)*
         | 
| 86 | 
            -
                  =
         | 
| 87 | 
            -
                  [\s\t]*(?:\r\n[\s\t]*)*
         | 
| 88 | 
            -
                  (?:
         | 
| 89 | 
            -
                   "((?:[^"]+|\\[\x00-\x7F])*)" |
         | 
| 90 | 
            -
                   ([!\#$%&'*+\-.0-9A-Z^_`a-z|~]+)
         | 
| 91 | 
            -
                  )/x
         | 
| 92 | 
            -
             | 
| 93 | 
            -
              def test_digest_auth
         | 
| 94 | 
            -
                TestWEBrick.start_httpserver{|server, addr, port, log|
         | 
| 95 | 
            -
                  realm = "WEBrick's realm"
         | 
| 96 | 
            -
                  path = "/digest_auth"
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                  tmpfile = Tempfile.new("test_webrick_auth")
         | 
| 99 | 
            -
                  tmpfile.close
         | 
| 100 | 
            -
                  tmp_pass = WEBrick::HTTPAuth::Htdigest.new(tmpfile.path)
         | 
| 101 | 
            -
                  tmp_pass.set_passwd(realm, "webrick", "supersecretpassword")
         | 
| 102 | 
            -
                  tmp_pass.set_passwd(realm, "foo", "supersecretpassword")
         | 
| 103 | 
            -
                  tmp_pass.flush
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                  htdigest = WEBrick::HTTPAuth::Htdigest.new(tmpfile.path)
         | 
| 106 | 
            -
                  users = []
         | 
| 107 | 
            -
                  htdigest.each{|user, pass| users << user }
         | 
| 108 | 
            -
                  assert_equal(2, users.size, log.call)
         | 
| 109 | 
            -
                  assert(users.member?("webrick"), log.call)
         | 
| 110 | 
            -
                  assert(users.member?("foo"), log.call)
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                  auth = WEBrick::HTTPAuth::DigestAuth.new(
         | 
| 113 | 
            -
                    :Realm => realm, :UserDB => htdigest,
         | 
| 114 | 
            -
                    :Algorithm => 'MD5',
         | 
| 115 | 
            -
                    :Logger => server.logger
         | 
| 116 | 
            -
                  )
         | 
| 117 | 
            -
                  server.mount_proc(path){|req, res|
         | 
| 118 | 
            -
                    auth.authenticate(req, res)
         | 
| 119 | 
            -
                    res.body = "hoge"
         | 
| 120 | 
            -
                  }
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                  Net::HTTP.start(addr, port) do |http|
         | 
| 123 | 
            -
                    g = Net::HTTP::Get.new(path)
         | 
| 124 | 
            -
                    params = {}
         | 
| 125 | 
            -
                    http.request(g) do |res|
         | 
| 126 | 
            -
                      assert_equal('401', res.code, log.call)
         | 
| 127 | 
            -
                      res["www-authenticate"].scan(DIGESTRES_) do |key, quoted, token|
         | 
| 128 | 
            -
                        params[key.downcase] = token || quoted.delete('\\')
         | 
| 129 | 
            -
                      end
         | 
| 130 | 
            -
                       params['uri'] = "http://#{addr}:#{port}#{path}"
         | 
| 131 | 
            -
                    end
         | 
| 132 | 
            -
             | 
| 133 | 
            -
                    g['Authorization'] = credentials_for_request('webrick', "supersecretpassword", params)
         | 
| 134 | 
            -
                    http.request(g){|res| assert_equal("hoge", res.body, log.call)}
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                    params['algorithm'].downcase! #4936
         | 
| 137 | 
            -
                    g['Authorization'] = credentials_for_request('webrick', "supersecretpassword", params)
         | 
| 138 | 
            -
                    http.request(g){|res| assert_equal("hoge", res.body, log.call)}
         | 
| 139 | 
            -
             | 
| 140 | 
            -
                    g['Authorization'] = credentials_for_request('webrick', "not super", params)
         | 
| 141 | 
            -
                    http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
         | 
| 142 | 
            -
                  end
         | 
| 143 | 
            -
                }
         | 
| 144 | 
            -
              end
         | 
| 145 | 
            -
             | 
| 146 | 
            -
              private
         | 
| 147 | 
            -
              def credentials_for_request(user, password, params)
         | 
| 148 | 
            -
                cnonce = "hoge"
         | 
| 149 | 
            -
                nonce_count = 1
         | 
| 150 | 
            -
                ha1 = "#{user}:#{params['realm']}:#{password}"
         | 
| 151 | 
            -
                ha2 = "GET:#{params['uri']}"
         | 
| 152 | 
            -
                request_digest =
         | 
| 153 | 
            -
                  "#{Digest::MD5.hexdigest(ha1)}:" \
         | 
| 154 | 
            -
                  "#{params['nonce']}:#{'%08x' % nonce_count}:#{cnonce}:#{params['qop']}:" \
         | 
| 155 | 
            -
                  "#{Digest::MD5.hexdigest(ha2)}"
         | 
| 156 | 
            -
                "Digest username=\"#{user}\"" \
         | 
| 157 | 
            -
                  ", realm=\"#{params['realm']}\"" \
         | 
| 158 | 
            -
                  ", nonce=\"#{params['nonce']}\"" \
         | 
| 159 | 
            -
                  ", uri=\"#{params['uri']}\"" \
         | 
| 160 | 
            -
                  ", qop=#{params['qop']}" \
         | 
| 161 | 
            -
                  ", nc=#{'%08x' % nonce_count}" \
         | 
| 162 | 
            -
                  ", cnonce=\"#{cnonce}\"" \
         | 
| 163 | 
            -
                  ", response=\"#{Digest::MD5.hexdigest(request_digest)}\"" \
         | 
| 164 | 
            -
                  ", opaque=\"#{params['opaque']}\"" \
         | 
| 165 | 
            -
                  ", algorithm=#{params['algorithm']}"
         | 
| 166 | 
            -
              end
         | 
| 167 | 
            -
            end
         | 
| @@ -1,282 +0,0 @@ | |
| 1 | 
            -
            require "test/unit"
         | 
| 2 | 
            -
            require "net/http"
         | 
| 3 | 
            -
            require "webrick"
         | 
| 4 | 
            -
            require "webrick/httpproxy"
         | 
| 5 | 
            -
            begin
         | 
| 6 | 
            -
              require "webrick/ssl"
         | 
| 7 | 
            -
              require "net/https"
         | 
| 8 | 
            -
              require File.expand_path("../openssl/utils.rb", File.dirname(__FILE__))
         | 
| 9 | 
            -
            rescue LoadError
         | 
| 10 | 
            -
              # test_connect will be skipped
         | 
| 11 | 
            -
            end
         | 
| 12 | 
            -
            require File.expand_path("utils.rb", File.dirname(__FILE__))
         | 
| 13 | 
            -
             | 
| 14 | 
            -
            class TestWEBrickHTTPProxy < Test::Unit::TestCase
         | 
| 15 | 
            -
              def test_fake_proxy
         | 
| 16 | 
            -
                assert_nil(WEBrick::FakeProxyURI.scheme)
         | 
| 17 | 
            -
                assert_nil(WEBrick::FakeProxyURI.host)
         | 
| 18 | 
            -
                assert_nil(WEBrick::FakeProxyURI.port)
         | 
| 19 | 
            -
                assert_nil(WEBrick::FakeProxyURI.path)
         | 
| 20 | 
            -
                assert_nil(WEBrick::FakeProxyURI.userinfo)
         | 
| 21 | 
            -
                assert_raise(NoMethodError){ WEBrick::FakeProxyURI.foo }
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
              def test_proxy
         | 
| 25 | 
            -
                # Testing GET or POST to the proxy server
         | 
| 26 | 
            -
                # Note that the proxy server works as the origin server.
         | 
| 27 | 
            -
                #                    +------+
         | 
| 28 | 
            -
                #                    V      |
         | 
| 29 | 
            -
                #  client -------> proxy ---+
         | 
| 30 | 
            -
                #        GET / POST     GET / POST
         | 
| 31 | 
            -
                #
         | 
| 32 | 
            -
                proxy_handler_called = request_handler_called = 0
         | 
| 33 | 
            -
                config = {
         | 
| 34 | 
            -
                  :ServerName => "localhost.localdomain",
         | 
| 35 | 
            -
                  :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1 },
         | 
| 36 | 
            -
                  :RequestCallback => Proc.new{|req, res| request_handler_called += 1 }
         | 
| 37 | 
            -
                }
         | 
| 38 | 
            -
                TestWEBrick.start_httpproxy(config){|server, addr, port, log|
         | 
| 39 | 
            -
                  server.mount_proc("/"){|req, res|
         | 
| 40 | 
            -
                    res.body = "#{req.request_method} #{req.path} #{req.body}"
         | 
| 41 | 
            -
                  }
         | 
| 42 | 
            -
                  http = Net::HTTP.new(addr, port, addr, port)
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                  req = Net::HTTP::Get.new("/")
         | 
| 45 | 
            -
                  http.request(req){|res|
         | 
| 46 | 
            -
                    assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
         | 
| 47 | 
            -
                    assert_equal("GET / ", res.body, log.call)
         | 
| 48 | 
            -
                  }
         | 
| 49 | 
            -
                  assert_equal(1, proxy_handler_called, log.call)
         | 
| 50 | 
            -
                  assert_equal(2, request_handler_called, log.call)
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                  req = Net::HTTP::Head.new("/")
         | 
| 53 | 
            -
                  http.request(req){|res|
         | 
| 54 | 
            -
                    assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
         | 
| 55 | 
            -
                    assert_nil(res.body, log.call)
         | 
| 56 | 
            -
                  }
         | 
| 57 | 
            -
                  assert_equal(2, proxy_handler_called, log.call)
         | 
| 58 | 
            -
                  assert_equal(4, request_handler_called, log.call)
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                  req = Net::HTTP::Post.new("/")
         | 
| 61 | 
            -
                  req.body = "post-data"
         | 
| 62 | 
            -
                  http.request(req){|res|
         | 
| 63 | 
            -
                    assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
         | 
| 64 | 
            -
                    assert_equal("POST / post-data", res.body, log.call)
         | 
| 65 | 
            -
                  }
         | 
| 66 | 
            -
                  assert_equal(3, proxy_handler_called, log.call)
         | 
| 67 | 
            -
                  assert_equal(6, request_handler_called, log.call)
         | 
| 68 | 
            -
                }
         | 
| 69 | 
            -
              end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
              def test_no_proxy
         | 
| 72 | 
            -
                # Testing GET or POST to the proxy server without proxy request.
         | 
| 73 | 
            -
                #
         | 
| 74 | 
            -
                #  client -------> proxy
         | 
| 75 | 
            -
                #        GET / POST
         | 
| 76 | 
            -
                #
         | 
| 77 | 
            -
                proxy_handler_called = request_handler_called = 0
         | 
| 78 | 
            -
                config = {
         | 
| 79 | 
            -
                  :ServerName => "localhost.localdomain",
         | 
| 80 | 
            -
                  :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1 },
         | 
| 81 | 
            -
                  :RequestCallback => Proc.new{|req, res| request_handler_called += 1 }
         | 
| 82 | 
            -
                }
         | 
| 83 | 
            -
                TestWEBrick.start_httpproxy(config){|server, addr, port, log|
         | 
| 84 | 
            -
                  server.mount_proc("/"){|req, res|
         | 
| 85 | 
            -
                    res.body = "#{req.request_method} #{req.path} #{req.body}"
         | 
| 86 | 
            -
                  }
         | 
| 87 | 
            -
                  http = Net::HTTP.new(addr, port)
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                  req = Net::HTTP::Get.new("/")
         | 
| 90 | 
            -
                  http.request(req){|res|
         | 
| 91 | 
            -
                    assert_nil(res["via"], log.call)
         | 
| 92 | 
            -
                    assert_equal("GET / ", res.body, log.call)
         | 
| 93 | 
            -
                  }
         | 
| 94 | 
            -
                  assert_equal(0, proxy_handler_called, log.call)
         | 
| 95 | 
            -
                  assert_equal(1, request_handler_called, log.call)
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                  req = Net::HTTP::Head.new("/")
         | 
| 98 | 
            -
                  http.request(req){|res|
         | 
| 99 | 
            -
                    assert_nil(res["via"], log.call)
         | 
| 100 | 
            -
                    assert_nil(res.body, log.call)
         | 
| 101 | 
            -
                  }
         | 
| 102 | 
            -
                  assert_equal(0, proxy_handler_called, log.call)
         | 
| 103 | 
            -
                  assert_equal(2, request_handler_called, log.call)
         | 
| 104 | 
            -
             | 
| 105 | 
            -
                  req = Net::HTTP::Post.new("/")
         | 
| 106 | 
            -
                  req.body = "post-data"
         | 
| 107 | 
            -
                  http.request(req){|res|
         | 
| 108 | 
            -
                    assert_nil(res["via"], log.call)
         | 
| 109 | 
            -
                    assert_equal("POST / post-data", res.body, log.call)
         | 
| 110 | 
            -
                  }
         | 
| 111 | 
            -
                  assert_equal(0, proxy_handler_called, log.call)
         | 
| 112 | 
            -
                  assert_equal(3, request_handler_called, log.call)
         | 
| 113 | 
            -
                }
         | 
| 114 | 
            -
              end
         | 
| 115 | 
            -
             | 
| 116 | 
            -
              def make_certificate(key, cn)
         | 
| 117 | 
            -
                subject = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=#{cn}")
         | 
| 118 | 
            -
                exts = [
         | 
| 119 | 
            -
                  ["keyUsage", "keyEncipherment,digitalSignature", true],
         | 
| 120 | 
            -
                ]
         | 
| 121 | 
            -
                cert = OpenSSL::TestUtils.issue_cert(
         | 
| 122 | 
            -
                  subject, key, 1, Time.now, Time.now + 3600, exts,
         | 
| 123 | 
            -
                  nil, nil, OpenSSL::Digest::SHA1.new
         | 
| 124 | 
            -
                )
         | 
| 125 | 
            -
                return cert
         | 
| 126 | 
            -
              end
         | 
| 127 | 
            -
             | 
| 128 | 
            -
              def test_connect
         | 
| 129 | 
            -
                # Testing CONNECT to proxy server
         | 
| 130 | 
            -
                #
         | 
| 131 | 
            -
                #  client -----------> proxy -----------> https
         | 
| 132 | 
            -
                #    1.     CONNECT          establish TCP
         | 
| 133 | 
            -
                #    2.   ---- establish SSL session --->
         | 
| 134 | 
            -
                #    3.   ------- GET or POST ---------->
         | 
| 135 | 
            -
                #
         | 
| 136 | 
            -
                key = OpenSSL::TestUtils::TEST_KEY_RSA1024
         | 
| 137 | 
            -
                cert = make_certificate(key, "127.0.0.1")
         | 
| 138 | 
            -
                s_config = {
         | 
| 139 | 
            -
                  :SSLEnable =>true,
         | 
| 140 | 
            -
                  :ServerName => "localhost",
         | 
| 141 | 
            -
                  :SSLCertificate => cert,
         | 
| 142 | 
            -
                  :SSLPrivateKey => key,
         | 
| 143 | 
            -
                }
         | 
| 144 | 
            -
                config = {
         | 
| 145 | 
            -
                  :ServerName => "localhost.localdomain",
         | 
| 146 | 
            -
                  :RequestCallback => Proc.new{|req, res|
         | 
| 147 | 
            -
                    assert_equal("CONNECT", req.request_method)
         | 
| 148 | 
            -
                  },
         | 
| 149 | 
            -
                }
         | 
| 150 | 
            -
                TestWEBrick.start_httpserver(s_config){|s_server, s_addr, s_port, s_log|
         | 
| 151 | 
            -
                  s_server.mount_proc("/"){|req, res|
         | 
| 152 | 
            -
                    res.body = "SSL #{req.request_method} #{req.path} #{req.body}"
         | 
| 153 | 
            -
                  }
         | 
| 154 | 
            -
                  TestWEBrick.start_httpproxy(config){|server, addr, port, log|
         | 
| 155 | 
            -
                    http = Net::HTTP.new("127.0.0.1", s_port, addr, port)
         | 
| 156 | 
            -
                    http.use_ssl = true
         | 
| 157 | 
            -
                    http.verify_callback = Proc.new do |preverify_ok, store_ctx|
         | 
| 158 | 
            -
                      store_ctx.current_cert.to_der == cert.to_der
         | 
| 159 | 
            -
                    end
         | 
| 160 | 
            -
             | 
| 161 | 
            -
                    req = Net::HTTP::Get.new("/")
         | 
| 162 | 
            -
                    http.request(req){|res|
         | 
| 163 | 
            -
                      assert_equal("SSL GET / ", res.body, s_log.call + log.call)
         | 
| 164 | 
            -
                    }
         | 
| 165 | 
            -
             | 
| 166 | 
            -
                    req = Net::HTTP::Post.new("/")
         | 
| 167 | 
            -
                    req.body = "post-data"
         | 
| 168 | 
            -
                    http.request(req){|res|
         | 
| 169 | 
            -
                      assert_equal("SSL POST / post-data", res.body, s_log.call + log.call)
         | 
| 170 | 
            -
                    }
         | 
| 171 | 
            -
                  }
         | 
| 172 | 
            -
                }
         | 
| 173 | 
            -
              end if defined?(OpenSSL)
         | 
| 174 | 
            -
             | 
| 175 | 
            -
              def test_upstream_proxy
         | 
| 176 | 
            -
                # Testing GET or POST through the upstream proxy server
         | 
| 177 | 
            -
                # Note that the upstream proxy server works as the origin server.
         | 
| 178 | 
            -
                #                                   +------+
         | 
| 179 | 
            -
                #                                   V      |
         | 
| 180 | 
            -
                #  client -------> proxy -------> proxy ---+
         | 
| 181 | 
            -
                #        GET / POST     GET / POST     GET / POST
         | 
| 182 | 
            -
                #
         | 
| 183 | 
            -
                up_proxy_handler_called = up_request_handler_called = 0
         | 
| 184 | 
            -
                proxy_handler_called = request_handler_called = 0
         | 
| 185 | 
            -
                up_config = {
         | 
| 186 | 
            -
                  :ServerName => "localhost.localdomain",
         | 
| 187 | 
            -
                  :ProxyContentHandler => Proc.new{|req, res| up_proxy_handler_called += 1},
         | 
| 188 | 
            -
                  :RequestCallback => Proc.new{|req, res| up_request_handler_called += 1}
         | 
| 189 | 
            -
                }
         | 
| 190 | 
            -
                TestWEBrick.start_httpproxy(up_config){|up_server, up_addr, up_port, up_log|
         | 
| 191 | 
            -
                  up_server.mount_proc("/"){|req, res|
         | 
| 192 | 
            -
                    res.body = "#{req.request_method} #{req.path} #{req.body}"
         | 
| 193 | 
            -
                  }
         | 
| 194 | 
            -
                  config = {
         | 
| 195 | 
            -
                    :ServerName => "localhost.localdomain",
         | 
| 196 | 
            -
                    :ProxyURI => URI.parse("http://localhost:#{up_port}"),
         | 
| 197 | 
            -
                    :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1},
         | 
| 198 | 
            -
                    :RequestCallback => Proc.new{|req, res| request_handler_called += 1},
         | 
| 199 | 
            -
                  }
         | 
| 200 | 
            -
                  TestWEBrick.start_httpproxy(config){|server, addr, port, log|
         | 
| 201 | 
            -
                    http = Net::HTTP.new(up_addr, up_port, addr, port)
         | 
| 202 | 
            -
             | 
| 203 | 
            -
                    req = Net::HTTP::Get.new("/")
         | 
| 204 | 
            -
                    http.request(req){|res|
         | 
| 205 | 
            -
                      skip res.message unless res.code == '200'
         | 
| 206 | 
            -
                      via = res["via"].split(/,\s+/)
         | 
| 207 | 
            -
                      assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
         | 
| 208 | 
            -
                      assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
         | 
| 209 | 
            -
                      assert_equal("GET / ", res.body)
         | 
| 210 | 
            -
                    }
         | 
| 211 | 
            -
                    assert_equal(1, up_proxy_handler_called, up_log.call + log.call)
         | 
| 212 | 
            -
                    assert_equal(2, up_request_handler_called, up_log.call + log.call)
         | 
| 213 | 
            -
                    assert_equal(1, proxy_handler_called, up_log.call + log.call)
         | 
| 214 | 
            -
                    assert_equal(1, request_handler_called, up_log.call + log.call)
         | 
| 215 | 
            -
             | 
| 216 | 
            -
                    req = Net::HTTP::Head.new("/")
         | 
| 217 | 
            -
                    http.request(req){|res|
         | 
| 218 | 
            -
                      via = res["via"].split(/,\s+/)
         | 
| 219 | 
            -
                      assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
         | 
| 220 | 
            -
                      assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
         | 
| 221 | 
            -
                      assert_nil(res.body, up_log.call + log.call)
         | 
| 222 | 
            -
                    }
         | 
| 223 | 
            -
                    assert_equal(2, up_proxy_handler_called, up_log.call + log.call)
         | 
| 224 | 
            -
                    assert_equal(4, up_request_handler_called, up_log.call + log.call)
         | 
| 225 | 
            -
                    assert_equal(2, proxy_handler_called, up_log.call + log.call)
         | 
| 226 | 
            -
                    assert_equal(2, request_handler_called, up_log.call + log.call)
         | 
| 227 | 
            -
             | 
| 228 | 
            -
                    req = Net::HTTP::Post.new("/")
         | 
| 229 | 
            -
                    req.body = "post-data"
         | 
| 230 | 
            -
                    http.request(req){|res|
         | 
| 231 | 
            -
                      via = res["via"].split(/,\s+/)
         | 
| 232 | 
            -
                      assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
         | 
| 233 | 
            -
                      assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
         | 
| 234 | 
            -
                      assert_equal("POST / post-data", res.body, up_log.call + log.call)
         | 
| 235 | 
            -
                    }
         | 
| 236 | 
            -
                    assert_equal(3, up_proxy_handler_called, up_log.call + log.call)
         | 
| 237 | 
            -
                    assert_equal(6, up_request_handler_called, up_log.call + log.call)
         | 
| 238 | 
            -
                    assert_equal(3, proxy_handler_called, up_log.call + log.call)
         | 
| 239 | 
            -
                    assert_equal(3, request_handler_called, up_log.call + log.call)
         | 
| 240 | 
            -
             | 
| 241 | 
            -
                    if defined?(OpenSSL)
         | 
| 242 | 
            -
                      # Testing CONNECT to the upstream proxy server
         | 
| 243 | 
            -
                      #
         | 
| 244 | 
            -
                      #  client -------> proxy -------> proxy -------> https
         | 
| 245 | 
            -
                      #    1.   CONNECT        CONNECT      establish TCP
         | 
| 246 | 
            -
                      #    2.   -------- establish SSL session ------>
         | 
| 247 | 
            -
                      #    3.   ---------- GET or POST -------------->
         | 
| 248 | 
            -
                      #
         | 
| 249 | 
            -
                      key = OpenSSL::TestUtils::TEST_KEY_RSA1024
         | 
| 250 | 
            -
                      cert = make_certificate(key, "127.0.0.1")
         | 
| 251 | 
            -
                      s_config = {
         | 
| 252 | 
            -
                        :SSLEnable =>true,
         | 
| 253 | 
            -
                        :ServerName => "localhost",
         | 
| 254 | 
            -
                        :SSLCertificate => cert,
         | 
| 255 | 
            -
                        :SSLPrivateKey => key,
         | 
| 256 | 
            -
                      }
         | 
| 257 | 
            -
                      TestWEBrick.start_httpserver(s_config){|s_server, s_addr, s_port, s_log|
         | 
| 258 | 
            -
                        s_server.mount_proc("/"){|req2, res|
         | 
| 259 | 
            -
                          res.body = "SSL #{req2.request_method} #{req2.path} #{req2.body}"
         | 
| 260 | 
            -
                        }
         | 
| 261 | 
            -
                        http = Net::HTTP.new("127.0.0.1", s_port, addr, port, up_log.call + log.call + s_log.call)
         | 
| 262 | 
            -
                        http.use_ssl = true
         | 
| 263 | 
            -
                        http.verify_callback = Proc.new do |preverify_ok, store_ctx|
         | 
| 264 | 
            -
                          store_ctx.current_cert.to_der == cert.to_der
         | 
| 265 | 
            -
                        end
         | 
| 266 | 
            -
             | 
| 267 | 
            -
                        req2 = Net::HTTP::Get.new("/")
         | 
| 268 | 
            -
                        http.request(req2){|res|
         | 
| 269 | 
            -
                          assert_equal("SSL GET / ", res.body, up_log.call + log.call + s_log.call)
         | 
| 270 | 
            -
                        }
         | 
| 271 | 
            -
             | 
| 272 | 
            -
                        req2 = Net::HTTP::Post.new("/")
         | 
| 273 | 
            -
                        req2.body = "post-data"
         | 
| 274 | 
            -
                        http.request(req2){|res|
         | 
| 275 | 
            -
                          assert_equal("SSL POST / post-data", res.body, up_log.call + log.call + s_log.call)
         | 
| 276 | 
            -
                        }
         | 
| 277 | 
            -
                      }
         | 
| 278 | 
            -
                    end
         | 
| 279 | 
            -
                  }
         | 
| 280 | 
            -
                }
         | 
| 281 | 
            -
              end
         | 
| 282 | 
            -
            end
         |