rhack 1.2.1 → 1.2.7

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.
Files changed (47) hide show
  1. checksums.yaml +13 -5
  2. data/README.md +21 -9
  3. data/ext/curb/curb.c +977 -977
  4. data/ext/curb/curb.h +52 -52
  5. data/ext/curb/curb_config.h +270 -270
  6. data/ext/curb/curb_easy.c +3437 -3434
  7. data/ext/curb/curb_easy.h +94 -94
  8. data/ext/curb/curb_errors.c +647 -647
  9. data/ext/curb/curb_errors.h +129 -129
  10. data/ext/curb/curb_macros.h +162 -162
  11. data/ext/curb/curb_multi.c +704 -702
  12. data/ext/curb/curb_multi.h +26 -26
  13. data/ext/curb/curb_postfield.c +523 -523
  14. data/ext/curb/curb_postfield.h +40 -40
  15. data/ext/curb/curb_upload.c +80 -80
  16. data/ext/curb/curb_upload.h +30 -30
  17. data/ext/curb-original/curb.c +977 -977
  18. data/ext/curb-original/curb.h +52 -52
  19. data/ext/curb-original/curb_config.h +238 -238
  20. data/ext/curb-original/curb_easy.c +3404 -3404
  21. data/ext/curb-original/curb_easy.h +90 -90
  22. data/ext/curb-original/curb_errors.c +647 -647
  23. data/ext/curb-original/curb_errors.h +129 -129
  24. data/ext/curb-original/curb_macros.h +159 -159
  25. data/ext/curb-original/curb_multi.c +633 -633
  26. data/ext/curb-original/curb_multi.h +26 -26
  27. data/ext/curb-original/curb_postfield.c +523 -523
  28. data/ext/curb-original/curb_postfield.h +40 -40
  29. data/ext/curb-original/curb_upload.c +80 -80
  30. data/ext/curb-original/curb_upload.h +30 -30
  31. data/lib/rhack/clients/base.rb +61 -10
  32. data/lib/rhack/clients/oauth.rb +4 -4
  33. data/lib/rhack/curl/easy.rb +1 -0
  34. data/lib/rhack/curl/global.rb +2 -0
  35. data/lib/rhack/curl/response.rb +4 -2
  36. data/lib/rhack/frame.rb +70 -32
  37. data/lib/rhack/js/browser/env.js +697 -697
  38. data/lib/rhack/js/browser/jquery.js +7180 -7180
  39. data/lib/rhack/js/browser/xmlsax.js +1564 -1564
  40. data/lib/rhack/js/browser/xmlw3cdom_1.js +1443 -1443
  41. data/lib/rhack/js/browser/xmlw3cdom_2.js +2744 -2744
  42. data/lib/rhack/page.rb +227 -68
  43. data/lib/rhack/scout.rb +52 -26
  44. data/lib/rhack/scout_squad.rb +10 -2
  45. data/lib/rhack/version.rb +1 -1
  46. data/rhack.gemspec +1 -1
  47. metadata +17 -17
@@ -1,40 +1,40 @@
1
- /* curb_postfield.h - Field class for POST method
2
- * Copyright (c)2006 Ross Bamford.
3
- * Licensed under the Ruby License. See LICENSE for details.
4
- *
5
- * $Id: curb_postfield.h 4 2006-11-17 18:35:31Z roscopeco $
6
- */
7
- #ifndef __CURB_POSTFIELD_H
8
- #define __CURB_POSTFIELD_H
9
-
10
- #include "curb.h"
11
-
12
- /*
13
- * postfield doesn't actually wrap a curl_httppost - instead,
14
- * it just holds together some ruby objects and has a C-side
15
- * method to add it to a given form list during the perform.
16
- */
17
- typedef struct {
18
- /* Objects we associate */
19
- VALUE name;
20
- VALUE content;
21
- VALUE content_type;
22
- VALUE content_proc;
23
- VALUE local_file;
24
- VALUE remote_file;
25
-
26
- /* this will sometimes hold a string, which is the result
27
- * of the content_proc invocation. We need it to hang around.
28
- */
29
- VALUE buffer_str;
30
- } ruby_curl_postfield;
31
-
32
- extern VALUE cCurlPostField;
33
-
34
- void append_to_form(VALUE self,
35
- struct curl_httppost **first,
36
- struct curl_httppost **last);
37
-
38
- void init_curb_postfield();
39
-
40
- #endif
1
+ /* curb_postfield.h - Field class for POST method
2
+ * Copyright (c)2006 Ross Bamford.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ *
5
+ * $Id: curb_postfield.h 4 2006-11-17 18:35:31Z roscopeco $
6
+ */
7
+ #ifndef __CURB_POSTFIELD_H
8
+ #define __CURB_POSTFIELD_H
9
+
10
+ #include "curb.h"
11
+
12
+ /*
13
+ * postfield doesn't actually wrap a curl_httppost - instead,
14
+ * it just holds together some ruby objects and has a C-side
15
+ * method to add it to a given form list during the perform.
16
+ */
17
+ typedef struct {
18
+ /* Objects we associate */
19
+ VALUE name;
20
+ VALUE content;
21
+ VALUE content_type;
22
+ VALUE content_proc;
23
+ VALUE local_file;
24
+ VALUE remote_file;
25
+
26
+ /* this will sometimes hold a string, which is the result
27
+ * of the content_proc invocation. We need it to hang around.
28
+ */
29
+ VALUE buffer_str;
30
+ } ruby_curl_postfield;
31
+
32
+ extern VALUE cCurlPostField;
33
+
34
+ void append_to_form(VALUE self,
35
+ struct curl_httppost **first,
36
+ struct curl_httppost **last);
37
+
38
+ void init_curb_postfield();
39
+
40
+ #endif
@@ -1,80 +1,80 @@
1
- /* curb_upload.c - Curl upload handle
2
- * Copyright (c)2009 Todd A Fisher.
3
- * Licensed under the Ruby License. See LICENSE for details.
4
- */
5
- #include "curb_upload.h"
6
- extern VALUE mCurl;
7
- VALUE cCurlUpload;
8
-
9
- #ifdef RDOC_NEVER_DEFINED
10
- mCurl = rb_define_module("Curl");
11
- #endif
12
-
13
- static void curl_upload_mark(ruby_curl_upload *rbcu) {
14
- if (rbcu->stream && !NIL_P(rbcu->stream)) rb_gc_mark(rbcu->stream);
15
- }
16
- static void curl_upload_free(ruby_curl_upload *rbcu) {
17
- free(rbcu);
18
- }
19
-
20
- /*
21
- * call-seq:
22
- * internal class for sending large file uploads
23
- */
24
- VALUE ruby_curl_upload_new(VALUE klass) {
25
- VALUE upload;
26
- ruby_curl_upload *rbcu = ALLOC(ruby_curl_upload);
27
- rbcu->stream = Qnil;
28
- rbcu->offset = 0;
29
- upload = Data_Wrap_Struct(klass, curl_upload_mark, curl_upload_free, rbcu);
30
- return upload;
31
- }
32
-
33
- /*
34
- * call-seq:
35
- * internal class for sending large file uploads
36
- */
37
- VALUE ruby_curl_upload_stream_set(VALUE self, VALUE stream) {
38
- ruby_curl_upload *rbcu;
39
- Data_Get_Struct(self, ruby_curl_upload, rbcu);
40
- rbcu->stream = stream;
41
- return stream;
42
- }
43
- /*
44
- * call-seq:
45
- * internal class for sending large file uploads
46
- */
47
- VALUE ruby_curl_upload_stream_get(VALUE self) {
48
- ruby_curl_upload *rbcu;
49
- Data_Get_Struct(self, ruby_curl_upload, rbcu);
50
- return rbcu->stream;
51
- }
52
- /*
53
- * call-seq:
54
- * internal class for sending large file uploads
55
- */
56
- VALUE ruby_curl_upload_offset_set(VALUE self, VALUE offset) {
57
- ruby_curl_upload *rbcu;
58
- Data_Get_Struct(self, ruby_curl_upload, rbcu);
59
- rbcu->offset = FIX2LONG(offset);
60
- return offset;
61
- }
62
- /*
63
- * call-seq:
64
- * internal class for sending large file uploads
65
- */
66
- VALUE ruby_curl_upload_offset_get(VALUE self) {
67
- ruby_curl_upload *rbcu;
68
- Data_Get_Struct(self, ruby_curl_upload, rbcu);
69
- return INT2FIX(rbcu->offset);
70
- }
71
-
72
- /* =================== INIT LIB =====================*/
73
- void init_curb_upload() {
74
- cCurlUpload = rb_define_class_under(mCurl, "Upload", rb_cObject);
75
- rb_define_singleton_method(cCurlUpload, "new", ruby_curl_upload_new, 0);
76
- rb_define_method(cCurlUpload, "stream=", ruby_curl_upload_stream_set, 1);
77
- rb_define_method(cCurlUpload, "stream", ruby_curl_upload_stream_get, 0);
78
- rb_define_method(cCurlUpload, "offset=", ruby_curl_upload_offset_set, 1);
79
- rb_define_method(cCurlUpload, "offset", ruby_curl_upload_offset_get, 0);
80
- }
1
+ /* curb_upload.c - Curl upload handle
2
+ * Copyright (c)2009 Todd A Fisher.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ */
5
+ #include "curb_upload.h"
6
+ extern VALUE mCurl;
7
+ VALUE cCurlUpload;
8
+
9
+ #ifdef RDOC_NEVER_DEFINED
10
+ mCurl = rb_define_module("Curl");
11
+ #endif
12
+
13
+ static void curl_upload_mark(ruby_curl_upload *rbcu) {
14
+ if (rbcu->stream && !NIL_P(rbcu->stream)) rb_gc_mark(rbcu->stream);
15
+ }
16
+ static void curl_upload_free(ruby_curl_upload *rbcu) {
17
+ free(rbcu);
18
+ }
19
+
20
+ /*
21
+ * call-seq:
22
+ * internal class for sending large file uploads
23
+ */
24
+ VALUE ruby_curl_upload_new(VALUE klass) {
25
+ VALUE upload;
26
+ ruby_curl_upload *rbcu = ALLOC(ruby_curl_upload);
27
+ rbcu->stream = Qnil;
28
+ rbcu->offset = 0;
29
+ upload = Data_Wrap_Struct(klass, curl_upload_mark, curl_upload_free, rbcu);
30
+ return upload;
31
+ }
32
+
33
+ /*
34
+ * call-seq:
35
+ * internal class for sending large file uploads
36
+ */
37
+ VALUE ruby_curl_upload_stream_set(VALUE self, VALUE stream) {
38
+ ruby_curl_upload *rbcu;
39
+ Data_Get_Struct(self, ruby_curl_upload, rbcu);
40
+ rbcu->stream = stream;
41
+ return stream;
42
+ }
43
+ /*
44
+ * call-seq:
45
+ * internal class for sending large file uploads
46
+ */
47
+ VALUE ruby_curl_upload_stream_get(VALUE self) {
48
+ ruby_curl_upload *rbcu;
49
+ Data_Get_Struct(self, ruby_curl_upload, rbcu);
50
+ return rbcu->stream;
51
+ }
52
+ /*
53
+ * call-seq:
54
+ * internal class for sending large file uploads
55
+ */
56
+ VALUE ruby_curl_upload_offset_set(VALUE self, VALUE offset) {
57
+ ruby_curl_upload *rbcu;
58
+ Data_Get_Struct(self, ruby_curl_upload, rbcu);
59
+ rbcu->offset = FIX2LONG(offset);
60
+ return offset;
61
+ }
62
+ /*
63
+ * call-seq:
64
+ * internal class for sending large file uploads
65
+ */
66
+ VALUE ruby_curl_upload_offset_get(VALUE self) {
67
+ ruby_curl_upload *rbcu;
68
+ Data_Get_Struct(self, ruby_curl_upload, rbcu);
69
+ return INT2FIX(rbcu->offset);
70
+ }
71
+
72
+ /* =================== INIT LIB =====================*/
73
+ void init_curb_upload() {
74
+ cCurlUpload = rb_define_class_under(mCurl, "Upload", rb_cObject);
75
+ rb_define_singleton_method(cCurlUpload, "new", ruby_curl_upload_new, 0);
76
+ rb_define_method(cCurlUpload, "stream=", ruby_curl_upload_stream_set, 1);
77
+ rb_define_method(cCurlUpload, "stream", ruby_curl_upload_stream_get, 0);
78
+ rb_define_method(cCurlUpload, "offset=", ruby_curl_upload_offset_set, 1);
79
+ rb_define_method(cCurlUpload, "offset", ruby_curl_upload_offset_get, 0);
80
+ }
@@ -1,30 +1,30 @@
1
- /* curb_upload.h - Curl upload handle
2
- * Copyright (c)2009 Todd A Fisher.
3
- * Licensed under the Ruby License. See LICENSE for details.
4
- */
5
- #ifndef __CURB_UPLOAD_H
6
- #define __CURB_UPLOAD_H
7
-
8
- #include "curb.h"
9
-
10
- #include <curl/easy.h>
11
-
12
- /*
13
- * Maintain the state of an upload e.g. for putting large streams with very little memory
14
- * out to a server. via PUT requests
15
- */
16
- typedef struct {
17
- VALUE stream;
18
- size_t offset;
19
- } ruby_curl_upload;
20
-
21
- extern VALUE cCurlUpload;
22
- void init_curb_upload();
23
-
24
- VALUE ruby_curl_upload_new(VALUE klass);
25
- VALUE ruby_curl_upload_stream_set(VALUE self, VALUE stream);
26
- VALUE ruby_curl_upload_stream_get(VALUE self);
27
- VALUE ruby_curl_upload_offset_set(VALUE self, VALUE offset);
28
- VALUE ruby_curl_upload_offset_get(VALUE self);
29
-
30
- #endif
1
+ /* curb_upload.h - Curl upload handle
2
+ * Copyright (c)2009 Todd A Fisher.
3
+ * Licensed under the Ruby License. See LICENSE for details.
4
+ */
5
+ #ifndef __CURB_UPLOAD_H
6
+ #define __CURB_UPLOAD_H
7
+
8
+ #include "curb.h"
9
+
10
+ #include <curl/easy.h>
11
+
12
+ /*
13
+ * Maintain the state of an upload e.g. for putting large streams with very little memory
14
+ * out to a server. via PUT requests
15
+ */
16
+ typedef struct {
17
+ VALUE stream;
18
+ size_t offset;
19
+ } ruby_curl_upload;
20
+
21
+ extern VALUE cCurlUpload;
22
+ void init_curb_upload();
23
+
24
+ VALUE ruby_curl_upload_new(VALUE klass);
25
+ VALUE ruby_curl_upload_stream_set(VALUE self, VALUE stream);
26
+ VALUE ruby_curl_upload_stream_get(VALUE self);
27
+ VALUE ruby_curl_upload_offset_set(VALUE self, VALUE offset);
28
+ VALUE ruby_curl_upload_offset_get(VALUE self);
29
+
30
+ #endif
@@ -6,29 +6,65 @@
6
6
  module RHACK
7
7
 
8
8
  class Client
9
+ attr_reader :service
9
10
  attr_accessor :f
10
- alias_constant :URI
11
+ class_attribute :frame_defaults
12
+ class_attribute :accounts
13
+ class_attribute :routes
11
14
 
12
- def self.inherited(child)
13
- child.class_eval {
14
- include RHACK
15
- __init__
16
- }
15
+ @@frame_defaults = {}
16
+ @@accounts = {}
17
+ @@routes = {}
18
+
19
+ class << self
20
+
21
+ def inherited(child)
22
+ child.class_eval {
23
+ include RHACK
24
+ __init__
25
+ }
26
+ end
27
+
28
+ private
29
+
30
+ # Set routes map
31
+ def map(dict)
32
+ # URI is deprecated # backward compatibility
33
+ if defined? URI and URI.is Hash
34
+ URI.merge! dict.map_hash {|k, v| [k.to_sym, v.freeze]}
35
+ end
36
+ @@routes.merge! dict.map_hash {|k, v| [k.to_sym, v.freeze]}
37
+ end
38
+
39
+ # Set default Frame options
40
+ def frame(dict)
41
+ @@frame_defaults.merge! dict
42
+ end
43
+
44
+ # Set usable accounts
45
+ # @ dict : {symbol => {symbol => string, ...}}
46
+ def accounts(dict)
47
+ @@accounts.merge! dict
48
+ end
49
+
17
50
  end
18
51
 
19
- def initialize(service=:api, frame=nil, *args)
52
+ def initialize(service=:api, opts={})
20
53
  @service = service
21
54
  # first argument should be a string so that frame won't be static
22
- @f = frame || Frame(URI(service) || URI(:login), *args)
55
+ @f = opts.is_a?(Frame) ?
56
+ opts :
57
+ Frame(route(service) || route(:login), @@frame_defaults.merge(opts))
23
58
  end
24
59
 
60
+
25
61
  # Usable only for sync requests
26
62
  def login(*)
27
63
  Curl.run
28
64
  @f[0].cookies.clear
29
65
  json, wait, @f.opts[:json], @f.opts[:wait] = @f.opts[:json], @f.opts[:wait], false, true
30
- yield @f.get(URI :login)
31
- @f.get(URI :home) if URI :home
66
+ yield @f.get(route :login)
67
+ @f.get(route :home) if route :home
32
68
  @f.opts[:json], @f.opts[:wait] = json, wait
33
69
  @f.copy_cookies!
34
70
  end
@@ -40,6 +76,8 @@ module RHACK
40
76
  Curl.reload
41
77
  end
42
78
 
79
+
80
+
43
81
  def scrape!(page)
44
82
  __send__(:"scrape_#{@service}", page)
45
83
  if url = next_url(page)
@@ -51,6 +89,19 @@ module RHACK
51
89
  "<##{self.class.self_name}:#{@service.to_s.camelize} service via #{@f.inspect}>"
52
90
  end
53
91
 
92
+ # shortcuts to class variables #
93
+
94
+ def route(name)
95
+ @@routes[name]
96
+ end
97
+ alias :url :route
98
+ # URI is deprecated # backward compatibility
99
+ alias :URI :route
100
+
101
+ def account(name)
102
+ @@accounts[name]
103
+ end
104
+
54
105
  end
55
106
 
56
107
  class ClientError < Exception; end
@@ -91,7 +91,7 @@ module RHACK
91
91
  url_params[:redirect_uri].sub!(/^\w+/, redirect_protocol)
92
92
  end
93
93
  L.debug url_params
94
- @oauth_url = URI(:oauth)[:auth] + {
94
+ @oauth_url = route(:oauth)[:auth] + {
95
95
  response_type: 'code',
96
96
  client_id: OAUTH(:id),
97
97
  state: state
@@ -117,7 +117,7 @@ module RHACK
117
117
  url_params[:redirect_uri].sub!(/^\w+/, redirect_protocol)
118
118
  end
119
119
  L.debug url_params
120
- @f.run({}, URI(:oauth)[:token] + {
120
+ @f.run({}, route(:oauth)[:token] + {
121
121
  grant_type: 'authorization_code',
122
122
  client_id: OAUTH(:id),
123
123
  client_secret: OAUTH(:secret)
@@ -141,7 +141,7 @@ module RHACK
141
141
  end
142
142
 
143
143
  def get_application_oauth_token(&block)
144
- @f.run(URI(:oauth)[:token] + {
144
+ @f.run(route(:oauth)[:token] + {
145
145
  grant_type: 'client_credentials',
146
146
  client_id: OAUTH(:id),
147
147
  client_secret: OAUTH(:secret)
@@ -198,7 +198,7 @@ module RHACK
198
198
  L.debug [action_data, action, token]
199
199
  opts = {proc_result: block, headers: {'Referer' => nil}, result: CodeIndiffirentPage}.merge(opts)
200
200
  # TODO: option to
201
- @f.run(URI(:api) % {action: action} + token, opts) {|page|
201
+ @f.run(route(:api) % {action: action} + token, opts) {|page|
202
202
  if page.hash and page.hash != true and error = page.hash.error
203
203
  L.debug state_params
204
204
  if error.code.in([190, 100]) and state_params
@@ -34,6 +34,7 @@ module Curl
34
34
 
35
35
  def retry!
36
36
  @base.retry!
37
+ # <self> is forgotten now
37
38
  end
38
39
 
39
40
  # curb changed getters interface, so i get some shortcuts from curb/lib/curl/easy.rb
@@ -107,6 +107,7 @@ module Curl
107
107
  L.debug caller
108
108
  if @@carier_thread
109
109
  L.log "Recalling Carier thread"
110
+ L.debug {caller[1..10]}
110
111
  @@carier_thread.kill
111
112
  sleep 1
112
113
  else
@@ -118,6 +119,7 @@ module Curl
118
119
  def recall!
119
120
  if @@carier_thread
120
121
  L.warn "Recalling thread and resetting Carier!!!"
122
+ L.debug {caller[1..10]}
121
123
  @@carier_thread.kill
122
124
  @@carier_thread = nil
123
125
  reset_carier!
@@ -66,9 +66,11 @@ module Curl
66
66
  @req.range = $1.to_i .. $2.to_i
67
67
  end
68
68
  if easy.base and @req.meth = easy.base.last_method and @req.meth.in [:post, :put]
69
- @req.body = easy.post_body.dup
70
69
  if @req.meth == :post
71
- @req.mp = easy.multipart_form_post?
70
+ @req.body = easy.post_body.dup
71
+ @req.mp = easy.multipart_form_post?
72
+ else
73
+ @req.body = easy.base.body.dup
72
74
  end
73
75
  end
74
76
  end
data/lib/rhack/frame.rb CHANGED
@@ -25,23 +25,24 @@ module RHACK
25
25
  @@cache = {}
26
26
 
27
27
  def initialize *args
28
- args << 10 unless args[-1].is Fixnum
29
- args.insert -2, {} unless args[-2].is Hash
30
- opts = args[-2]
31
- if scouts = (opts[:scouts] || opts[:threads])
32
- args[-1] = scouts
33
- end
28
+ #args << 10 unless args[-1].is Fixnum
29
+ #args.insert -2, {} unless args[-2].is Hash
30
+ #opts = args[-2]
31
+ #if scouts = (opts[:scouts] || opts[:threads])
32
+ # args[-1] = scouts
33
+ #end
34
+ opts = args.find_by_class Hash
35
+ scouts_count = opts[:scouts] || opts[:threads] || 10
34
36
  @opts = {:eval => Johnson::Enabled, :redir => true, :cp => true, :result => Page}.merge!(opts)
35
- args[-2] = @opts
36
37
  if args[0].is String
37
- url = args[0]
38
+ url = args[0].dup
38
39
  'http://' >> url if url !~ /^\w+:\/\//
39
40
  update_loc url
40
41
  else
41
42
  @loc = {}
42
43
  @static = false
43
44
  end
44
- @ss = ScoutSquad *args
45
+ @ss = ScoutSquad @loc.href, @opts, scouts_count
45
46
  end
46
47
 
47
48
  def update_loc url
@@ -91,8 +92,14 @@ module RHACK
91
92
  "<#Frame @ #{@ss.untargeted ? 'no target' : @loc.root}: #{sssize} #{sssize == 1 ? 'scout' : 'scouts'}#{', static'+(' => '+@static.protocol if @static.is(Hash)) if @static}, cookies #{@ss[0].cookieProc ? 'on' : 'off'}>"
92
93
  end
93
94
 
94
- # opts are :eval, :json, :hash, :wait, :proc_result, :save_result, :load_scripts,
95
- # :zip, :thread_safe, :result, :stream, :raw, :xhr + any opts for Scouts in one hash
95
+ # All opts going in one hash.
96
+ # Opts for Frame:
97
+ # :wait, :proc_result, :save_result, :zip, :thread_safe, :result, :stream, :raw, :xhr, :content_type
98
+ # Opts passed to Page:
99
+ # :xml, :html, :json, :hash, :eval, :load_scripts
100
+ # Opts for Scout:
101
+ # :headers, :redir, :relvl
102
+ # TODO: describe options
96
103
  def exec *args, &callback
97
104
  many, order, orders, with_opts = interpret_request *args
98
105
  L.log({:many => many, :order => order, :orders => orders, :with_opts => with_opts})
@@ -116,31 +123,42 @@ module RHACK
116
123
  L.log [body, mp, url, opts]
117
124
  zip = opts.delete :zip
118
125
  verb = opts.delete :verb
119
- many = order = orders = post = false
120
- # Default options set is for POST
121
- if mp.is String or mp.kinda Array and !(url.is String or url.kinda Array)
122
- # if second arg is String, then that's url
123
- url, mp, post = mp.dup, false, true
124
- # L.debug "url #{url.inspect} has been passed as second argument instead of third"
125
- # But if we have only one argument actually passed
126
- # except for options hash, then believe it's GET
127
- elsif body.is String or body.kinda [String]
128
- L.debug "first parameter (#{body.inspect}) was implicitly taken as url#{' '+body.class if body.kinda Array}, but last paramter is of type #{url.class}, too" if url
129
- url = body.dup
130
- elsif !body
131
- url = nil
126
+ post = put = verb == :put
127
+ many = order = orders = false
128
+
129
+ if put
130
+ # If request is PUT then first argument is always body
131
+ if mp.is String
132
+ # and second is URL if specified
133
+ url = mp.dup
134
+ else
135
+ url = nil
136
+ end
132
137
  else
133
- url = url.dup if url
134
- mp, post = !!mp, true
138
+ # Default options set is for POST
139
+ if mp.is String or mp.kinda Array and !(url.is String or url.kinda Array)
140
+ # if second arg is String then it's URL
141
+ url, mp, post = mp.dup, false, true
142
+ # L.debug "URL #{url.inspect} has been passed as second argument instead of third"
143
+ # But if we have only one argument actually passed
144
+ # except for options hash then believe it's GET
145
+ elsif body.is String or body.kinda [String]
146
+ L.debug "first parameter (#{body.inspect}) was implicitly taken as url#{' '+body.class if body.kinda Array}, but last paramter is of type #{url.class}, too" if url
147
+ url = body.dup
148
+ elsif !body
149
+ url = nil
150
+ else
151
+ url = url.dup if url
152
+ mp, post = !!mp, true
153
+ end
135
154
  end
136
155
 
137
156
  if post
138
- put = verb == :put
139
157
  validate_zip url, body if zip
140
158
  if zip or url.kinda Array or body.kinda Array
141
159
  many = true
142
160
  unless put or body.kinda [Hash]
143
- raise TypeError, "body of post request must be a hash array, params was
161
+ raise TypeError, "body of POST request must be a hash array, params was
144
162
  (#{args.inspect[1..-2]})"
145
163
  end
146
164
 
@@ -157,9 +175,16 @@ module RHACK
157
175
  orders.each {|o| o.unshift :loadPost and o.insert 2, mp}
158
176
  end
159
177
  else
160
- unless put or body.is Hash
161
- raise TypeError, "body of post request must be a hash, params was
162
- (#{args.inspect[1..-2]})"
178
+ if put
179
+ unless body.is String
180
+ raise TypeError, "body of PUT request must be a string, params was
181
+ (#{args.inspect[1..-2]})"
182
+ end
183
+ else
184
+ unless body.is Hash
185
+ raise TypeError, "body of POST request must be a hash, params was
186
+ (#{args.inspect[1..-2]})"
187
+ end
163
188
  end
164
189
 
165
190
  url = validate url
@@ -184,10 +209,21 @@ module RHACK
184
209
  opts[:wait] = opts[:sync] if :sync.in opts
185
210
  opts[:wait] = true if !:wait.in(opts) and
186
211
  :proc_result.in(opts) ? !opts[:proc_result] : opts[:save_result]
212
+
187
213
  opts[:eval] = false if opts[:json] or opts[:hash] or opts[:raw]
188
214
  opts[:load_scripts] = self if opts[:load_scripts]
189
215
  opts[:stream] = true if opts[:raw]
216
+
190
217
  (opts[:headers] ||= {})['X-Requested-With'] = 'XMLHttpRequest' if opts[:xhr]
218
+ if opts[:content_type]
219
+ if mime_type = Mime::Type.lookup_by_extension(opts[:content_type])
220
+ (opts[:headers] ||= {})['Content-Type'] = mime_type
221
+ else
222
+ raise ArgumentError, "failed to detect Mime::Type by extension: #{opts[:content_type]}
223
+ (#{args.inspect[1..-2]})"
224
+ end
225
+ end
226
+
191
227
  [many, order, orders, opts]
192
228
  end
193
229
 
@@ -292,11 +328,13 @@ module RHACK
292
328
  RMTools.rw @write_to+'/'+order[-2].sub(/^[a-z]+:\/\//, ''), curl.res.body.xml_to_utf
293
329
  end
294
330
  if opts[:raw]
295
- page.res = yield curl
331
+ page.res = block_given? ? yield(curl) : curl.body_str
296
332
  # here +curl.res.body+ becomes empty
333
+ # curl.res.body.+xml_to_utf+ -- maybe this is problem?
297
334
  elsif page.process(curl, opts)
298
335
  @@cache[page.href] = page if order[0] == :loadGet and @use_cache
299
336
  run_callbacks! page, opts, &callback
337
+ # nothing to do here if process returns nil or false
300
338
  end
301
339
  }
302
340
  # > Carier.requests++