curl_ffi 0.0.5 → 0.0.6
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.
- data/lib/bindings.rb +5 -4
- data/lib/curl_ffi/version.rb +1 -1
- metadata +2 -4
- data/lib/streamly/request.rb +0 -136
- data/lib/streamly.rb +0 -124
data/lib/bindings.rb
CHANGED
@@ -28,10 +28,6 @@ module CurlFFI
|
|
28
28
|
INFO_DOUBLE = 0x300000
|
29
29
|
INFO_SLIST = 0x400000
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
31
|
CODE = enum :code, [
|
36
32
|
:OK, 0,
|
37
33
|
:UNSUPPORTED_PROTOCOL, 1,
|
@@ -997,4 +993,9 @@ module CurlFFI
|
|
997
993
|
|
998
994
|
attach_function :slist_append, :curl_slist_append, [:pointer, :string], :pointer
|
999
995
|
attach_function :slist_free_all, :curl_slist_free_all, [:pointer], :void
|
996
|
+
|
997
|
+
class CurlSlist < FFI::Struct
|
998
|
+
layout :data, :string,
|
999
|
+
:next, :pointer
|
1000
|
+
end
|
1000
1001
|
end
|
data/lib/curl_ffi/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 6
|
9
|
+
version: 0.0.6
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Arthur Schreiber
|
@@ -67,8 +67,6 @@ files:
|
|
67
67
|
- lib/curl_ffi/easy.rb
|
68
68
|
- lib/curl_ffi/multi.rb
|
69
69
|
- lib/curl_ffi/version.rb
|
70
|
-
- lib/streamly.rb
|
71
|
-
- lib/streamly/request.rb
|
72
70
|
- spec/curl_ffi/easy_spec.rb
|
73
71
|
- spec/curl_ffi/multi_spec.rb
|
74
72
|
- spec/spec_helper.rb
|
data/lib/streamly/request.rb
DELETED
@@ -1,136 +0,0 @@
|
|
1
|
-
require "ffi"
|
2
|
-
require "singleton"
|
3
|
-
|
4
|
-
module Streamly
|
5
|
-
class Request
|
6
|
-
include Singleton
|
7
|
-
|
8
|
-
attr_reader :response_header_handler, :response_body_handler
|
9
|
-
|
10
|
-
CallHandler = Proc.new do |stream, size, nmemb, handler|
|
11
|
-
handler.call(stream)
|
12
|
-
size * nmemb
|
13
|
-
end
|
14
|
-
|
15
|
-
StringHandler = Proc.new do |stream, size, nmemb, handler|
|
16
|
-
if handler.nil?
|
17
|
-
handler = stream.clone
|
18
|
-
else
|
19
|
-
handler << stream
|
20
|
-
end
|
21
|
-
size * nmemb
|
22
|
-
end
|
23
|
-
|
24
|
-
DataHandler = Proc.new do |stream, size, nmemb, handler|
|
25
|
-
case handler
|
26
|
-
when String then handler << stream
|
27
|
-
else handler.call(stream)
|
28
|
-
end
|
29
|
-
size * nmemb
|
30
|
-
end
|
31
|
-
|
32
|
-
# @TODO: Argumenting Checking + Error Handling
|
33
|
-
def initialize(url, method=:get, options={})
|
34
|
-
# url should be a string that doesn't suck
|
35
|
-
# method should be :post, :get, :put, :delete, :head
|
36
|
-
# options should contain any of the following keys:
|
37
|
-
# :headers, :response_header_handler, :response_body_handler, :payload (required if method = :post / :put)
|
38
|
-
|
39
|
-
# @response_header_handler ||= options[:response_header_handler] || FFI::MemoryPointer.from_string("")
|
40
|
-
# @response_body_handler ||= options[:response_body_handler] || FFI::MemoryPointer.from_string("")
|
41
|
-
|
42
|
-
case method
|
43
|
-
when :get then connection.setopt :HTTPGET, 1
|
44
|
-
when :head then connection.setopt :NOBODY, 1
|
45
|
-
when :post then connection.setopt :POST, 1
|
46
|
-
connection.setopt :POSTFIELDS, options[:payload]
|
47
|
-
connection.setopt :POSTFIELDSIZE, options[:payload].size
|
48
|
-
when :put then connection.setopt :CUSTOMREQUEST, "PUT"
|
49
|
-
connection.setopt :POSTFIELDS, options[:payload]
|
50
|
-
connection.setopt :POSTFIELDSIZE, options[:payload].size
|
51
|
-
when :delete then connection.setopt :CUSTOMREQUEST, "DELETE"
|
52
|
-
# else I WILL CUT YOU
|
53
|
-
end
|
54
|
-
|
55
|
-
if options[:headers].is_a? Hash and options[:headers].size > 0
|
56
|
-
options[:headers].each_pair do |key_and_value|
|
57
|
-
@request_headers = CurlFFI.slist_append(request_headers, key_and_value.join(": "))
|
58
|
-
end
|
59
|
-
connection.setopt :HTTPHEADER, @request_headers
|
60
|
-
end
|
61
|
-
|
62
|
-
if options[:response_header_handler].nil?
|
63
|
-
# @response_header_handler = FFI::MemoryPointer.from_string("")
|
64
|
-
@response_header_handler = FFI::MemoryPointer.new(:pointer)
|
65
|
-
connection.setopt_str_handler :HEADERFUNCTION, StringHandler
|
66
|
-
connection.setopt_str_handler :WRITEHEADER, @response_header_handler
|
67
|
-
else
|
68
|
-
@response_header_handler = options[:response_header_handler]
|
69
|
-
connection.setopt_handler :HEADERFUNCTION, CallHandler
|
70
|
-
connection.setopt_handler :WRITEHEADER, @response_header_handler
|
71
|
-
end
|
72
|
-
|
73
|
-
unless method == :head
|
74
|
-
connection.setopt :ENCODING, "identity, deflate, gzip"
|
75
|
-
|
76
|
-
if options[:response_body_handler].nil?
|
77
|
-
# @response_body_handler = FFI::MemoryPointer.from_string("")
|
78
|
-
@response_body_handler = FFI::MemoryPointer.new(:pointer)
|
79
|
-
connection.setopt_str_handler :WRITEFUNCTION, StringHandler
|
80
|
-
connection.setopt_str_handler :FILE, @response_body_handler
|
81
|
-
else
|
82
|
-
@response_body_handler = options[:response_body_handler]
|
83
|
-
connection.setopt_handler :WRITEFUNCTION, CallHandler
|
84
|
-
connection.setopt_handler :FILE, @response_body_handler
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
connection.setopt :URL, FFI::MemoryPointer.from_string(url)
|
89
|
-
|
90
|
-
# Other common options (blame streamly guy)
|
91
|
-
connection.setopt :FOLLOWLOCATION, 1
|
92
|
-
connection.setopt :MAXREDIRS, 3
|
93
|
-
|
94
|
-
# This should be an option
|
95
|
-
connection.setopt :SSL_VERIFYPEER, 0
|
96
|
-
connection.setopt :SSL_VERIFYHOST, 0
|
97
|
-
|
98
|
-
connection.setopt :ERRORBUFFER, error_buffer
|
99
|
-
|
100
|
-
return self
|
101
|
-
end
|
102
|
-
|
103
|
-
def connection
|
104
|
-
@connection ||= CurlFFI::Easy.new
|
105
|
-
end
|
106
|
-
|
107
|
-
def error_buffer
|
108
|
-
@error_buffer ||= FFI::MemoryPointer.new(:char, CurlFFI::ERROR_SIZE, :clear)
|
109
|
-
end
|
110
|
-
|
111
|
-
def request_headers
|
112
|
-
@request_headers ||= FFI::MemoryPointer.from_string("")
|
113
|
-
end
|
114
|
-
=begin
|
115
|
-
|
116
|
-
=end
|
117
|
-
def execute
|
118
|
-
connection.perform
|
119
|
-
return response_body_handler
|
120
|
-
end
|
121
|
-
|
122
|
-
def self.execute(url, method=:get, options={})
|
123
|
-
new(url, method, options).execute
|
124
|
-
end
|
125
|
-
|
126
|
-
# streamly's .c internal methods:
|
127
|
-
# @TODO: header_handler
|
128
|
-
# @TODO: data_handler
|
129
|
-
# @TODO: each_http_header
|
130
|
-
# @TODO: select_error
|
131
|
-
# @TODO: rb_streamly_new
|
132
|
-
# @TODO: rb_streamly_init
|
133
|
-
# @TODO: nogvl_perform
|
134
|
-
# @TODO: rb_streamly_execute
|
135
|
-
end
|
136
|
-
end
|
data/lib/streamly.rb
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
-
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
-
|
4
|
-
require "ffi"
|
5
|
-
require "curl_ffi"
|
6
|
-
|
7
|
-
module Streamly
|
8
|
-
extend FFI::Library
|
9
|
-
|
10
|
-
autoload :Request, "streamly/request"
|
11
|
-
|
12
|
-
class Error < StandardError; end
|
13
|
-
class UnsupportedProtocol < StandardError; end
|
14
|
-
class URLFormatError < StandardError; end
|
15
|
-
class HostResolutionError < StandardError; end
|
16
|
-
class ConnectionFailed < StandardError; end
|
17
|
-
class PartialFileError < StandardError; end
|
18
|
-
class TimeoutError < StandardError; end
|
19
|
-
class TooManyRedirects < StandardError; end
|
20
|
-
|
21
|
-
# A helper method to make HEAD requests a dead-simple one-liner
|
22
|
-
#
|
23
|
-
# Example:
|
24
|
-
# Streamly.head("www.somehost.com/some_resource/1")
|
25
|
-
#
|
26
|
-
# Streamly.head("www.somehost.com/some_resource/1") do |header_chunk|
|
27
|
-
# # do something with _header_chunk_
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# Parameters:
|
31
|
-
# +url+ should be a String, the url to request
|
32
|
-
# +headers+ should be a Hash and is optional
|
33
|
-
#
|
34
|
-
# This method also accepts a block, which will stream the response headers in chunks to the caller
|
35
|
-
def self.head(url, headers=nil, &block)
|
36
|
-
opts = {:method => :head, :url => url, :headers => headers}
|
37
|
-
opts.merge!({:response_header_handler => block}) if block_given?
|
38
|
-
Request.execute(opts)
|
39
|
-
end
|
40
|
-
|
41
|
-
# A helper method to make HEAD requests a dead-simple one-liner
|
42
|
-
#
|
43
|
-
# Example:
|
44
|
-
# Streamly.get("www.somehost.com/some_resource/1")
|
45
|
-
#
|
46
|
-
# Streamly.get("www.somehost.com/some_resource/1") do |chunk|
|
47
|
-
# # do something with _chunk_
|
48
|
-
# end
|
49
|
-
#
|
50
|
-
# Parameters:
|
51
|
-
# +url+ should be a String, the url to request
|
52
|
-
# +headers+ should be a Hash and is optional
|
53
|
-
#
|
54
|
-
# This method also accepts a block, which will stream the response body in chunks to the caller
|
55
|
-
def self.get(url, headers=nil, &block)
|
56
|
-
opts = {:headers => headers}
|
57
|
-
opts.merge!({:response_body_handler => block}) if block_given?
|
58
|
-
Request.execute(url, :get, opts)
|
59
|
-
end
|
60
|
-
|
61
|
-
# A helper method to make HEAD requests a dead-simple one-liner
|
62
|
-
#
|
63
|
-
# Example:
|
64
|
-
# Streamly.post("www.somehost.com/some_resource", "asset[id]=2&asset[name]=bar")
|
65
|
-
#
|
66
|
-
# Streamly.post("www.somehost.com/some_resource", "asset[id]=2&asset[name]=bar") do |chunk|
|
67
|
-
# # do something with _chunk_
|
68
|
-
# end
|
69
|
-
#
|
70
|
-
# Parameters:
|
71
|
-
# +url+ should be a String (the url to request) and is required
|
72
|
-
# +payload+ should be a String and is required
|
73
|
-
# +headers+ should be a Hash and is optional
|
74
|
-
#
|
75
|
-
# This method also accepts a block, which will stream the response body in chunks to the caller
|
76
|
-
def self.post(url, payload, headers=nil, &block)
|
77
|
-
opts = {:payload => payload, :headers => headers}
|
78
|
-
opts.merge!({:response_body_handler => block}) if block_given?
|
79
|
-
Request.execute(url, :post, opts)
|
80
|
-
end
|
81
|
-
|
82
|
-
# A helper method to make HEAD requests a dead-simple one-liner
|
83
|
-
#
|
84
|
-
# Example:
|
85
|
-
# Streamly.put("www.somehost.com/some_resource/1", "asset[name]=foo")
|
86
|
-
#
|
87
|
-
# Streamly.put("www.somehost.com/some_resource/1", "asset[name]=foo") do |chunk|
|
88
|
-
# # do something with _chunk_
|
89
|
-
# end
|
90
|
-
#
|
91
|
-
# Parameters:
|
92
|
-
# +url+ should be a String (the url to request) and is required
|
93
|
-
# +payload+ should be a String and is required
|
94
|
-
# +headers+ should be a Hash and is optional
|
95
|
-
#
|
96
|
-
# This method also accepts a block, which will stream the response body in chunks to the caller
|
97
|
-
def self.put(url, payload, headers=nil, &block)
|
98
|
-
opts = {:payload => payload, :headers => headers}
|
99
|
-
opts.merge!({:response_body_handler => block}) if block_given?
|
100
|
-
Request.execute(url, :put, opts)
|
101
|
-
end
|
102
|
-
|
103
|
-
# A helper method to make HEAD requests a dead-simple one-liner
|
104
|
-
#
|
105
|
-
# Example:
|
106
|
-
# Streamly.delete("www.somehost.com/some_resource/1")
|
107
|
-
#
|
108
|
-
# Streamly.delete("www.somehost.com/some_resource/1") do |chunk|
|
109
|
-
# # do something with _chunk_
|
110
|
-
# end
|
111
|
-
#
|
112
|
-
# Parameters:
|
113
|
-
# +url+ should be a String, the url to request
|
114
|
-
# +headers+ should be a Hash and is optional
|
115
|
-
#
|
116
|
-
# This method also accepts a block, which will stream the response body in chunks to the caller
|
117
|
-
def self.delete(url, headers={}, &block)
|
118
|
-
opts = {:method => :delete, :url => url, :headers => headers}
|
119
|
-
opts.merge!({:response_body_handler => block}) if block_given?
|
120
|
-
Request.execute(opts)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# require "streamly/request" # May need to do this? Not sure how autoload works with FFI yet
|