Class: BetterCap::Proxy::HTTP::Request
- Inherits:
-
Object
- Object
- BetterCap::Proxy::HTTP::Request
- Defined in:
- lib/bettercap/proxy/http/request.rb
Overview
HTTP request parser.
Instance Attribute Summary collapse
-
#body ⇒ Object
Request body.
-
#client ⇒ Object
Client address.
-
#content_length ⇒ Object
readonly
Content length.
-
#headers ⇒ Object
readonly
Request headers hash.
-
#host ⇒ Object
readonly
Hostname.
-
#method ⇒ Object
readonly
HTTP method.
-
#path ⇒ Object
readonly
Request path + query.
-
#port ⇒ Object
Request port.
-
#version ⇒ Object
readonly
HTTP version.
Class Method Summary collapse
-
.parse(raw) ⇒ Object
Return a Request object from a
raw
string.
Instance Method Summary collapse
-
#<<(line) ⇒ Object
Parse a single request line, patch it if needed and append it to #lines.
-
#[](name) ⇒ Object
Return the value of header with
name
or an empty string. -
#[]=(name, value) ⇒ Object
If the header with
name
is found, then avalue
is assigned to it. -
#base_url ⇒ Object
Return SCHEMA://HOST.
-
#initialize(default_port = 80) ⇒ Request
constructor
Initialize this object setting #port to
default_port
. -
#post? ⇒ Boolean
Return true if this is a POST request, otherwise false.
-
#read(sock) ⇒ Object
Read lines from the
sock
socket and parse them. -
#to_s ⇒ Object
Return a string representation of the HTTP request.
-
#to_url(max_length = 50) ⇒ Object
Return the full request URL trimming it at
max_length
characters.
Constructor Details
#initialize(default_port = 80) ⇒ Request
Initialize this object setting #port to default_port
.
40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/bettercap/proxy/http/request.rb', line 40 def initialize( default_port = 80 ) @lines = [] @method = nil @version = '1.1' @path = nil @host = nil @port = default_port @headers = {} @content_length = 0 @body = nil @client = "" end |
Instance Attribute Details
#body ⇒ Object
Request body.
35 36 37 |
# File 'lib/bettercap/proxy/http/request.rb', line 35 def body @body end |
#client ⇒ Object
Client address.
37 38 39 |
# File 'lib/bettercap/proxy/http/request.rb', line 37 def client @client end |
#content_length ⇒ Object (readonly)
Content length.
33 34 35 |
# File 'lib/bettercap/proxy/http/request.rb', line 33 def content_length @content_length end |
#headers ⇒ Object (readonly)
Request headers hash.
31 32 33 |
# File 'lib/bettercap/proxy/http/request.rb', line 31 def headers @headers end |
#host ⇒ Object (readonly)
Hostname.
27 28 29 |
# File 'lib/bettercap/proxy/http/request.rb', line 27 def host @host end |
#method ⇒ Object (readonly)
HTTP method.
21 22 23 |
# File 'lib/bettercap/proxy/http/request.rb', line 21 def method @method end |
#path ⇒ Object (readonly)
Request path + query.
25 26 27 |
# File 'lib/bettercap/proxy/http/request.rb', line 25 def path @path end |
#port ⇒ Object
Request port.
29 30 31 |
# File 'lib/bettercap/proxy/http/request.rb', line 29 def port @port end |
#version ⇒ Object (readonly)
HTTP version.
23 24 25 |
# File 'lib/bettercap/proxy/http/request.rb', line 23 def version @version end |
Class Method Details
.parse(raw) ⇒ Object
Return a Request object from a raw
string.
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/bettercap/proxy/http/request.rb', line 77 def self.parse(raw) req = Request.new lines = raw.split("\n") lines.each_with_index do |line,i| req << line if line.chomp == '' req.body = lines[i + 1..lines.size].join("\n") break end end req end |
Instance Method Details
#<<(line) ⇒ Object
Parse a single request line, patch it if needed and append it to #lines.
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 |
# File 'lib/bettercap/proxy/http/request.rb', line 91 def <<(line) line = line.chomp Logger.debug " REQUEST LINE: '#{line}'" # is this the first line '<VERB> <URI> HTTP/<VERSION>' ? if line =~ /^(\w+)\s+(\S+)\s+HTTP\/([\d\.]+)\s*$/ @method = $1 @path = $2 @version = $3 # fix url if @path.include? '://' uri = URI::parse @path @path = "#{uri.path}" + ( uri.query ? "?#{uri.query}" : '' ) end # collect and fix headers elsif line =~ /^([^:\s]+)\s*:\s*(.+)$/i name = $1 value = $2 case name when 'Host' @host = value if @host =~ /([^:]*):([0-9]*)$/ @host = $1 @port = $2.to_i end when 'Content-Length' @content_length = value.to_i # we don't want to have hundreds of threads running when 'Connection' value = 'close' when 'Proxy-Connection' name = 'Connection' # disable gzip, chunked, etc encodings when 'Accept-Encoding' value = 'identity' end @headers[name] = value end end |
#[](name) ⇒ Object
Return the value of header with name
or an empty string.
169 170 171 |
# File 'lib/bettercap/proxy/http/request.rb', line 169 def [](name) ( @headers.has_key?(name) ? @headers[name] : "" ) end |
#[]=(name, value) ⇒ Object
If the header with name
is found, then a value
is assigned to it. If value
is null and the header is found, it will be removed.
175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/bettercap/proxy/http/request.rb', line 175 def []=(name, value) if @headers.has_key?(name) if value.nil? @headers.delete(name) else @headers[name] = value end elsif !value.nil? @headers[name] = value end @host = value if name == 'Host' end |
#base_url ⇒ Object
Return SCHEMA://HOST
155 156 157 |
# File 'lib/bettercap/proxy/http/request.rb', line 155 def base_url "#{port == 443 ? 'https' : 'http'}://#{@host}" end |
#post? ⇒ Boolean
Return true if this is a POST request, otherwise false.
137 138 139 |
# File 'lib/bettercap/proxy/http/request.rb', line 137 def post? @method == 'POST' end |
#read(sock) ⇒ Object
Read lines from the sock
socket and parse them. Will raise an exception if the #hostname can not be parsed.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/bettercap/proxy/http/request.rb', line 55 def read(sock) # read the first line self << sock.readline loop do line = sock.readline self << line if line.chomp == '' break end end raise "Couldn't extract host from the request." unless @host # keep reading the request body if needed if @content_length > 0 @body = sock.read(@content_length) end end |
#to_s ⇒ Object
Return a string representation of the HTTP request.
142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/bettercap/proxy/http/request.rb', line 142 def to_s raw = "#{@method} #{@path} HTTP/#{@version}\n" @headers.each do |name,value| raw << "#{name}: #{value}\n" end raw << "\n" raw << ( @body || '' ) raw end |
#to_url(max_length = 50) ⇒ Object
Return the full request URL trimming it at max_length
characters.
160 161 162 163 164 165 166 |
# File 'lib/bettercap/proxy/http/request.rb', line 160 def to_url(max_length = 50) url = "#{base_url}#{@path}" unless max_length.nil? url = url.slice(0..max_length) + '...' unless url.length <= max_length end url end |