Class: SimpleHttp

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

Defined Under Namespace

Classes: SimpleHttpResponse

Constant Summary collapse

DEFAULTPORT =
80
DEFAULTHTTPSPORT =
443
HTTP_VERSION =
"HTTP/1.0"
DEFAULT_ACCEPT =
"*/*"
SEP =
"\r\n"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(schema, address, port = nil) ⇒ SimpleHttp

Returns a new instance of SimpleHttp.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/simplehttp.rb', line 28

def initialize(schema, address, port = nil)
  @use_socket = false
  @use_uv = false
  if socket_class_exist?
    @use_socket = true
  end

  if uv_module_exist?
    @use_uv = true
  end
  @uri = {}
  if @use_socket
    # nothing
  elsif @use_uv
    ip = ""
    UV::getaddrinfo(address, "http") do |x, info|
      if info
        ip = info.addr
      end
    end
    UV::run()
    @uri[:ip] = ip
  else
    raise "Not found Socket Class or UV Module"
  end
  @uri[:schema] = schema
  @uri[:address] = address
  if schema == "https"
    @uri[:port] = port ? port.to_i : DEFAULTHTTPSPORT
  else
    @uri[:port] = port ? port.to_i : DEFAULTPORT
  end
  self
end

Instance Attribute Details

#socketObject

Returns the value of attribute socket.



12
13
14
# File 'lib/simplehttp.rb', line 12

def socket
  @socket
end

#socket_tcpObject

Returns the value of attribute socket_tcp.



12
13
14
# File 'lib/simplehttp.rb', line 12

def socket_tcp
  @socket_tcp
end

#support_fiberObject

Returns the value of attribute support_fiber.



12
13
14
# File 'lib/simplehttp.rb', line 12

def support_fiber
  @support_fiber
end

Class Method Details

.versionObject



8
9
10
# File 'lib/simplehttp.rb', line 8

def self.version
  "0.4.3"
end

Instance Method Details

#addressObject



63
# File 'lib/simplehttp.rb', line 63

def address; @uri[:address]; end

#create_request_header(method, req) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/simplehttp.rb', line 172

def create_request_header(method, req)
  req = {}  unless req
  str = ""
  body   = ""
  str += sprintf("%s %s %s", method, @uri[:path], HTTP_VERSION) + SEP
  header = {}
  req.each do |key,value|
    header[key.capitalize] = value
  end
  header["Host"] = @uri[:address]  unless header.keys.include?("Host")
  header["Accept"] = DEFAULT_ACCEPT  unless header.keys.include?("Accept")
  header["Connection"] = "close"
  if header["Body"]
    body = header["Body"]
    header.delete("Body")
  end
  if method == "POST" && (not header.keys.include?("content-length".capitalize))
      header["Content-Length"] = (body || '').length
  end
  header.keys.sort.each do |key|
    str += sprintf("%s: %s", key, header[key]) + SEP
  end
  str + SEP + body
end

#get(path = "/", req = nil) ⇒ Object



66
67
68
# File 'lib/simplehttp.rb', line 66

def get(path = "/", req = nil)
  request("GET", path, req)
end

#portObject



64
# File 'lib/simplehttp.rb', line 64

def port; @uri[:port]; end

#post(path = "/", req = nil) ⇒ Object



70
71
72
# File 'lib/simplehttp.rb', line 70

def post(path = "/", req = nil)
  request("POST", path, req)
end

#read_fiberObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/simplehttp.rb', line 87

def read_fiber
  response_text = ""
  loop do
    return "" if (@socket_tcp.nil? || @socket_tcp.closed?)
    usleep(10000)
    if (available = socket.bytes_available) > 0
      usleep(10000)
      t = socket.read(available)
      usleep(10000)
      break if t.nil?
      response_text << t
    end
    finish = Fiber.yield(false)
    if finish
      return response_text
    end
  end
  response_text
end

#read_normalObject



107
108
109
110
111
112
113
# File 'lib/simplehttp.rb', line 107

def read_normal
  response_text = ""
  while (t = socket.read(1024))
    response_text += t
  end
  response_text
end

#request(method, path, req) ⇒ Object

private



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/simplehttp.rb', line 75

def request(method, path, req)
  @uri[:path] = path
  if @uri[:path].nil?
    @uri[:path] = "/"
  elsif @uri[:path][0] != "/"
    @uri[:path] = "/" + @uri[:path]
  end
  request_header = create_request_header(method.upcase.to_s, req)
  response_text = send_request(request_header)
  SimpleHttpResponse.new(response_text)
end

#send_request(request_header) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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
162
163
164
165
166
167
168
169
170
# File 'lib/simplehttp.rb', line 119

def send_request(request_header)
  response_text = ""
  if @socket
    socket.write(request_header)
    if support_fiber?
      response_text = read_fiber
    else
      response_text = read_normal
    end
  elsif @use_socket
    @socket = TCPSocket.new(@uri[:address], @uri[:port])
    if @uri[:schema] == "https"
      entropy = PolarSSL::Entropy.new
      ctr_drbg = PolarSSL::CtrDrbg.new entropy
      ssl = PolarSSL::SSL.new
      ssl.set_endpoint PolarSSL::SSL::SSL_IS_CLIENT
      ssl.set_rng ctr_drbg
      ssl.set_socket socket
      ssl.handshake
      ssl.write request_header
      while chunk = ssl.read(2048)
        response_text += chunk
      end
      ssl.close_notify
      socket.close
      ssl.close
    else
      socket.write(request_header)
      while (t = socket.read(1024))
        response_text += t
      end
      socket.close
    end
  elsif @use_uv
    socket = UV::TCP.new()
    socket.connect(UV.ip4_addr(@uri[:ip].sin_addr, @uri[:port])) do |x|
      if x == 0
        socket.write(request_header) do |x|
          socket.read_start do |b|
            response_text += b.to_s
          end
        end
      else
        socket.close()
      end
    end
    UV::run()
  else
    raise "Not found Socket Class or UV Module"
  end
  response_text
end

#socket_class_exist?Boolean

Returns:

  • (Boolean)


14
15
16
17
18
19
# File 'lib/simplehttp.rb', line 14

def socket_class_exist?
    c = Module.const_get("TCPSocket")
    c.is_a?(Class)
rescue
    return false
end

#support_fiber?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/simplehttp.rb', line 115

def support_fiber?
  @support_fiber
end

#uv_module_exist?Boolean

Returns:

  • (Boolean)


21
22
23
24
25
26
# File 'lib/simplehttp.rb', line 21

def uv_module_exist?
    c = Module.const_get("UV")
    c.is_a?(Module)
rescue
    return false
end