Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/spec/lib/rex/proto/http/client_request_spec.rb
Views: 11789
# -*- coding:binary -*-1require 'spec_helper'2345RSpec.shared_context "with no evasions" do6before(:example) do7client_request.opts['uri_dir_self_reference'] = false8client_request.opts['uri_fake_params_start'] = false9client_request.opts['uri_full_url'] = false10end1112it "should return the unmodified uri" do13expect(client_request.send(:set_uri)).to eq "/"14end15end161718RSpec.shared_context "with 'uri_dir_self_reference'" do19before(:example) do20client_request.opts['uri_dir_self_reference'] = true21end2223it "should have a self reference" do24expect(client_request.send(:set_uri)).to include("/./")25expect(client_request.to_s).to include("/./")26end27end282930RSpec.shared_context "with 'uri_dir_fake_relative'" do31before(:example) do32client_request.opts['uri_dir_fake_relative'] = true33end3435it "should contain sequences of '../'" do36expect(client_request.send(:set_uri)).to include("../")37expect(client_request.to_s).to include("../")38end3940end414243RSpec.shared_context "with 'uri_full_url'" do4445before(:example) do46client_request.opts['uri_full_url'] = true47end4849before(:example) do50client_request.opts['vhost'] = host51end5253context "with ipv4 host" do54let(:host) { '192.0.2.1' }5556it_behaves_like "uri_full_url"57end5859context "with ipv6 host" do60let(:host) { '2001:DB8::1' }6162it_behaves_like "uri_full_url"63end6465context "with dns host" do66let(:host) { 'www.example.com' }6768it_behaves_like "uri_full_url"69end7071end7273RSpec.shared_examples "uri_full_url" do7475it "#set_uri should have the host in the URI" do76expect(client_request.send(:set_uri)).to start_with("http://#{host}/")77end7879end808182RSpec.describe Rex::Proto::Http::ClientRequest do8384default_options = {85# All of these should be what you get when you pass in empty86# options, but of course that would make it too easy87'uri' => '/',88'method' => "GET",89'proto' => "HTTP",90'connection' => "close",91'version' => "1.1",92'port' => 80,93}9495[96[ "with reasonable default options",97default_options.merge({98'agent' => "Mozilla/4.0 (compatible; Metasploit RSPEC)",99'vhost' => 'www.example.com',100}),101{102:set_uri => { :result => "/" },103:set_method => { :result => "GET" },104:set_version => { :result => "HTTP/1.1\r\n" },105:set_uri_prepend => { :result => "" },106:set_uri_append => { :result => "" },107:set_agent_header => { :result => "User-Agent: Mozilla/4.0 (compatible; Metasploit RSPEC)\r\n" },108:set_host_header => { :result => "Host: www.example.com\r\n" },109:set_formatted_header => { :args => ["Foo\twith\tabs", "Bar"], :result => "Foo\twith\tabs: Bar\r\n" },110}111],112113[ "with header folding",114default_options.merge({115'agent' => "Mozilla/4.0 (compatible; Metasploit RSPEC)",116'header_folding' => true,117}),118{119:set_uri => { :result => "/" },120:set_method => { :result => "GET" },121:set_version => { :result => "HTTP/1.1\r\n" },122:set_agent_header => { :result => "User-Agent:\r\n\tMozilla/4.0 (compatible; Metasploit RSPEC)\r\n" },123:set_cookie_header => { :result => "" },124:set_connection_header => { :result => "Connection:\r\n\tclose\r\n" },125:set_formatted_header => { :args => ["Foo\twith\tabs", "Bar"], :result => "Foo\twith\tabs:\r\n\tBar\r\n" },126}127],128129[ "with ipv6 host",130default_options.merge({131'vhost' => "2001:DB8::1",132}),133{134:set_host_header => { :result => "Host: [2001:DB8::1]\r\n" },135}136],137138[ "with ipv6 host and non-default port",139default_options.merge({140'port' => 1234,141'vhost' => "2001:DB8::1",142}),143{144:set_host_header => { :result => "Host: [2001:DB8::1]:1234\r\n" },145}146],147148[149"with modified Content-Length header",150default_options.merge({151'headers' => { 'Content-Length' => 1337 }152}),153{154:set_content_len_header => { args: 0, result: ''}155}156],157158[159"with 1024 bytes of Content-Length",160default_options,161{162:set_content_len_header => { args: 1024, result: "Content-Length: 1024\r\n"}163}164],165166[167"with a POST request and no payload body",168default_options.merge({169'method' => 'POST'170}),171{172:set_content_len_header => { args: 0, result: "Content-Length: 0\r\n"}173}174],175176].each do |c, opts, expectations|177context c do178subject(:client_request) { Rex::Proto::Http::ClientRequest.new(opts) }179180expectations.each do |meth, things|181args = things[:args] || []182result = things[:result]183describe "##{meth}" do184it "should return #{result.inspect}" do185expect(client_request.send(meth, *args)).to eq result186end187end188end189190end191end192193subject(:client_request) { Rex::Proto::Http::ClientRequest.new(default_options) }194195context "with GET parameters" do196subject(:client_request) {197options_with_params = default_options.merge({198'uri_encode_mode' => encode_mode,199'encode_params' => encode_params,200'encode' => false,201'vars_get' => vars_get,202})203Rex::Proto::Http::ClientRequest.new(options_with_params)204}205# default206let(:encode_mode) { 'hex-normal' }207208let(:vars_get) do209{210'foo[]' => 'bar',211'bar' => 'baz',212'frobnicate' => 'the froozle?',213'foshizzle' => 'my/nizzle',214'asdf' => nil,215'test' => ''216}217end218219context "with 'pad_get_params'" do220let(:encode_params) { true }221it "should ..." do222old = client_request.opts['pad_get_params']223client_request.opts['pad_get_params'] = true224225client_request.opts['pad_get_params_count'] = 0226expect(client_request.to_s.split("&").length).to eq vars_get.length227228client_request.opts['pad_get_params_count'] = 10229expect(client_request.to_s.split("&").length).to eq vars_get.length + 10230231client_request.opts['pad_get_params'] = old232end233end234235context "without 'encode_params'" do236let(:encode_params) { false }237it "should contain the unaltered params" do238str = client_request.to_s239expect(str).to include("foo[]=bar")240expect(str).to include("bar=baz")241expect(str).to include("frobnicate=the froozle?")242expect(str).to include("foshizzle=my/nizzle")243expect(str).to include("asdf&")244expect(str).to include("test=")245end246end247248context "with 'encode_params'" do249let(:encode_params) { true }250context "and 'uri_encode_mode' = default (hex-normal)" do251it "should encode special chars" do252str = client_request.to_s253expect(str).to include("foo%5b%5d=bar")254expect(str).to include("bar=baz")255expect(str).to include("frobnicate=the%20froozle%3f")256expect(str).to include("foshizzle=my/nizzle")257expect(str).to include("asdf&")258expect(str).to include("test=")259end260end261262context "and 'uri_encode_mode' = hex-noslashes" do263let(:encode_mode) { 'hex-noslashes' }264it "should encode all chars" do265str = client_request.to_s266expect(str).to include("%66%6f%6f%5b%5d=%62%61%72")267expect(str).to include("%62%61%72=%62%61%7a")268expect(str).to include("%66%72%6f%62%6e%69%63%61%74%65=%74%68%65%20%66%72%6f%6f%7a%6c%65%3f")269expect(str).to include("%66%6f%73%68%69%7a%7a%6c%65=%6d%79/%6e%69%7a%7a%6c%65")270end271end272273context "and 'uri_encode_mode' = hex-all" do274let(:encode_mode) { 'hex-all' }275it "should encode all chars" do276str = client_request.to_s277expect(str).to include("%66%6f%6f%5b%5d=%62%61%72")278expect(str).to include("%62%61%72=%62%61%7a")279expect(str).to include("%66%72%6f%62%6e%69%63%61%74%65=%74%68%65%20%66%72%6f%6f%7a%6c%65%3f")280expect(str).to include("%66%6f%73%68%69%7a%7a%6c%65=%6d%79%2f%6e%69%7a%7a%6c%65")281end282end283284describe "#to_s" do285it "should produce same values if called multiple times with same options" do286expect(client_request.to_s).to eq client_request.to_s287end288end289290end291292end293294describe "#set_uri" do295it_behaves_like "with 'uri_full_url'"296it_behaves_like "with 'uri_dir_self_reference'"297it_behaves_like "with 'uri_dir_fake_relative'"298it_behaves_like "with no evasions"299end300301end302303304