PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/spec/lib/rex/proto/http/client_request_spec.rb

https://gitlab.com/leijianbin/metasploit-framework
Ruby | 259 lines | 206 code | 49 blank | 4 comment | 7 complexity | f55bc096d7edf0fa12b51f1464a66f43 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, GPL-2.0, LGPL-2.1
  1. # -*- coding:binary -*-
  2. require 'spec_helper'
  3. require 'rex/proto/http/client_request'
  4. shared_context "with no evasions" do
  5. before(:each) do
  6. client_request.opts['uri_dir_self_reference'] = false
  7. client_request.opts['uri_fake_params_start'] = false
  8. client_request.opts['uri_full_url'] = false
  9. end
  10. it "should return the unmodified uri" do
  11. client_request.send(:set_uri).should == "/"
  12. end
  13. end
  14. shared_context "with 'uri_dir_self_reference'" do
  15. before(:each) do
  16. client_request.opts['uri_dir_self_reference'] = true
  17. end
  18. it "should have a self reference" do
  19. client_request.send(:set_uri).should include("/./")
  20. client_request.to_s.should include("/./")
  21. end
  22. end
  23. shared_context "with 'uri_dir_fake_relative'" do
  24. before(:each) do
  25. client_request.opts['uri_dir_fake_relative'] = true
  26. end
  27. it "should contain sequences of '../'" do
  28. client_request.send(:set_uri).should include("../")
  29. client_request.to_s.should include("../")
  30. end
  31. end
  32. shared_context "with 'uri_full_url'" do
  33. before(:each) do
  34. client_request.opts['uri_full_url'] = true
  35. end
  36. before(:each) do
  37. client_request.opts['vhost'] = host
  38. end
  39. context "with ipv4 host" do
  40. let(:host) { '192.0.2.1' }
  41. it_behaves_like "uri_full_url"
  42. end
  43. context "with ipv6 host" do
  44. let(:host) { '2001:DB8::1' }
  45. it_behaves_like "uri_full_url"
  46. end
  47. context "with dns host" do
  48. let(:host) { 'www.example.com' }
  49. it_behaves_like "uri_full_url"
  50. end
  51. end
  52. shared_examples "uri_full_url" do
  53. it "#set_uri should have the host in the URI" do
  54. client_request.send(:set_uri).should start_with("http://#{host}/")
  55. end
  56. end
  57. describe Rex::Proto::Http::ClientRequest do
  58. default_options = {
  59. # All of these should be what you get when you pass in empty
  60. # options, but of course that would make it too easy
  61. 'uri' => '/',
  62. 'method' => "GET",
  63. 'proto' => "HTTP",
  64. 'connection' => "close",
  65. 'version' => "1.1",
  66. 'port' => 80,
  67. }
  68. [
  69. [ "with reasonable default options",
  70. default_options.merge({
  71. 'agent' => "Mozilla/4.0 (compatible; Metasploit RSPEC)",
  72. 'vhost' => 'www.example.com',
  73. }),
  74. {
  75. :set_uri => { :result => "/" },
  76. :set_method => { :result => "GET" },
  77. :set_version => { :result => "HTTP/1.1\r\n" },
  78. :set_uri_prepend => { :result => "" },
  79. :set_uri_append => { :result => "" },
  80. :set_agent_header => { :result => "User-Agent: Mozilla/4.0 (compatible; Metasploit RSPEC)\r\n" },
  81. :set_host_header => { :result => "Host: www.example.com\r\n" },
  82. :set_formatted_header => { :args => ["Foo", "Bar"], :result => "Foo: Bar\r\n" },
  83. :set_formatted_header => { :args => ["foo", "Bar"], :result => "foo: Bar\r\n" },
  84. :set_formatted_header => { :args => ["Foo", "Bar\twith\ttabs"], :result => "Foo: Bar\twith\ttabs\r\n" },
  85. :set_formatted_header => { :args => ["Foo\twith\tabs", "Bar"], :result => "Foo\twith\tabs: Bar\r\n" },
  86. }
  87. ],
  88. [ "with header folding",
  89. default_options.merge({
  90. 'agent' => "Mozilla/4.0 (compatible; Metasploit RSPEC)",
  91. 'header_folding' => true,
  92. }),
  93. {
  94. :set_uri => { :result => "/" },
  95. :set_method => { :result => "GET" },
  96. :set_version => { :result => "HTTP/1.1\r\n" },
  97. :set_agent_header => { :result => "User-Agent:\r\n\tMozilla/4.0 (compatible; Metasploit RSPEC)\r\n" },
  98. :set_cookie_header => { :result => "" },
  99. :set_connection_header => { :result => "Connection:\r\n\tclose\r\n" },
  100. :set_formatted_header => { :args => ["Foo", "Bar"], :result => "Foo:\r\n\tBar\r\n" },
  101. :set_formatted_header => { :args => ["foo", "Bar"], :result => "foo:\r\n\tBar\r\n" },
  102. :set_formatted_header => { :args => ["Foo", "Bar\twith\ttabs"], :result => "Foo:\r\n\tBar\twith\ttabs\r\n" },
  103. :set_formatted_header => { :args => ["Foo\twith\tabs", "Bar"], :result => "Foo\twith\tabs:\r\n\tBar\r\n" },
  104. }
  105. ],
  106. [ "with ipv6 host",
  107. default_options.merge({
  108. 'vhost' => "2001:DB8::1",
  109. }),
  110. {
  111. :set_host_header => { :result => "Host: [2001:DB8::1]\r\n" },
  112. }
  113. ],
  114. [ "with ipv6 host and non-default port",
  115. default_options.merge({
  116. 'port' => 1234,
  117. 'vhost' => "2001:DB8::1",
  118. }),
  119. {
  120. :set_host_header => { :result => "Host: [2001:DB8::1]:1234\r\n" },
  121. }
  122. ]
  123. ].each do |c, opts, expectations|
  124. context c do
  125. subject(:client_request) { Rex::Proto::Http::ClientRequest.new(opts) }
  126. expectations.each do |meth, things|
  127. args = things[:args] || []
  128. result = things[:result]
  129. describe "##{meth}" do
  130. it "should return #{result.inspect}" do
  131. client_request.send(meth, *args).should == result
  132. end
  133. end
  134. end
  135. end
  136. end
  137. subject(:client_request) { Rex::Proto::Http::ClientRequest.new(default_options) }
  138. context "with GET paramaters" do
  139. subject(:client_request) {
  140. options_with_params = default_options.merge({
  141. 'uri_encode_mode' => encode_mode,
  142. 'encode_params' => encode_params,
  143. 'encode' => false,
  144. 'vars_get' => vars_get,
  145. })
  146. Rex::Proto::Http::ClientRequest.new(options_with_params)
  147. }
  148. # default
  149. let(:encode_mode) { 'hex-normal' }
  150. let(:vars_get) do
  151. {
  152. 'foo[]' => 'bar',
  153. 'bar' => 'baz',
  154. 'frobnicate' => 'the froozle?',
  155. }
  156. end
  157. context "with 'pad_get_params'" do
  158. let(:encode_params) { true }
  159. it "should ..." do
  160. old = client_request.opts['pad_get_params']
  161. client_request.opts['pad_get_params'] = true
  162. client_request.opts['pad_get_params_count'] = 0
  163. client_request.to_s.split("&").length.should == vars_get.length
  164. client_request.opts['pad_get_params_count'] = 10
  165. client_request.to_s.split("&").length.should == vars_get.length + 10
  166. client_request.opts['pad_get_params'] = old
  167. end
  168. end
  169. context "without 'encode_params'" do
  170. let(:encode_params) { false }
  171. it "should contain the unaltered params" do
  172. str = client_request.to_s
  173. str.should include("foo[]=bar")
  174. str.should include("bar=baz")
  175. str.should include("frobnicate=the froozle?")
  176. end
  177. end
  178. context "with 'encode_params'" do
  179. let(:encode_params) { true }
  180. context "and 'uri_encode_mode' = default (hex-normal)" do
  181. it "should encode special chars" do
  182. str = client_request.to_s
  183. str.should include("foo%5b%5d=bar")
  184. str.should include("bar=baz")
  185. str.should include("frobnicate=the%20froozle%3f")
  186. end
  187. end
  188. context "and 'uri_encode_mode' = hex-all" do
  189. let(:encode_mode) { 'hex-all' }
  190. it "should encode all chars" do
  191. str = client_request.to_s
  192. str.should include("%66%6f%6f%5b%5d=%62%61%72")
  193. str.should include("%62%61%72=%62%61%7a")
  194. str.should include("%66%72%6f%62%6e%69%63%61%74%65=%74%68%65%20%66%72%6f%6f%7a%6c%65%3f")
  195. end
  196. end
  197. describe "#to_s" do
  198. it "should produce same values if called multiple times with same options" do
  199. client_request.to_s.should == client_request.to_s
  200. end
  201. end
  202. end
  203. end
  204. describe "#set_uri" do
  205. it_behaves_like "with 'uri_full_url'"
  206. it_behaves_like "with 'uri_dir_self_reference'"
  207. it_behaves_like "with 'uri_dir_fake_relative'"
  208. it_behaves_like "with no evasions"
  209. end
  210. end