PageRenderTime 56ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/spec/session_ssl_spec.rb

https://github.com/toland/patron
Ruby | 295 lines | 245 code | 45 blank | 5 comment | 35 complexity | eaabd059795840f9c68f4c348eb0afd9 MD5 | raw file
  1. require File.expand_path("./spec") + '/spec_helper.rb'
  2. require 'webrick'
  3. require 'yaml'
  4. require 'base64'
  5. require 'fileutils'
  6. describe Patron::Session do
  7. before(:each) do
  8. @session = Patron::Session.new
  9. @session.base_url = "https://localhost:9043"
  10. @session.insecure = true
  11. end
  12. it "should retrieve a url with :get" do
  13. response = @session.get("/test")
  14. body = YAML::load(response.body)
  15. expect(body.request_method).to be == "GET"
  16. end
  17. it "should download content with :get and a file path" do
  18. tmpfile = "/tmp/patron_test.yaml"
  19. response = @session.get_file "/test", tmpfile
  20. expect(response.body).to be_nil
  21. body = YAML::load_file(tmpfile)
  22. expect(body.request_method).to be == "GET"
  23. FileUtils.rm tmpfile
  24. end
  25. # See https://github.com/curl/curl/issues/788
  26. # Basically any HTTPS operation crashes on OSX with securetransport-enabled libCURL
  27. it "should download content in a forked subprocess" do
  28. # To trigger the bug, we need to perform a request in the master process first
  29. tmpfile = "/tmp/patron_test.yaml"
  30. @session.get_file "/test", tmpfile
  31. FileUtils.rm tmpfile
  32. # and this one segfaults
  33. pid = fork do
  34. response = @session.get_file "/test", tmpfile
  35. expect(response.body).to be_nil
  36. body = YAML::load_file(tmpfile)
  37. expect(body.request_method).to be == "GET"
  38. FileUtils.rm tmpfile
  39. end
  40. exit_pid, status = Process.wait2(pid)
  41. expect(status.exitstatus).to be_zero
  42. end
  43. it "should download correctly(md5 ok) with get_file" do
  44. tmpfile = "/tmp/picture"
  45. response = @session.get_file "/picture", tmpfile
  46. expect(response.body).to be_nil
  47. expect(File.size(File.join(File.dirname(__FILE__),"../pic.png"))).to be == File.size(tmpfile)
  48. FileUtils.rm tmpfile
  49. end
  50. it "should include custom headers in a request" do
  51. response = @session.get("/test", {"User-Agent" => "PatronTest"})
  52. body = YAML::load(response.body)
  53. expect(body.header["user-agent"]).to be == ["PatronTest"]
  54. end
  55. it "should merge custom headers with session headers" do
  56. @session.headers["X-Test"] = "Testing"
  57. response = @session.get("/test", {"User-Agent" => "PatronTest"})
  58. body = YAML::load(response.body)
  59. expect(body.header["user-agent"]).to be == ["PatronTest"]
  60. expect(body.header["x-test"]).to be == ["Testing"]
  61. end
  62. it "should raise an exception on timeout" do
  63. @session.timeout = 1
  64. expect {
  65. @session.get("/timeout?millis=1100")
  66. }.to raise_error(Patron::TimeoutError)
  67. end
  68. it "should follow redirects by default" do
  69. @session.max_redirects = 1
  70. response = @session.get("/redirect")
  71. body = YAML::load(response.body)
  72. expect(response.status).to be == 200
  73. expect(body.path).to be == "/test"
  74. end
  75. it "should include redirect count in response" do
  76. @session.max_redirects = 1
  77. response = @session.get("/redirect")
  78. expect(response.redirect_count).to be == 1
  79. end
  80. it "should not follow redirects when configured to do so" do
  81. @session.max_redirects = 0
  82. response = @session.get("/redirect")
  83. expect(response.status).to be == 301
  84. expect(response.body).to be_empty
  85. end
  86. it "should retrieve URL metadata with :head" do
  87. response = @session.head("/test")
  88. expect(response.status).to be == 200
  89. expect(response.body).to be_empty
  90. expect(response.headers).to_not be_empty
  91. end
  92. it "should send a delete request with :delete" do
  93. response = @session.delete("/test")
  94. body = YAML::load(response.body)
  95. expect(body.request_method).to be == "DELETE"
  96. end
  97. it "should send a COPY request with :copy" do
  98. response = @session.copy("/test", "/test2")
  99. body = YAML::load(response.body)
  100. expect(body.request_method).to be == "COPY"
  101. end
  102. it "should include a Destination header in COPY requests" do
  103. response = @session.copy("/test", "/test2")
  104. body = YAML::load(response.body)
  105. expect(body.header['destination'].first).to be == "/test2"
  106. end
  107. it "should upload data with :get" do
  108. data = "upload data"
  109. response = @session.request(:get, "/test", {}, :data => data)
  110. body = YAML::load(response.body)
  111. expect(body.request_method).to be == "GET"
  112. expect(body.header['content-length']).to be == [data.size.to_s]
  113. end
  114. it "should upload data with :put" do
  115. data = "upload data"
  116. response = @session.put("/test", data)
  117. body = YAML::load(response.body)
  118. expect(body.request_method).to be == "PUT"
  119. expect(body.header['content-length']).to be == [data.size.to_s]
  120. end
  121. it "should raise when no data is provided to :put" do
  122. expect { @session.put("/test", nil) }.to raise_error(ArgumentError)
  123. end
  124. it "should upload a file with :put" do
  125. response = @session.put_file("/test", "LICENSE")
  126. body = YAML::load(response.body)
  127. expect(body.request_method).to be == "PUT"
  128. end
  129. it "should raise when no file is provided to :put" do
  130. expect { @session.put_file("/test", nil) }.to raise_error(ArgumentError)
  131. end
  132. it "should use chunked encoding when uploading a file with :put" do
  133. response = @session.put_file("/test", "LICENSE")
  134. body = YAML::load(response.body)
  135. expect(body.header['transfer-encoding'].first).to be == "chunked"
  136. end
  137. it "should upload data with :post" do
  138. data = "upload data"
  139. response = @session.post("/test", data)
  140. body = YAML::load(response.body)
  141. expect(body.request_method).to be == "POST"
  142. expect(body.header['content-length']).to be == [data.size.to_s]
  143. end
  144. it "should post a hash of arguments as a urlencoded form" do
  145. data = {:foo => 123, 'baz' => '++hello world++'}
  146. response = @session.post("/testpost", data)
  147. body = YAML::load(response.body)
  148. expect(body['content_type']).to be == "application/x-www-form-urlencoded"
  149. expect(body['body']).to match(/baz=%2B%2Bhello%20world%2B%2B/)
  150. expect(body['body']).to match(/foo=123/)
  151. end
  152. it "should raise when no data is provided to :post" do
  153. expect { @session.post("/test", nil) }.to raise_error(ArgumentError)
  154. end
  155. it "should upload a file with :post" do
  156. response = @session.post_file("/test", "LICENSE")
  157. body = YAML::load(response.body)
  158. expect(body.request_method).to be == "POST"
  159. end
  160. it "should upload a multipart with :post" do
  161. response = @session.post_multipart("/test", { :test_data => "123" }, { :test_file => "LICENSE" } )
  162. body = YAML::load(response.body)
  163. expect(body.request_method).to be == "POST"
  164. end
  165. it "should raise when no file is provided to :post" do
  166. expect { @session.post_file("/test", nil) }.to raise_error(ArgumentError)
  167. end
  168. it "should use chunked encoding when uploading a file with :post" do
  169. response = @session.post_file("/test", "LICENSE")
  170. body = YAML::load(response.body)
  171. expect(body.header['transfer-encoding'].first).to be == "chunked"
  172. end
  173. it "should handle cookies if set" do
  174. @session.handle_cookies
  175. response = @session.get("/setcookie").body
  176. expect(YAML::load(response).header['cookie'].first).to be == "session_id=foo123"
  177. end
  178. it "should not handle cookies by default" do
  179. response = @session.get("/setcookie").body
  180. expect(YAML::load(response).header).to_not include('cookie')
  181. end
  182. it "should raise exception if cookie store is not writable or readable" do
  183. expect { @session.handle_cookies("/trash/clash/foo") }.to raise_error(ArgumentError)
  184. end
  185. it "should work with multiple threads" do
  186. threads = []
  187. 3.times do
  188. threads << Thread.new do
  189. session = Patron::Session.new
  190. session.base_url = "https://localhost:9043"
  191. session.insecure = true
  192. session.post_file("/test", "LICENSE")
  193. end
  194. end
  195. threads.each {|t| t.join }
  196. end
  197. it "should fail when insecure mode is off" do
  198. expect {
  199. @session.insecure = nil
  200. response = @session.get("/test")
  201. }.to raise_error(Patron::Error)
  202. end
  203. it "should work when insecure mode is off but certificate is supplied" do
  204. @session.insecure = nil
  205. @session.cacert = File.join(__dir__, 'support', 'certs', 'cacert.pem')
  206. response = @session.get("/test")
  207. body = YAML::load(response.body)
  208. expect(body.request_method).to be == "GET"
  209. end
  210. it "should work with different SSL versions" do
  211. ['TLSv1_0','TLSv1_1'].each do |version|
  212. @session.ssl_version = version
  213. response = @session.get("/test")
  214. expect(response.status).to be == 200
  215. end
  216. end
  217. it "should raise when an unsupported or unknown SSL version is requested" do
  218. ['something', 1].each do |version|
  219. @session.ssl_version = version
  220. expect {
  221. @session.get("/test")
  222. }.to raise_error(Patron::UnsupportedSSLVersion)
  223. end
  224. end
  225. it "should work with different HTTP versions" do
  226. ['HTTPv1_0','HTTPv1_1'].each do |version|
  227. @session.http_version = version
  228. response = @session.get("/test")
  229. expect(response.status).to be == 200
  230. end
  231. end
  232. it "should raise when an unsupported or unknown HTTP version is requested" do
  233. ['something', 1].each do |version|
  234. @session.http_version = version
  235. expect {
  236. @session.get("/test")
  237. }.to raise_error(Patron::UnsupportedHTTPVersion)
  238. end
  239. end
  240. # ------------------------------------------------------------------------
  241. describe 'when debug is enabled' do
  242. it 'it should not clobber stderr' do
  243. rdev = STDERR.stat.rdev
  244. @session.enable_debug
  245. expect(STDERR.stat.rdev).to be == rdev
  246. @session.enable_debug
  247. expect(STDERR.stat.rdev).to be == rdev
  248. end
  249. end
  250. end