aboutsummaryrefslogtreecommitdiffstats
path: root/spec/ruby/library/net/http/httpgenericrequest/exec_spec.rb
blob: b3850d6c7463af70dcf26b6b3cf94a33bd7f5ef9 (plain)
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
require File.expand_path('../../../../../spec_helper', __FILE__)
require 'net/http'
require "stringio"

describe "Net::HTTPGenericRequest#exec when passed socket, version, path" do
  before :each do
    @socket = StringIO.new("")
    @buffered_socket = Net::BufferedIO.new(@socket)
  end

  it "executes the request over the socket to the path using the HTTP version" do
    request = Net::HTTPGenericRequest.new("POST", true, true, "/some/path")

    request.exec(@buffered_socket, "1.1", "/some/path")
    str = @socket.string

    str.should =~ %r[POST /some/path HTTP/1.1\r\n]
    str.should =~ %r[Accept: \*/\*\r\n]
    str[-4..-1].should == "\r\n\r\n"

    request = Net::HTTPGenericRequest.new("GET", true, true, "/some/path",
                                          "Content-Type" => "text/html")

    request.exec(@buffered_socket, "1.0", "/some/other/path")
    str = @socket.string

    str.should =~ %r[GET /some/other/path HTTP/1.0\r\n]
    str.should =~ %r[Accept: \*/\*\r\n]
    str.should =~ %r[Content-Type: text/html\r\n]
    str[-4..-1].should == "\r\n\r\n"
  end

  describe "when a request body is set" do
    it "sets the 'Content-Type' header to 'application/x-www-form-urlencoded' unless the 'Content-Type' header is supplied" do
      request = Net::HTTPGenericRequest.new("POST", true, true, "/some/path")
      request.body = "Some Content"

      request.exec(@buffered_socket, "1.1", "/some/other/path")
      str = @socket.string

      str.should =~ %r[POST /some/other/path HTTP/1.1\r\n]
      str.should =~ %r[Accept: \*/\*\r\n]
      str.should =~ %r[Content-Type: application/x-www-form-urlencoded\r\n]
      str.should =~ %r[Content-Length: 12\r\n]
      str[-16..-1].should == "\r\n\r\nSome Content"
    end

    it "correctly sets the 'Content-Length' header and includes the body" do
      request = Net::HTTPGenericRequest.new("POST", true, true, "/some/path",
                                            "Content-Type" => "text/html")
      request.body = "Some Content"

      request.exec(@buffered_socket, "1.1", "/some/other/path")
      str = @socket.string

      str.should =~ %r[POST /some/other/path HTTP/1.1\r\n]
      str.should =~ %r[Accept: \*/\*\r\n]
      str.should =~ %r[Content-Type: text/html\r\n]
      str.should =~ %r[Content-Length: 12\r\n]
      str[-16..-1].should == "\r\n\r\nSome Content"
    end
  end

  describe "when a body stream is set" do
    it "sets the 'Content-Type' header to 'application/x-www-form-urlencoded' unless the 'Content-Type' header is supplied" do
      request = Net::HTTPGenericRequest.new("POST", true, true, "/some/path",
                                            "Content-Length" => "10")
      request.body_stream = StringIO.new("a" * 20)

      request.exec(@buffered_socket, "1.1", "/some/other/path")
      str = @socket.string

      str.should =~ %r[POST /some/other/path HTTP/1.1\r\n]
      str.should =~ %r[Accept: \*/\*\r\n]
      str.should =~ %r[Content-Type: application/x-www-form-urlencoded\r\n]
      str.should =~ %r[Content-Length: 10\r\n]
      str[-24..-1].should == "\r\n\r\naaaaaaaaaaaaaaaaaaaa"
    end

    it "sends the whole stream, regardless of the 'Content-Length' header" do
      request = Net::HTTPGenericRequest.new("POST", true, true,"/some/path",
                                            "Content-Type" => "text/html",
                                            "Content-Length" => "10")
      request.body_stream = StringIO.new("a" * 20)

      request.exec(@buffered_socket, "1.1", "/some/other/path")
      str = @socket.string

      str.should =~ %r[POST /some/other/path HTTP/1.1\r\n]
      str.should =~ %r[Accept: \*/\*\r\n]
      str.should =~ %r[Content-Type: text/html\r\n]
      str.should =~ %r[Content-Length: 10\r\n]
      str[-24..-1].should == "\r\n\r\naaaaaaaaaaaaaaaaaaaa"
    end

    it "sends the request in chunks when 'Transfer-Encoding' is set to 'chunked'" do
      request = Net::HTTPGenericRequest.new("POST", true, true, "/some/path",
                                            "Content-Type" => "text/html",
                                            "Transfer-Encoding" => "chunked")
      datasize = 1024 * 10
      request.body_stream = StringIO.new("a" * datasize)

      request.exec(@buffered_socket, "1.1", "/some/other/path")
      str = @socket.string

      str.should =~ %r[POST /some/other/path HTTP/1.1\r\n]
      str.should =~ %r[Accept: \*/\*\r\n]
      str.should =~ %r[Content-Type: text/html\r\n]
      str.should =~ %r[Transfer-Encoding: chunked\r\n]
      str =~ %r[\r\n\r\n]
      str = $'
      while datasize > 0
        chunk_size_line, str = str.split(/\r\n/, 2)
        chunk_size = chunk_size_line[/\A[0-9A-Fa-f]+/].to_i(16)
        str.slice!(0, chunk_size).should == 'a' * chunk_size
        datasize -= chunk_size
        str.slice!(0, 2).should == "\r\n"
      end
      datasize.should == 0
      str.should == %"0\r\n\r\n"
    end

    it "raises an ArgumentError when the 'Content-Length' is not set or 'Transfer-Encoding' is not set to 'chunked'" do
      request = Net::HTTPGenericRequest.new("POST", true, true, "/some/path",
                                            "Content-Type" => "text/html")
      request.body_stream = StringIO.new("Some Content")

      lambda { request.exec(@buffered_socket, "1.1", "/some/other/path") }.should raise_error(ArgumentError)
    end
  end
end