Class: Http2

Inherits:
Object
  • Object
show all
Defined in:
lib/http2.rb

Overview

This class tries to emulate a browser in Ruby without any visual stuff. Remember cookies, keep sessions alive, reset connections according to keep-alive rules and more.

Examples

Http2.new(host: “www.somedomain.com”, port: 80, ssl: false, debug: false) do |http|

res = http.get("index.rhtml?show=some_page")
html = res.body
print html

res = res.post("index.rhtml?choice=login", {"username" => "John Doe", "password" => 123})
print res.body
print "#{res.headers}"

end

Constant Summary collapse

VALID_ARGUMENTS_INITIALIZE =
[:host, :port, :skip_port_in_host_header, :ssl, :nl, :user_agent, :raise_errors, :follow_redirects, :debug, :encoding_gzip, :autostate, :basic_auth, :extra_headers, :proxy]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Http2

Returns a new instance of Http2.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/http2.rb', line 36

def initialize(args = {})
  @args = parse_init_args(args)
  set_default_values
  @cookies = {}
  @mutex = Monitor.new

  @connection = ::Http2::Connection.new(self)

  if block_given?
    begin
      yield(self)
    ensure
      self.destroy
    end
  end
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



32
33
34
# File 'lib/http2.rb', line 32

def args
  @args
end

#autostateObject (readonly)

Returns the value of attribute autostate.



32
33
34
# File 'lib/http2.rb', line 32

def autostate
  @autostate
end

#connectionObject (readonly)

Returns the value of attribute connection.



32
33
34
# File 'lib/http2.rb', line 32

def connection
  @connection
end

#cookiesObject (readonly)

Returns the value of attribute cookies.



32
33
34
# File 'lib/http2.rb', line 32

def cookies
  @cookies
end

#debugObject (readonly)

Returns the value of attribute debug.



32
33
34
# File 'lib/http2.rb', line 32

def debug
  @debug
end

#keepalive_maxObject

Returns the value of attribute keepalive_max.



33
34
35
# File 'lib/http2.rb', line 33

def keepalive_max
  @keepalive_max
end

#keepalive_timeoutObject

Returns the value of attribute keepalive_timeout.



33
34
35
# File 'lib/http2.rb', line 33

def keepalive_timeout
  @keepalive_timeout
end

#mutexObject (readonly)

Returns the value of attribute mutex.



32
33
34
# File 'lib/http2.rb', line 32

def mutex
  @mutex
end

#nlObject (readonly)

Returns the value of attribute nl.



32
33
34
# File 'lib/http2.rb', line 32

def nl
  @nl
end

#raise_errorsObject (readonly)

Returns the value of attribute raise_errors.



32
33
34
# File 'lib/http2.rb', line 32

def raise_errors
  @raise_errors
end

#respObject (readonly)

Returns the value of attribute resp.



32
33
34
# File 'lib/http2.rb', line 32

def resp
  @resp
end

Class Method Details

.const_missing(name) ⇒ Object

Autoloader for subclasses.



19
20
21
22
# File 'lib/http2.rb', line 19

def self.const_missing(name)
  require "#{File.dirname(__FILE__)}/../include/#{::StringCases.camel_to_snake(name)}.rb"
  return Http2.const_get(name)
end

Converts a URL to “is.gd”-short-URL.



25
26
27
28
29
30
# File 'lib/http2.rb', line 25

def self.isgdlink(url)
  Http2.new(host: "is.gd") do |http|
    resp = http.get("/api.php?longurl=#{url}")
    return resp.body
  end
end

Instance Method Details

#change(args) ⇒ Object

Closes current connection if any, changes the arguments on the object and reconnects keeping all cookies and other stuff intact.



75
76
77
78
79
# File 'lib/http2.rb', line 75

def change(args)
  @args.merge!(args)
  @connection.destroy
  @connection = ::Http2::Connection.new(self)
end


189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/http2.rb', line 189

def cookie_header_string
  cstr = ""

  first = true
  @cookies.each do |cookie_name, cookie_data|
    cstr << "; " unless first
    first = false if first

    if cookie_data.is_a?(Hash)
      name = cookie_data["name"]
      value = cookie_data["value"]
    else
      name = cookie_name
      value = cookie_data
    end

    raise "Unexpected lines: #{value.lines.to_a.length}." if value.lines.to_a.length != 1
    cstr << "#{Http2::Utils.urlenc(name)}=#{Http2::Utils.urlenc(value)}"
  end

  return cstr
end

#default_headers(args = {}) ⇒ Object

Returns the default headers for a request.

Examples

headers_hash = http.default_headers print “#headers_hash”



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/http2.rb', line 137

def default_headers(args = {})
  return args[:default_headers] if args[:default_headers]

  headers = {
    "Connection" => "Keep-Alive",
    "User-Agent" => @uagent
  }

  #Possible to give custom host-argument.
  host = args[:host] || self.host
  port = args[:port] || self.port

  headers["Host"] = "#{host}" # Copy host string to avoid changing the original string if port has been given!
  headers["Host"] << ":#{port}" if port && ![80, 443].include?(port.to_i) && !@args[:skip_port_in_host_header]
  headers["Accept-Encoding"] = "gzip" if @args[:encoding_gzip]

  if @args[:basic_auth]
    require "base64" unless ::Kernel.const_defined?(:Base64)
    headers["Authorization"] = "Basic #{Base64.encode64("#{@args[:basic_auth][:user]}:#{@args[:basic_auth][:passwd]}").strip}"
  end

  headers.merge!(@args[:extra_headers]) if @args[:extra_headers]
  headers.merge!(args[:headers]) if args[:headers]
  return headers
end

#delete(args) ⇒ Object

Proxies the request to another method but forces the method to be “DELETE”.



125
126
127
128
129
130
131
# File 'lib/http2.rb', line 125

def delete(args)
  if args[:json]
    return post(args.merge(method: :delete))
  else
    return get(args.merge(method: :delete))
  end
end

#destroyObject

Destroys the object unsetting all variables and closing all sockets.

Examples

http.destroy



84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/http2.rb', line 84

def destroy
  @args = nil
  @cookies = nil
  @debug = nil
  @mutex = nil
  @uagent = nil
  @keepalive_timeout = nil
  @request_last = nil

  @connection.destroy
  @connection = nil
end

#get(args) ⇒ Object

Returns a result-object based on the arguments.

Examples

res = http.get(“somepage.html”) print res.body #=> <String>-object containing the HTML gotten.



120
121
122
# File 'lib/http2.rb', line 120

def get(args)
  ::Http2::GetRequest.new(self, args).execute
end

#header_str(headers_hash, args = {}) ⇒ Object

Returns a header-string which normally would be used for a request in the given state.



178
179
180
181
182
183
184
185
186
187
# File 'lib/http2.rb', line 178

def header_str(headers_hash, args = {})
  headers_hash["Cookie"] = cookie_header_string

  headers_str = ""
  headers_hash.each do |key, val|
    headers_str << "#{key}: #{val}#{@nl}"
  end

  return headers_str
end

#hostObject



53
54
55
# File 'lib/http2.rb', line 53

def host
  @args[:host]
end

#inspectObject



227
228
229
# File 'lib/http2.rb', line 227

def inspect
  to_s
end

#new_urlObject



65
66
67
68
69
70
71
72
# File 'lib/http2.rb', line 65

def new_url
  builder = Http2::UrlBuilder.new
  builder.host = host
  builder.port = port
  builder.protocol = @args[:protocol]

  return builder
end

#on_content_call(args, str) ⇒ Object



212
213
214
# File 'lib/http2.rb', line 212

def on_content_call(args, str)
  args[:on_content].call(str) if args.key?(:on_content)
end

#parse_args(*args) ⇒ Object

Forces various stuff into arguments-hash like URL from original arguments and enables single-string-shortcuts and more.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/http2.rb', line 98

def parse_args(*args)
  if args.length == 1 && args.first.is_a?(String)
    args = {url: args.first}
  elsif args.length >= 2
    raise "Couldnt parse arguments."
  elsif args.is_a?(Array) && args.length == 1
    args = args.first
  else
    raise "Invalid arguments: '#{args.class.name}'."
  end

  if args[:url].to_s.split("\n").length != 1
    raise "Invalid URL: '#{args[:url]}'."
  end

  return args
end

#portObject



57
58
59
# File 'lib/http2.rb', line 57

def port
  @args[:port]
end

#post(args) ⇒ Object

Posts to a certain page.

Examples

res = http.post(“login.php”, {“username” => “John Doe”, “password” => 123)



166
167
168
# File 'lib/http2.rb', line 166

def post(args)
  ::Http2::PostRequest.new(self, args).execute
end

#post_multipart(*args) ⇒ Object

Posts to a certain page using the multipart-method.

Examples

res = http.post_multipart(“upload.php”, => 123, “file” => Tempfile.new(?))



173
174
175
# File 'lib/http2.rb', line 173

def post_multipart(*args)
  ::Http2::PostMultipartRequest.new(self, *args).execute
end

#read_response(args = {}) ⇒ Object

Reads the response after posting headers and data.

Examples

res = http.read_response



219
220
221
# File 'lib/http2.rb', line 219

def read_response(args = {})
  ::Http2::ResponseReader.new(http2: self, sock: @sock, args: args).response
end

#reconnectObject



61
62
63
# File 'lib/http2.rb', line 61

def reconnect
  @connection.reconnect
end

#to_sObject



223
224
225
# File 'lib/http2.rb', line 223

def to_s
  "<Http2 host: #{host}:#{port}>"
end