File: test_httpclient.rb

package info (click to toggle)
ruby-eventmachine 1.3~pre20201020-b50c135-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,768 kB
  • sloc: ruby: 10,597; cpp: 6,032; java: 1,136; makefile: 12
file content (238 lines) | stat: -rw-r--r-- 6,022 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
require_relative 'em_test_helper'

class TestHttpClient < Test::Unit::TestCase

  def setup
    @port = next_port
  end

  #-------------------------------------

  def est_http_client
    ok = false
    EM.run {
      c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
      c.callback {
        ok = true
        c.close_connection
        EM.stop
      }
      c.errback {EM.stop} # necessary, otherwise a failure blocks the test suite forever.
    }
    assert ok
  end

  #-------------------------------------

  def est_http_client_1
    ok = false
    EM.run {
      c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
      c.callback {
        ok = true
        c.close_connection
        EM.stop
      }
      c.errback {EM.stop}
    }
    assert ok
  end

  #-------------------------------------

  def est_http_client_2
    ok = false
    EM.run {
      c = silent { EM::P::HttpClient.send :request, :host => "www.google.com", :port => 80 }
      c.callback {
        ok = true
        c.close_connection
        EM.stop
      }
      c.errback {EM.stop}
    }
    assert ok
  end


  #-----------------------------------------

  # Test a server that returns a page with a zero content-length.
  # This caused an early version of the HTTP client not to generate a response,
  # causing this test to hang. Observe, there was no problem with responses
  # lacking a content-length, just when the content-length was zero.
  #
  class EmptyContent < EM::Connection
      def initialize *args
        super
      end
      def receive_data data
        send_data "HTTP/1.0 404 ...\r\nContent-length: 0\r\n\r\n"
        close_connection_after_writing
      end
  end

  def test_http_empty_content
      ok = false
      EM.run {
        EM.start_server "localhost", @port, EmptyContent
        c = silent { EM::P::HttpClient.send :request, :host => "localhost", :port => @port }
        c.callback {
          ok = true
          c.close_connection
          EM.stop
        }
      }
      assert ok
  end


  #---------------------------------------

  class PostContent < EM::P::LineAndTextProtocol
      def initialize *args
        super
        @lines = []
      end
      def receive_line line
        if line.length > 0
          @lines << line
        else
          process_headers
        end
      end
      def receive_binary_data data
        @post_content = data
        send_response
      end
      def process_headers
        if @lines.first =~ /\APOST ([^\s]+) HTTP\/1.1\Z/
          @uri = $1.dup
        else
          raise "bad request"
        end

        @lines.each {|line|
          if line =~ /\AContent-length:\s*(\d+)\Z/i
            @content_length = $1.dup.to_i
          elsif line =~ /\AContent-type:\s*(\d+)\Z/i
            @content_type = $1.dup
          end
        }

        raise "invalid content length" unless @content_length
        set_binary_mode @content_length
      end
      def send_response
        send_data "HTTP/1.1 200 ...\r\nConnection: close\r\nContent-length: 10\r\nContent-type: text/html\r\n\r\n0123456789"
        close_connection_after_writing
      end
  end
  
  # TODO, this is WRONG. The handler is asserting an HTTP 1.1 request, but the client
  # is sending a 1.0 request. Gotta fix the client
  def test_post
      response = nil
      EM.run {
        EM.start_server 'localhost', @port, PostContent
        setup_timeout 2
        c = silent { EM::P::HttpClient.request(
          :host         => 'localhost',
          :port         => @port,
          :method       => :post,
          :request      => "/aaa",
          :content      => "XYZ",
          :content_type => "text/plain"
        )}
        c.callback {|r|
          response = r
          EM.stop
        }
      }

      assert_equal( 200, response[:status] )
      assert_equal( "0123456789", response[:content] )
  end


  # TODO, need a more intelligent cookie tester.
  # In fact, this whole test-harness needs a beefier server implementation.
  def est_cookie
    ok = false
    EM.run {
      c = silent { EM::Protocols::HttpClient.send :request, :host => "www.google.com", :port => 80, :cookie=>"aaa=bbb" }
      c.callback {
        ok = true
        c.close_connection
        EM.stop
      }
      c.errback {EM.stop}
    }
    assert ok
  end

  # We can tell the client to send an HTTP/1.0 request (default is 1.1).
  # This is useful for suppressing chunked responses until those are working.
  def est_version_1_0
    ok = false
    EM.run {
      c = silent { EM::P::HttpClient.request(
        :host => "www.google.com",
        :port => 80,
        :version => "1.0"
      )}
      c.callback {
        ok = true
        c.close_connection
        EM.stop
      }
      c.errback {EM.stop}
    }
    assert ok
  end

  #-----------------------------------------

  # Test a server that returns chunked encoding
  #
  class ChunkedEncodingContent < EventMachine::Connection
    def initialize *args
      super
    end
    def receive_data data
      send_data ["HTTP/1.1 200 OK",
                "Server: nginx/0.7.67", 
                "Date: Sat, 23 Oct 2010 16:41:32 GMT",
                "Content-Type: application/json",
                "Transfer-Encoding: chunked",
                "Connection: keep-alive",
                "", 
                "1800",
                "chunk1" * 1024,
                "5a",
                "chunk2" * 15,
                "0",
                ""].join("\r\n")
      close_connection_after_writing
    end
  end

  def test_http_chunked_encoding_content
    ok = false
    EM.run {
      EM.start_server "localhost", @port, ChunkedEncodingContent
      c = silent { EM::P::HttpClient.send :request, :host => "localhost", :port => @port }
      c.callback { |result|
        if result[:content] == "chunk1" * 1024 + "chunk2" * 15
          ok = true
        end
        c.close_connection
        EM.stop
      }
    }
    assert ok
  end

end