lib/knj/http2.rb in knjrbfw-0.0.29 vs lib/knj/http2.rb in knjrbfw-0.0.30
- old
+ new
@@ -1,7 +1,18 @@
require "#{$knjpath}web"
+#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
+# Knj::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
class Knj::Http2
attr_reader :cookies, :args
def initialize(args = {})
args = {:host => args} if args.is_a?(String)
@@ -42,10 +53,13 @@
self.destroy
end
end
end
+ #Returns boolean based on the if the object is connected and the socket is working.
+ #===Examples
+ # print "Socket is working." if http.socket_working?
def socket_working?
return false if !@sock or @sock.closed?
if @keepalive_timeout and @request_last
between = Time.now.to_i - @request_last.to_i
@@ -56,10 +70,13 @@
end
return true
end
+ #Destroys the object unsetting all variables and closing all sockets.
+ #===Examples
+ # http.destroy
def destroy
@args = nil
@cookies = nil
@debug = nil
@mutex = nil
@@ -131,10 +148,14 @@
else
@sock = @sock_plain
end
end
+ #Returns a result-object based on the arguments.
+ #===Examples
+ # res = http.get("somepage.html")
+ # print res.body #=> <String>-object containing the HTML gotten.
def get(addr, args = {})
begin
@mutex.synchronize do
args[:addr] = addr
header_str = "GET /#{addr} HTTP/1.1#{@nl}"
@@ -172,10 +193,14 @@
end
@request_last = Time.now
end
+ #Returns the default headers for a request.
+ #===Examples
+ # headers_hash = http.default_headers
+ # print "#{headers_hash}"
def default_headers(args = {})
return args[:default_headers] if args[:default_headers]
headers = {
"Host" => @args[:host],
@@ -211,10 +236,13 @@
end
return praw
end
+ #Posts to a certain page.
+ #===Examples
+ # res = http.post("login.php", {"username" => "John Doe", "password" => 123)
def post(addr, pdata = {}, args = {})
begin
@mutex.synchronize do
praw = Knj::Http2.post_convert_data(pdata)
@@ -229,10 +257,13 @@
rescue Knj::Errors::Retry => e
return self.get(e.message, args)
end
end
+ #Posts to a certain page using the multipart-method.
+ #===Examples
+ # res = http.post_multipart("upload.php", {"normal_value" => 123, "file" => Tempfile.new(?)})
def post_multipart(addr, pdata, args = {})
begin
@mutex.synchronize do
boundary = Digest::MD5.hexdigest(Time.now.to_f.to_s)
@@ -272,10 +303,11 @@
rescue Knj::Errors::Retry => e
return self.get(e.message, args)
end
end
+ #Returns a header-string which normally would be used for a request in the given state.
def header_str(headers_hash, args = {})
if @cookies.length > 0 and (!args.key?(:cookies) or args[:cookies])
cstr = ""
first = true
@@ -299,10 +331,13 @@
def on_content_call(args, line)
args[:on_content].call(line) if args.key?(:on_content)
end
+ #Reads the response after posting headers and data.
+ #===Examples
+ # res = http.read_response
def read_response(args = {})
@mode = "headers"
@resp = Knj::Http2::Response.new
loop do
@@ -384,11 +419,14 @@
else
return resp
end
end
- def parse_header(line, args)
+ #Parse a header-line and saves it on the object.
+ #===Examples
+ # http.parse_header("Content-Type: text/html\r\n")
+ def parse_header(line, args = {})
if match = line.match(/^(.+?):\s*(.+)#{@nl}$/)
key = match[1].to_s.downcase
if key == "set-cookie"
Knj::Web.parse_set_cookies(match[2]).each do |cookie_data|
@@ -434,10 +472,12 @@
else
raise "Could not understand header string: '#{line}'."
end
end
+ #Parses the body based on given headers and saves it to the result-object.
+ # http.parse_body(str)
def parse_body(line, args)
if @resp.args[:http_version] = "1.1"
return "break" if @length == 0
if @resp.header("transfer-encoding").to_s.downcase == "chunked"
@@ -478,40 +518,61 @@
@args = args
@args[:headers] = {} if !@args.key?(:headers)
@args[:body] = "" if !@args.key?(:body)
end
+ #Returns headers given from the host for the result.
+ #===Examples
+ # headers_hash = res.headers
def headers
return @args[:headers]
end
+ #Returns a certain header by name or false if not found.
+ #===Examples
+ # val = res.header("content-type")
def header(key)
return false if !@args[:headers].key?(key)
return @args[:headers][key].first.to_s
end
#Returns true if a header of the given string exists.
+ #===Examples
+ # print "No content-type was given." if !http.header?("content-type")
def header?(key)
return true if @args[:headers].key?(key) and @args[:headers][key].first.to_s.length > 0
return false
end
+ #Returns the code of the result (200, 404, 500 etc).
+ #===Examples
+ # print "An internal error occurred." if res.code.to_i == 500
def code
return @args[:code]
end
+ #Returns the HTTP-version of the result.
+ #===Examples
+ # print "We are using HTTP 1.1 and should support keep-alive." if res.http_version.to_s == "1.1"
def http_version
return @args[:http_version]
end
+ #Returns the complete body of the result as a string.
+ #===Examples
+ # print "Looks like we caught the end of it as well?" if res.body.to_s.downcase.index("</html>") != nil
def body
return @args[:body]
end
+ #Returns the charset of the result.
def charset
return @args[:charset]
end
+ #Returns the content-type of the result as a string.
+ #===Examples
+ # print "This body can be printed - its just plain text!" if http.contenttype == "text/plain"
def contenttype
return @args[:contenttype]
end
end
\ No newline at end of file