typhoeus 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG.markdown +14 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +2 -0
- data/LICENSE +20 -0
- data/README.textile +39 -5
- data/Rakefile +8 -5
- data/VERSION +1 -1
- data/examples/file.rb +12 -0
- data/examples/times.rb +40 -0
- data/ext/typhoeus/.gitignore +2 -1
- data/ext/typhoeus/native.c +1 -0
- data/ext/typhoeus/native.h +1 -0
- data/ext/typhoeus/typhoeus_easy.c +32 -7
- data/ext/typhoeus/typhoeus_easy.h +1 -0
- data/ext/typhoeus/typhoeus_form.c +59 -0
- data/ext/typhoeus/typhoeus_form.h +13 -0
- data/ext/typhoeus/typhoeus_multi.c +15 -29
- data/lib/typhoeus.rb +1 -0
- data/lib/typhoeus/easy.rb +70 -48
- data/lib/typhoeus/form.rb +47 -0
- data/lib/typhoeus/hydra.rb +40 -7
- data/lib/typhoeus/hydra/connect_options.rb +19 -3
- data/lib/typhoeus/multi.rb +7 -5
- data/lib/typhoeus/remote.rb +1 -1
- data/lib/typhoeus/remote_proxy_object.rb +2 -0
- data/lib/typhoeus/request.rb +15 -3
- data/lib/typhoeus/response.rb +16 -1
- data/spec/fixtures/placeholder.gif +0 -0
- data/spec/fixtures/placeholder.txt +1 -0
- data/spec/fixtures/placeholder.ukn +0 -0
- data/spec/servers/app.rb +9 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/typhoeus/easy_spec.rb +55 -6
- data/spec/typhoeus/filter_spec.rb +2 -2
- data/spec/typhoeus/form_spec.rb +106 -0
- data/spec/typhoeus/hydra_mock_spec.rb +1 -1
- data/spec/typhoeus/hydra_spec.rb +108 -38
- data/spec/typhoeus/multi_spec.rb +1 -1
- data/spec/typhoeus/normalized_header_hash_spec.rb +1 -1
- data/spec/typhoeus/remote_method_spec.rb +2 -2
- data/spec/typhoeus/remote_proxy_object_spec.rb +1 -1
- data/spec/typhoeus/remote_spec.rb +1 -1
- data/spec/typhoeus/request_spec.rb +31 -2
- data/spec/typhoeus/response_spec.rb +13 -1
- data/spec/typhoeus/utils_spec.rb +1 -1
- data/typhoeus.gemspec +23 -6
- metadata +39 -19
data/.gitignore
CHANGED
data/CHANGELOG.markdown
CHANGED
@@ -1,5 +1,18 @@
|
|
1
|
+
Current Master
|
2
|
+
--------------
|
3
|
+
* Added extended proxy support [Zapotek, GH-46]
|
4
|
+
* eliminated compile time warnings by using proper type declarations [skaes, GH-54]
|
5
|
+
* fixed broken calls to rb_raise [skaes, GH-54]
|
6
|
+
* prevent leaking of curl easy handles when exceptions are raised (either from typhoeus itself or user callbacks) [skaes, GH-54]
|
7
|
+
* fixed Easy#timed_out? using curl return codes [skaes, GH-54]
|
8
|
+
* provide curl return codes and corresponding curl error messages on classes Easy and Request [skaes, GH-54]
|
9
|
+
* allow VCR to whitelist hosts in Typhoeus stubbing/mocking [myronmarston, GH-57]
|
10
|
+
* added timed_out? documentation, method to Response [dbalatero, GH-34]
|
11
|
+
* added abort to Hydra to prematurely stop a hydra.run [Zapotek]
|
12
|
+
* added file upload support for POST requests [jtarchie, GH-59]
|
13
|
+
|
1
14
|
0.2.0
|
2
|
-
|
15
|
+
------
|
3
16
|
* Fix warning in Request#headers from attr_accessor
|
4
17
|
* Params with array values were not parsing into the format that rack expects
|
5
18
|
[GH-39, smartocci]
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -10,6 +10,7 @@ GEM
|
|
10
10
|
rubyforge (>= 2.0.0)
|
11
11
|
json (1.4.6)
|
12
12
|
json_pure (1.4.6)
|
13
|
+
mime-types (1.16)
|
13
14
|
rack (1.2.1)
|
14
15
|
rspec (1.3.1)
|
15
16
|
rubyforge (2.0.4)
|
@@ -26,5 +27,6 @@ DEPENDENCIES
|
|
26
27
|
diff-lcs
|
27
28
|
jeweler
|
28
29
|
json
|
30
|
+
mime-types
|
29
31
|
rspec (= 1.3.1)
|
30
32
|
sinatra
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 David Balatero
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
CHANGED
@@ -18,7 +18,7 @@ h2. Installation
|
|
18
18
|
|
19
19
|
Typhoeus requires you to have a current version of libcurl installed. I've tested this with 7.19.4 and higher.
|
20
20
|
<pre>
|
21
|
-
gem install typhoeus
|
21
|
+
gem install typhoeus
|
22
22
|
</pre>
|
23
23
|
If you're on Debian or Ubuntu and getting errors while trying to install, it could be because you don't have the latest version of libcurl installed. Do this to fix:
|
24
24
|
<pre>
|
@@ -29,7 +29,7 @@ There's also something built in so that if you have a super old version of curl
|
|
29
29
|
gem install typhoeus --source http://gemcutter.org -- --with-curl=/usr/local/curl/7.19.7/
|
30
30
|
</pre>
|
31
31
|
|
32
|
-
Another problem could be if you are running Mac Ports and you have libcurl installed through there. You need to uninstall it for Typhoeus to work! The version in Mac Ports is old and doesn't play nice. You should "download curl":http://curl.haxx.se/download.html and build from source. Then you'll have to install the gem again.
|
32
|
+
-Another problem could be if you are running Mac Ports and you have libcurl installed through there. You need to uninstall it for Typhoeus to work! The version in Mac Ports is old and doesn't play nice. You should "download curl":http://curl.haxx.se/download.html and build from source. Then you'll have to install the gem again.- The current version of Mac Ports (7.21.2) works just fine.
|
33
33
|
|
34
34
|
If you're still having issues, please let me know on "the mailing list":http://groups.google.com/group/typhoeus.
|
35
35
|
|
@@ -79,6 +79,18 @@ response = Typhoeus::Request.post("http://localhost:3000/posts", :params => {:ti
|
|
79
79
|
response = Typhoeus::Request.delete("http://localhost:3000/posts/1")
|
80
80
|
</pre>
|
81
81
|
|
82
|
+
*Handling file uploads*
|
83
|
+
A File object can be passed as a param for a POST request to handle uploading files to the server. Typhoeus will upload the file as the original file name and use Mime::Types to set the content type.
|
84
|
+
|
85
|
+
<pre>
|
86
|
+
response = Typhoeus::Request.post("http://localhost:3000/posts",
|
87
|
+
:params => {
|
88
|
+
:title => "test post", :content => "this is my test",
|
89
|
+
:file => File.open("thesis.txt","r")
|
90
|
+
}
|
91
|
+
)
|
92
|
+
</pre>
|
93
|
+
|
82
94
|
*Making Parallel Requests*
|
83
95
|
|
84
96
|
<pre>
|
@@ -149,7 +161,7 @@ hydra.cache_getter do |request|
|
|
149
161
|
end
|
150
162
|
</pre>
|
151
163
|
|
152
|
-
*Stubbing*
|
164
|
+
*Direct Stubbing*
|
153
165
|
Hydra allows you to stub out specific urls and patters to avoid hitting remote servers while testing.
|
154
166
|
|
155
167
|
<pre>
|
@@ -180,6 +192,15 @@ hydra = Typhoeus::Hydra.hydra
|
|
180
192
|
hydra.stub(:get, "http://localhost:3000/users")
|
181
193
|
</pre>
|
182
194
|
|
195
|
+
*Timeouts*
|
196
|
+
|
197
|
+
No exceptions are raised on HTTP timeouts. You can check whether a request timed out with the following methods:
|
198
|
+
|
199
|
+
<pre>
|
200
|
+
easy.timed_out? # for a raw Easy handle
|
201
|
+
response.timed_out? # for a Response handle
|
202
|
+
</pre>
|
203
|
+
|
183
204
|
*Basic Authentication*
|
184
205
|
|
185
206
|
<pre>
|
@@ -203,7 +224,9 @@ Typhoeus::Request.get("https://mail.google.com/mail", :disable_ssl_peer_verifica
|
|
203
224
|
*LibCurl*
|
204
225
|
Typhoeus also has a more raw libcurl interface. These are the Easy and Multi objects. If you're into accessing just the raw libcurl style, those are your best bet.
|
205
226
|
|
206
|
-
|
227
|
+
However, by using this raw interface, you do not get access to Hydra-specific features, such as stubbing/mocking.
|
228
|
+
|
229
|
+
SSL Certs can be provided to the Easy interface:
|
207
230
|
|
208
231
|
<pre>
|
209
232
|
e = Typhoeus::Easy.new
|
@@ -262,7 +285,7 @@ There's also an easy way to perform any kind of authentication via the quick req
|
|
262
285
|
e = Typhoeus::Request.get("http://example.com",
|
263
286
|
:username => 'username',
|
264
287
|
:password => 'password',
|
265
|
-
:
|
288
|
+
:auth_method => :ntlm)
|
266
289
|
</pre>
|
267
290
|
|
268
291
|
All methods listed above is available in a shorter form - :basic, :digest, :gssnegotiate, :ntlm, :digest_ie, :auto.
|
@@ -300,6 +323,17 @@ I set up a benchmark to test how the parallel performance works vs Ruby's built
|
|
300
323
|
|
301
324
|
We can see from this that NET::HTTP performs as expected, taking 10 seconds to run 20 500ms requests. Typhoeus only takes 500ms (the time of the response that took the longest.) One other thing to note is that Typhoeus keeps a pool of libcurl Easy handles to use. For this benchmark I warmed the pool first. So if you test this out it may be a bit slower until the Easy handle pool has enough in it to run all the simultaneous requests. For some reason the easy handles can take quite some time to allocate.
|
302
325
|
|
326
|
+
h2. Running the specs
|
327
|
+
|
328
|
+
Running the specs requires a couple of Sinatra servers to be booted. Do this:
|
329
|
+
|
330
|
+
<pre>
|
331
|
+
ruby spec/servers/app.rb -p 3000
|
332
|
+
ruby spec/servers/app.rb -p 3001
|
333
|
+
ruby spec/servers/app.rb -p 3002
|
334
|
+
rake spec
|
335
|
+
</pre>
|
336
|
+
|
303
337
|
h2. Next Steps
|
304
338
|
|
305
339
|
* Add in ability to keep-alive requests and reuse them within hydra.
|
data/Rakefile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
|
1
3
|
require "spec"
|
2
4
|
require "spec/rake/spectask"
|
3
|
-
require 'lib/typhoeus
|
5
|
+
require 'lib/typhoeus'
|
4
6
|
|
5
7
|
begin
|
6
8
|
require 'jeweler'
|
@@ -8,9 +10,10 @@ begin
|
|
8
10
|
gemspec.name = "typhoeus"
|
9
11
|
gemspec.summary = "A library for interacting with web services (and building SOAs) at blinding speed."
|
10
12
|
gemspec.description = "Like a modern code version of the mythical beast with 100 serpent heads, Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling logic."
|
11
|
-
gemspec.email = "
|
12
|
-
gemspec.homepage = "http://github.com/
|
13
|
-
gemspec.authors = ["Paul Dix"]
|
13
|
+
gemspec.email = "dbalatero@gmail.com"
|
14
|
+
gemspec.homepage = "http://github.com/dbalatero/typhoeus"
|
15
|
+
gemspec.authors = ["Paul Dix", "David Balatero"]
|
16
|
+
gemspec.add_dependency "mime-types"
|
14
17
|
gemspec.add_development_dependency "rspec"
|
15
18
|
gemspec.add_development_dependency "jeweler"
|
16
19
|
gemspec.add_development_dependency "diff-lcs"
|
@@ -31,7 +34,7 @@ end
|
|
31
34
|
task :install do
|
32
35
|
rm_rf "*.gem"
|
33
36
|
puts `gem build typhoeus.gemspec`
|
34
|
-
puts `
|
37
|
+
puts `gem install typhoeus-#{Typhoeus::VERSION}.gem`
|
35
38
|
end
|
36
39
|
|
37
40
|
desc "Run all the tests"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.1
|
data/examples/file.rb
ADDED
data/examples/times.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/typhoeus.rb'
|
2
|
+
|
3
|
+
hydra = Typhoeus::Hydra.new
|
4
|
+
hydra.disable_memoization
|
5
|
+
|
6
|
+
urls = [
|
7
|
+
'http://google.com',
|
8
|
+
'http://testphp.vulnweb.com',
|
9
|
+
'http://demo.testfire.net',
|
10
|
+
'http://example.net',
|
11
|
+
]
|
12
|
+
|
13
|
+
10.times {
|
14
|
+
|i|
|
15
|
+
|
16
|
+
req = Typhoeus::Request.new( urls[ i % urls.size] )
|
17
|
+
req.on_complete {
|
18
|
+
|res|
|
19
|
+
puts 'URL: ' + res.effective_url
|
20
|
+
puts 'Time: ' + res.time.to_s
|
21
|
+
puts 'Connect time: ' + res.connect_time.to_s
|
22
|
+
puts 'App connect time: ' + res.app_connect_time.to_s
|
23
|
+
puts 'Start transfer time: ' + res.start_transfer_time.to_s
|
24
|
+
puts 'Pre transfer time: ' + res.pretransfer_time.to_s
|
25
|
+
puts '-------------'
|
26
|
+
}
|
27
|
+
|
28
|
+
hydra.queue( req )
|
29
|
+
puts 'Queued: ' + req.url
|
30
|
+
}
|
31
|
+
|
32
|
+
puts
|
33
|
+
puts 'Harvesting responses...'
|
34
|
+
puts
|
35
|
+
|
36
|
+
hydra.run
|
37
|
+
|
38
|
+
puts
|
39
|
+
puts 'Done.'
|
40
|
+
puts
|
data/ext/typhoeus/.gitignore
CHANGED
data/ext/typhoeus/native.c
CHANGED
data/ext/typhoeus/native.h
CHANGED
@@ -21,16 +21,27 @@ static VALUE easy_setopt_string(VALUE self, VALUE opt_name, VALUE parameter) {
|
|
21
21
|
CurlEasy *curl_easy;
|
22
22
|
Data_Get_Struct(self, CurlEasy, curl_easy);
|
23
23
|
|
24
|
-
|
24
|
+
CURLoption opt = NUM2LONG(opt_name);
|
25
25
|
curl_easy_setopt(curl_easy->curl, opt, StringValuePtr(parameter));
|
26
26
|
return opt_name;
|
27
27
|
}
|
28
28
|
|
29
|
+
static VALUE easy_setopt_form(VALUE self, VALUE opt_name, VALUE parameter) {
|
30
|
+
CurlEasy *curl_easy;
|
31
|
+
CurlForm *curl_form;
|
32
|
+
Data_Get_Struct(self, CurlEasy, curl_easy);
|
33
|
+
Data_Get_Struct(parameter, CurlForm, curl_form);
|
34
|
+
|
35
|
+
CURLoption opt = NUM2LONG(opt_name);
|
36
|
+
curl_easy_setopt(curl_easy->curl, opt, curl_form->first);
|
37
|
+
return opt_name;
|
38
|
+
}
|
39
|
+
|
29
40
|
static VALUE easy_setopt_long(VALUE self, VALUE opt_name, VALUE parameter) {
|
30
41
|
CurlEasy *curl_easy;
|
31
42
|
Data_Get_Struct(self, CurlEasy, curl_easy);
|
32
43
|
|
33
|
-
|
44
|
+
CURLoption opt = NUM2LONG(opt_name);
|
34
45
|
curl_easy_setopt(curl_easy->curl, opt, NUM2LONG(parameter));
|
35
46
|
return opt_name;
|
36
47
|
}
|
@@ -40,7 +51,7 @@ static VALUE easy_getinfo_string(VALUE self, VALUE info) {
|
|
40
51
|
CurlEasy *curl_easy;
|
41
52
|
Data_Get_Struct(self, CurlEasy, curl_easy);
|
42
53
|
|
43
|
-
|
54
|
+
CURLoption opt = NUM2LONG(info);
|
44
55
|
curl_easy_getinfo(curl_easy->curl, opt, &info_string);
|
45
56
|
|
46
57
|
return rb_str_new2(info_string);
|
@@ -51,7 +62,7 @@ static VALUE easy_getinfo_long(VALUE self, VALUE info) {
|
|
51
62
|
CurlEasy *curl_easy;
|
52
63
|
Data_Get_Struct(self, CurlEasy, curl_easy);
|
53
64
|
|
54
|
-
|
65
|
+
CURLoption opt = NUM2LONG(info);
|
55
66
|
curl_easy_getinfo(curl_easy->curl, opt, &info_long);
|
56
67
|
|
57
68
|
return LONG2NUM(info_long);
|
@@ -62,7 +73,7 @@ static VALUE easy_getinfo_double(VALUE self, VALUE info) {
|
|
62
73
|
CurlEasy *curl_easy;
|
63
74
|
Data_Get_Struct(self, CurlEasy, curl_easy);
|
64
75
|
|
65
|
-
|
76
|
+
CURLoption opt = NUM2LONG(info);
|
66
77
|
curl_easy_getinfo(curl_easy->curl, opt, &info_double);
|
67
78
|
|
68
79
|
return rb_float_new(info_double);
|
@@ -70,8 +81,10 @@ static VALUE easy_getinfo_double(VALUE self, VALUE info) {
|
|
70
81
|
|
71
82
|
static VALUE easy_perform(VALUE self) {
|
72
83
|
CurlEasy *curl_easy;
|
84
|
+
CURLcode return_code;
|
73
85
|
Data_Get_Struct(self, CurlEasy, curl_easy);
|
74
|
-
curl_easy_perform(curl_easy->curl);
|
86
|
+
return_code = curl_easy_perform(curl_easy->curl);
|
87
|
+
rb_iv_set(self, "@curl_return_code", INT2FIX(return_code));
|
75
88
|
|
76
89
|
return Qnil;
|
77
90
|
}
|
@@ -166,7 +179,7 @@ static VALUE easy_escape(VALUE self, VALUE data, VALUE length) {
|
|
166
179
|
CurlEasy *curl_easy;
|
167
180
|
Data_Get_Struct(self, CurlEasy, curl_easy);
|
168
181
|
|
169
|
-
return rb_str_new2(curl_easy_escape(curl_easy->curl, StringValuePtr(data), NUM2INT(length)));
|
182
|
+
return rb_str_new2(curl_easy_escape(curl_easy->curl, StringValuePtr(data), (int)NUM2INT(length)));
|
170
183
|
}
|
171
184
|
|
172
185
|
static VALUE version(VALUE self) {
|
@@ -188,11 +201,23 @@ static VALUE new(int argc, VALUE *argv, VALUE klass) {
|
|
188
201
|
return easy;
|
189
202
|
}
|
190
203
|
|
204
|
+
static VALUE curl_error_message(VALUE self) {
|
205
|
+
VALUE return_code = rb_iv_get(self, "@curl_return_code");
|
206
|
+
if (return_code == Qnil)
|
207
|
+
return Qnil;
|
208
|
+
else {
|
209
|
+
CURLcode rc = (CURLcode)FIX2INT(return_code);
|
210
|
+
return rb_str_new2(curl_easy_strerror(rc));
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
191
214
|
void init_typhoeus_easy() {
|
192
215
|
VALUE klass = cTyphoeusEasy = rb_define_class_under(mTyphoeus, "Easy", rb_cObject);
|
193
216
|
idAppend = rb_intern("<<");
|
194
217
|
rb_define_singleton_method(klass, "new", new, -1);
|
218
|
+
rb_define_method(klass, "curl_error_message", curl_error_message, 0);
|
195
219
|
rb_define_private_method(klass, "easy_setopt_string", easy_setopt_string, 2);
|
220
|
+
rb_define_private_method(klass, "easy_setopt_form", easy_setopt_form, 2);
|
196
221
|
rb_define_private_method(klass, "easy_setopt_long", easy_setopt_long, 2);
|
197
222
|
rb_define_private_method(klass, "easy_getinfo_string", easy_getinfo_string, 1);
|
198
223
|
rb_define_private_method(klass, "easy_getinfo_long", easy_getinfo_long, 1);
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#include <typhoeus_form.h>
|
2
|
+
|
3
|
+
VALUE cTyphoeusForm;
|
4
|
+
|
5
|
+
static void dealloc(CurlForm *curl_form) {
|
6
|
+
curl_formfree(curl_form->first);
|
7
|
+
free(curl_form);
|
8
|
+
}
|
9
|
+
|
10
|
+
static VALUE formadd_file(VALUE self,
|
11
|
+
VALUE name,
|
12
|
+
VALUE filename,
|
13
|
+
VALUE content_type,
|
14
|
+
VALUE path) {
|
15
|
+
CurlForm *curl_form;
|
16
|
+
Data_Get_Struct(self, CurlForm, curl_form);
|
17
|
+
|
18
|
+
return INT2NUM((long) curl_formadd(&curl_form->first, &curl_form->last,
|
19
|
+
CURLFORM_COPYNAME, RSTRING_PTR(name),
|
20
|
+
CURLFORM_NAMELENGTH, (long)RSTRING_LEN(name),
|
21
|
+
CURLFORM_FILENAME, RSTRING_PTR(filename),
|
22
|
+
CURLFORM_CONTENTTYPE, RSTRING_PTR(content_type),
|
23
|
+
CURLFORM_FILE, RSTRING_PTR(path),
|
24
|
+
CURLFORM_END
|
25
|
+
));
|
26
|
+
}
|
27
|
+
|
28
|
+
static VALUE formadd_param(VALUE self, VALUE name, VALUE value) {
|
29
|
+
CurlForm *curl_form;
|
30
|
+
Data_Get_Struct(self, CurlForm, curl_form);
|
31
|
+
|
32
|
+
return INT2NUM((long)curl_formadd(&curl_form->first, &curl_form->last,
|
33
|
+
CURLFORM_COPYNAME, RSTRING_PTR(name),
|
34
|
+
CURLFORM_NAMELENGTH, (long)RSTRING_LEN(name),
|
35
|
+
CURLFORM_COPYCONTENTS, RSTRING_PTR(value),
|
36
|
+
CURLFORM_CONTENTSLENGTH, (long)RSTRING_LEN(value),
|
37
|
+
CURLFORM_END
|
38
|
+
));
|
39
|
+
}
|
40
|
+
|
41
|
+
static VALUE new(int argc, VALUE *argv, VALUE klass) {
|
42
|
+
CurlForm *curl_form = ALLOC(CurlForm);
|
43
|
+
curl_form->first = NULL;
|
44
|
+
curl_form->last = NULL;
|
45
|
+
|
46
|
+
VALUE form = Data_Wrap_Struct(cTyphoeusForm, 0, dealloc, curl_form);
|
47
|
+
|
48
|
+
rb_obj_call_init(form, argc, argv);
|
49
|
+
|
50
|
+
return form;
|
51
|
+
}
|
52
|
+
|
53
|
+
void init_typhoeus_form() {
|
54
|
+
VALUE klass = cTyphoeusForm = rb_define_class_under(mTyphoeus, "Form", rb_cObject);
|
55
|
+
|
56
|
+
rb_define_singleton_method(klass, "new", new, -1);
|
57
|
+
rb_define_private_method(klass, "formadd_file", formadd_file, 4);
|
58
|
+
rb_define_private_method(klass, "formadd_param", formadd_param, 2);
|
59
|
+
}
|