funky-simplehttp 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 19b2df5b95c721fd8b240d79bba007b27e1b051b
4
+ data.tar.gz: d83529c9ae13241bb3f5761118391cea43e37086
5
+ SHA512:
6
+ metadata.gz: 32cc670f116b166c49b5c9f3db867b3717da27fe105647186ddb8dbbb1c11c9b579665ee05a3d2ba09f2a386be10914e2e61e72d5170faa4bb06c7510734067d
7
+ data.tar.gz: 4f437d49945cc6842524b6041ab7abf42fe0aba310c13511ae485555081d2b6a8ae964a6ec8fdfcadeac8a73e509c7d199b0e61b8e5d851cd4ac038abe065047
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ out
2
+ out/*
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,17 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ funky-simplehttp (0.4.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ rake (10.4.2)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ bundler (~> 1.7)
16
+ funky-simplehttp!
17
+ rake (~> 10.0)
data/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # SimpleHttp Class for mruby
2
+
3
+ POC to CloudWalk gems and libs, pure ruby implementation.
4
+
5
+ Simple http or https connection class for mruby.
6
+
7
+ Project based on matsumoto-r/mruby-simplehttp and iij/mruby-simplehttp
8
+
9
+ ## Contributing
10
+
11
+ 1. Fork it
12
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
13
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
14
+ 4. Push to the branch (`git push origin my-new-feature`)
15
+ 5. Create new Pull Request
16
+
17
+ # License
18
+ under the MIT License:
19
+
20
+ * http://www.opensource.org/licenses/mit-license.php
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ require 'rake'
2
+ #require "bundler/gem_tasks"
3
+
4
+ SIMPLEHTTP_ROOT = File.dirname(File.expand_path(__FILE__))
5
+ SIMPLEHTTP_OUT = File.join(SIMPLEHTTP_ROOT, "out", "simplehttp.mrb")
6
+
7
+ task :default => :build
8
+
9
+ task :check do
10
+ if ENV["MRBC"].nil?
11
+ if system("type cloudwalk > /dev/null 2>&1 ")
12
+ ENV["MRBC"] = "env cloudwalk compile"
13
+ elsif system("type mrbc > /dev/null 2>&1 ")
14
+ ENV["MRBC"] = "env mrbc"
15
+ else
16
+ puts "$MRBC isn't set or mrbc/cloudwalk isn't on $PATH"
17
+ exit 0
18
+ end
19
+ end
20
+ end
21
+
22
+ desc "Compile simplehttp to mrb"
23
+ task :build => :check do
24
+ sh "mkdir -p #{File.join(SIMPLEHTTP_ROOT, "out")}"
25
+ if ENV["MRBC"]
26
+ sh "#{ENV["MRBC"]} -g -o #{SIMPLEHTTP_OUT} #{File.join(SIMPLEHTTP_ROOT, "lib", "simplehttp.rb")} "
27
+ else
28
+ sh "env mrbc -g -o #{SIMPLEHTTP_OUT} #{File.join(SIMPLEHTTP_ROOT, "lib", "simplehttp.rb")} "
29
+ end
30
+ end
31
+
32
+ desc "Clobber/Clean"
33
+ task :clean => :check do
34
+ sh "mkdir -p out"
35
+ sh "rm -f #{SIMPLEHTTP_OUT}"
36
+ end
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'simplehttp.rb'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "funky-simplehttp"
8
+ spec.version = SimpleHttp.version
9
+ spec.authors = ["Thiago Scalone"]
10
+ spec.email = ["thiago@scalone.com.br"]
11
+ spec.summary = "Simplehttp"
12
+ spec.description = "Minimal HTTP implementation"
13
+ spec.homepage = "http://github.com/cloudwalkio/funky-simplehttp"
14
+ spec.license = "MIT"
15
+ spec.files = `git ls-files -z`.split("\x0") << "out/simplehttp.mrb"
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ end
data/lib/simplehttp.rb ADDED
@@ -0,0 +1,255 @@
1
+ class SimpleHttp
2
+ DEFAULTPORT = 80
3
+ DEFAULTHTTPSPORT = 443
4
+ HTTP_VERSION = "HTTP/1.0"
5
+ DEFAULT_ACCEPT = "*/*"
6
+ SEP = "\r\n"
7
+
8
+ def self.version
9
+ "0.4.2"
10
+ end
11
+
12
+ attr_accessor :socket, :socket_tcp, :support_fiber
13
+
14
+ def socket_class_exist?
15
+ c = Module.const_get("TCPSocket")
16
+ c.is_a?(Class)
17
+ rescue
18
+ return false
19
+ end
20
+
21
+ def uv_module_exist?
22
+ c = Module.const_get("UV")
23
+ c.is_a?(Module)
24
+ rescue
25
+ return false
26
+ end
27
+
28
+ def initialize(schema, address, port = nil)
29
+ @use_socket = false
30
+ @use_uv = false
31
+ if socket_class_exist?
32
+ @use_socket = true
33
+ end
34
+
35
+ if uv_module_exist?
36
+ @use_uv = true
37
+ end
38
+ @uri = {}
39
+ if @use_socket
40
+ # nothing
41
+ elsif @use_uv
42
+ ip = ""
43
+ UV::getaddrinfo(address, "http") do |x, info|
44
+ if info
45
+ ip = info.addr
46
+ end
47
+ end
48
+ UV::run()
49
+ @uri[:ip] = ip
50
+ else
51
+ raise "Not found Socket Class or UV Module"
52
+ end
53
+ @uri[:schema] = schema
54
+ @uri[:address] = address
55
+ if schema == "https"
56
+ @uri[:port] = port ? port.to_i : DEFAULTHTTPSPORT
57
+ else
58
+ @uri[:port] = port ? port.to_i : DEFAULTPORT
59
+ end
60
+ self
61
+ end
62
+
63
+ def address; @uri[:address]; end
64
+ def port; @uri[:port]; end
65
+
66
+ def get(path = "/", req = nil)
67
+ request("GET", path, req)
68
+ end
69
+
70
+ def post(path = "/", req = nil)
71
+ request("POST", path, req)
72
+ end
73
+
74
+ # private
75
+ def request(method, path, req)
76
+ @uri[:path] = path
77
+ if @uri[:path].nil?
78
+ @uri[:path] = "/"
79
+ elsif @uri[:path][0] != "/"
80
+ @uri[:path] = "/" + @uri[:path]
81
+ end
82
+ request_header = create_request_header(method.upcase.to_s, req)
83
+ response_text = send_request(request_header)
84
+ SimpleHttpResponse.new(response_text)
85
+ end
86
+
87
+ def read_fiber
88
+ response_text = ""
89
+ loop do
90
+ return "" if (@socket_tcp.nil? || @socket_tcp.closed?)
91
+ usleep(10000)
92
+ if (available = socket.bytes_available) > 0
93
+ usleep(10000)
94
+ t = socket.read(available)
95
+ usleep(10000)
96
+ break if t.nil?
97
+ response_text << t
98
+ end
99
+ finish = Fiber.yield(false)
100
+ if finish
101
+ return response_text
102
+ end
103
+ end
104
+ response_text
105
+ end
106
+
107
+ def read_normal
108
+ response_text = ""
109
+ while (t = socket.read(1024))
110
+ response_text += t
111
+ end
112
+ response_text
113
+ end
114
+
115
+ def support_fiber?
116
+ @support_fiber
117
+ end
118
+
119
+ def send_request(request_header)
120
+ response_text = ""
121
+ if @socket
122
+ socket.write(request_header)
123
+ if support_fiber?
124
+ response_text = read_fiber
125
+ else
126
+ response_text = read_normal
127
+ end
128
+ elsif @use_socket
129
+ @socket = TCPSocket.new(@uri[:address], @uri[:port])
130
+ if @uri[:schema] == "https"
131
+ entropy = PolarSSL::Entropy.new
132
+ ctr_drbg = PolarSSL::CtrDrbg.new entropy
133
+ ssl = PolarSSL::SSL.new
134
+ ssl.set_endpoint PolarSSL::SSL::SSL_IS_CLIENT
135
+ ssl.set_rng ctr_drbg
136
+ ssl.set_socket socket
137
+ ssl.handshake
138
+ ssl.write request_header
139
+ while chunk = ssl.read(2048)
140
+ response_text += chunk
141
+ end
142
+ ssl.close_notify
143
+ socket.close
144
+ ssl.close
145
+ else
146
+ socket.write(request_header)
147
+ while (t = socket.read(1024))
148
+ response_text += t
149
+ end
150
+ socket.close
151
+ end
152
+ elsif @use_uv
153
+ socket = UV::TCP.new()
154
+ socket.connect(UV.ip4_addr(@uri[:ip].sin_addr, @uri[:port])) do |x|
155
+ if x == 0
156
+ socket.write(request_header) do |x|
157
+ socket.read_start do |b|
158
+ response_text += b.to_s
159
+ end
160
+ end
161
+ else
162
+ socket.close()
163
+ end
164
+ end
165
+ UV::run()
166
+ else
167
+ raise "Not found Socket Class or UV Module"
168
+ end
169
+ response_text
170
+ end
171
+
172
+ def create_request_header(method, req)
173
+ req = {} unless req
174
+ str = ""
175
+ body = ""
176
+ str += sprintf("%s %s %s", method, @uri[:path], HTTP_VERSION) + SEP
177
+ header = {}
178
+ req.each do |key,value|
179
+ header[key.capitalize] = value
180
+ end
181
+ header["Host"] = @uri[:address] unless header.keys.include?("Host")
182
+ header["Accept"] = DEFAULT_ACCEPT unless header.keys.include?("Accept")
183
+ header["Connection"] = "close"
184
+ if header["Body"]
185
+ body = header["Body"]
186
+ header.delete("Body")
187
+ end
188
+ if method == "POST" && (not header.keys.include?("content-length".capitalize))
189
+ header["Content-Length"] = (body || '').length
190
+ end
191
+ header.keys.sort.each do |key|
192
+ str += sprintf("%s: %s", key, header[key]) + SEP
193
+ end
194
+ str + SEP + body
195
+ end
196
+
197
+ class SimpleHttpResponse
198
+ SEP = SimpleHttp::SEP
199
+ def initialize(response_text)
200
+ @response = {}
201
+ @headers = {}
202
+ if response_text.empty?
203
+ @response["header"] = nil
204
+ elsif response_text.include?(SEP + SEP)
205
+ @response["header"], @response["body"] = response_text.split(SEP + SEP, 2)
206
+ else
207
+ @response["header"] = response_text
208
+ end
209
+ parse_header
210
+ self
211
+ end
212
+
213
+ def [](key); @response[key]; end
214
+ def []=(key, value); @response[key] = value; end
215
+
216
+ def header; @response['header']; end
217
+ def headers; @headers; end
218
+ def body; @response['body']; end
219
+ def status; @response['status']; end
220
+ def code; @response['code']; end
221
+ def date; @response['date']; end
222
+ def content_type; @response['content-type']; end
223
+ def content_length; @response['content-length']; end
224
+
225
+ def each(&block)
226
+ if block
227
+ @response.each do |k,v| block.call(k,v) end
228
+ end
229
+ end
230
+ def each_name(&block)
231
+ if block
232
+ @response.each do |k,v| block.call(k) end
233
+ end
234
+ end
235
+
236
+ # private
237
+ def parse_header
238
+ return unless @response["header"]
239
+ h = @response["header"].split(SEP)
240
+ if h[0].include?("HTTP/1")
241
+ @response["status"] = h[0].split(" ", 2).last
242
+ @response["code"] = h[0].split(" ", 3)[1].to_i
243
+ end
244
+ h.each do |line|
245
+ if line.include?(": ")
246
+ k,v = line.split(": ")
247
+ @response[k.downcase] = v
248
+ @headers[k.downcase] = v
249
+ end
250
+ end
251
+ end
252
+ end
253
+ end
254
+
255
+
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: funky-simplehttp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.2
5
+ platform: ruby
6
+ authors:
7
+ - Thiago Scalone
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Minimal HTTP implementation
42
+ email:
43
+ - thiago@scalone.com.br
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - Gemfile
50
+ - Gemfile.lock
51
+ - README.md
52
+ - Rakefile
53
+ - funky-simplehttp.gemspec
54
+ - lib/simplehttp.rb
55
+ - out/simplehttp.mrb
56
+ homepage: http://github.com/cloudwalkio/funky-simplehttp
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.2.2
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: Simplehttp
80
+ test_files: []
81
+ has_rdoc: