sapoci-connect 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0bae5fbcde1485abc6cb0f0da1ce2255f07aea565e6a086c2d54b409488325d2
4
- data.tar.gz: 353065cc83f067446274bfcfeb39bf280edb81d498d9dd55bb465bdb1b800ca2
3
+ metadata.gz: ae2069036bd3958772d6f27b0385184d2c5469ffc6e0644249b9fb0203cc3aea
4
+ data.tar.gz: 11fa7831b52b7886ad839aceb583bba83790e102a3dee3ab10c25da7f7d09eed
5
5
  SHA512:
6
- metadata.gz: ea3985b967fa17c3da6d250381cada9a90a9e4042ac06b83d0799f97bfa2f8f2c2d1730472ee2b8f8528f9ce6b364d3eee988c3e2e0995b0c5a9ed1e32fb5465
7
- data.tar.gz: 5ea36e998eb586cea2fed4f0cd6b0559f4ff439cb414b927f0ba9b19702b253be534cb988f13b2e4720ab7fcdfb3ee1dc77572f6748be945b9251ad8f71a8b42
6
+ metadata.gz: 999fd82bac0ad76b508ff7aaca7dae625a7543168bb6455aafad442025bb5bce55cba72c0016f3d1663eb57948f6f292db27cfee34ddd15ae76aa0420e0bbed4
7
+ data.tar.gz: 78fc3d50523a6a917c24784dca371bb9b9bba88ab679b626312029ad135cf43aaaaf8daa1e53e7f568101d3e87dd063dd3db69e34401870fe3e6ad11301391fc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ *2020-07-28 (0.5.0)*
2
+
3
+ * Require latest versions of all dependencies, including
4
+ Faraday 1.0.1 or later.
5
+ * Require Ruby 2.4 or later.
6
+
7
+
1
8
  *2014-03-14 (0.1.13)*
2
9
 
3
10
  * Fix versioning issues
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007-2012 Oliver Eilhard
1
+ Copyright (c) 2007-2020 Oliver Eilhard
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # SAP OCI Connect
2
2
 
3
+ [![Test](https://github.com/meplato/sapoci-connect/actions/workflows/test.yml/badge.svg)](https://github.com/meplato/sapoci-connect/actions/workflows/test.yml)
4
+
3
5
  We use this library to work with eprocurement punchout systems that
4
- comply to the SAP OCI 4.0 specification.
6
+ comply to the SAP OCI 4.0 and 5.0 specification.
5
7
 
6
8
  ## Features
7
9
 
@@ -9,47 +11,78 @@ comply to the SAP OCI 4.0 specification.
9
11
 
10
12
  It's as simple as this:
11
13
 
12
- conn = Faraday.new("http://onlineshop.com/path", :params => {"token" => "123"}) do |builder|
13
- builder.response :follow_redirects, :cookies => :all, :limit => 5
14
- builder.response :background_search
15
- builder.adapter :net_http
16
- end
17
-
18
- conn.options[:timeout] = 5
19
- conn.options[:open_timeout] = 10
20
-
21
- resp = SAPOCI::Connect.search(:get, conn, "toner", "http://return.to/me")
22
- puts resp.status # => 200
23
- puts resp.body # => <SAPOCI::Document>
24
- puts resp.env[:raw_body] # => "<html>...</html>"
25
-
26
- Review [Faraday](https://github.com/technoweenie/faraday) for details on
27
- connection initiation. We require Faraday version 0.8.0 or later.
14
+ ```ruby
15
+ conn = Faraday.new("http://onlineshop.com/path")
16
+ resp = SAPOCI::Connect.search(:get, conn, "toner", "http://return.to/me")
17
+ puts resp.status # => 200
18
+ puts resp.body # => <SAPOCI::Document>
19
+ puts resp.env[:raw_body] # => "<html>...</html>"
20
+ ```
21
+
22
+ You can configure the Faraday connection in all detail. Just be sure to
23
+ include the SAPOCI middleware. Here's an example:
24
+
25
+ ```ruby
26
+ conn = Faraday.new("http://onlineshop.com/path", params: {"token" => "123"}) do |builder|
27
+ builder.use SAPOCI::Connect::Middleware::FollowRedirects, {cookies: :all, limit: 5}
28
+ builder.use SAPOCI::Connect::Middleware::BackgroundSearch, {preserve_raw: true}
29
+ builder.adapter :net_http
30
+ end
31
+ ```
32
+
33
+ Or, use symbols:
34
+
35
+ ```ruby
36
+ conn = Faraday.new("http://onlineshop.com/path", params: {"token" => "123"}) do |builder|
37
+ builder.use :oci_follow_redirects, {cookies: :all, limit: 5}
38
+ builder.use :oci_background_search, {preserve_raw: true}
39
+ builder.adapter :net_http
40
+ end
41
+ ```
42
+
43
+ The `SAPOCI::Connect::Middleware::FollowRedirects` expands on the existing
44
+ `FaradayMiddleware::FollowRedirects` middleware in that it forwards cookies
45
+ and returns some errors like e.g. when a redirect is blank or
46
+ the maximum number of redirects is reached.
47
+
48
+ The `SAPOCI::Connect::Middleware::BackgroundSearch` automatically parses the
49
+ response body (just like the JSON and XML parser middlewares do), and returns
50
+ an `SAPOCI::Document` to look into. Notice that `{preserve_raw: true}` needs
51
+ to be passed as well if you want the original HTTP response body in
52
+ `response.env[:raw_body]`.
53
+
54
+ Review [Faraday](https://github.com/lostisland/faraday) for details on
55
+ connection initiation. We require Faraday version 1.0.1 or later.
28
56
 
29
57
  ## Testing
30
58
 
31
59
  Here's how to test locally:
32
60
 
33
- $ bundle update
34
- $ # Start a second console
35
- $ ruby test/live_server.rb
36
- $ # Back in first console
37
- $ bundle exec rake test
61
+ ```sh
62
+ bundle install
63
+ # Start a second console
64
+ rake start_test_server
65
+ # Back in first console
66
+ bundle exec rake test
67
+ ```
38
68
 
39
- To test external servers, use the REMOTE environment variable:
69
+ To test remote OCI punchout shops, use the `REMOTE` environment variable:
40
70
 
41
- $ REMOTE="http://remote-site.com/Login.aspx?u=demo&p=secret" rake
71
+ ```sh
72
+ REMOTE="http://remote-site.com/Login.aspx?u=demo&p=secret" rake
73
+ ```
42
74
 
43
75
  ## Credits
44
76
 
45
77
  Standing on the shoulder of giants, where giants include:
46
78
 
47
- * Rick Olson for [faraday](https://github.com/technoweenie/faraday),
79
+ * Rick Olson and all contributors for
80
+ [faraday](https://github.com/lostisland/faraday),
48
81
  * Erik Michaels-Ober, Wynn Netherland, et al. for
49
- [faraday_middleware](https://github.com/pengwynn/faraday_middleware),
50
- * Ilya Grigorik for [em-synchrony](https://github.com/igrigorik/em-synchrony),
51
- [em-http-request](https://github.com/igrigorik/em-http-request) and stuff,
52
- * David Balatero and Paul Dix for [typhoeus](https://github.com/dbalatero/typhoeus)
82
+ [faraday_middleware](https://github.com/lostisland/faraday_middleware)
53
83
 
54
84
  ... and many other contributors. Thanks, guys. You rock!
55
85
 
86
+ ## License
87
+
88
+ MIT. See [LICENSE](https://github.com/meplato/sapoci-connect/blob/master/LICENSE).
data/bin/sapoci-search CHANGED
@@ -55,22 +55,22 @@ begin
55
55
  uri.query = nil
56
56
 
57
57
  # Setup
58
- conn = Faraday.new(uri.to_s, :ssl => {:verify => true}) do |builder|
59
- builder.response :follow_redirects, :cookies => :all, :limit => 10
60
- builder.response :background_search
61
- builder.use Faraday::Response::Logger if options.debug
62
- builder.adapter Faraday.default_adapter
58
+ conn = Faraday.new(uri.to_s, ssl: {verify: true}) do |builder|
59
+ builder.use :oci_follow_redirects, {cookies: :all, limit: 10}
60
+ builder.use :oci_background_search, {preserve_raw: true}
61
+ builder.response :logger if options.debug
62
+ builder.adapter Faraday.default_adapter
63
63
  end
64
64
 
65
65
  # Respect proxy settings
66
66
  options.proxy_uri ||= ENV['SAPOCI_PROXY_URI']
67
- conn.proxy({:uri => options.proxy_uri}) if options.proxy_uri
67
+ conn.proxy({uri: options.proxy_uri}) if options.proxy_uri
68
68
 
69
69
  # Execute
70
70
  method = options.http_post ? :post : :get
71
- resp = SAPOCI::Connect.search(method, conn, keywords, "http://return.to/me", params)
71
+ resp = SAPOCI::Connect.search(method, conn, keywords, "http://validator.meplato.com/oci/punchouts/checkout", params)
72
72
  if resp.status == 200
73
- doc = resp.env[:sapoci]
73
+ doc = resp.body
74
74
  $stdout.puts "%3s %-15s %-30s %s" % ["Idx", "Vendormat", "Description", "Price per unit"]
75
75
  $stdout.puts "".ljust(98, '-')
76
76
  doc.items.each do |item|
@@ -78,23 +78,22 @@ begin
78
78
  $stdout.puts " %s" % [item.longtext]
79
79
  end
80
80
  $stdout.puts "===> #{doc.items.size} items"
81
- $stdout.puts resp.body.to_s if options.debug
81
+ $stdout.puts resp.env[:raw_body].to_s if options.debug
82
82
  exit 0
83
83
  elsif resp.status == 404
84
84
  $stdout.puts "Not found (HTTP status #{resp.status})"
85
- $stdout.puts resp.body.to_s if options.debug
85
+ $stdout.puts resp.env[:raw_body].to_s if options.debug
86
86
  exit 1
87
87
  elsif resp.status == 500
88
88
  $stdout.puts "Server crashed (HTTP status #{resp.status})"
89
- $stdout.puts resp.body.to_s if options.debug
89
+ $stdout.puts resp.env[:raw_body].to_s if options.debug
90
90
  exit 1
91
91
  else
92
92
  $stdout.puts "Error: HTTP status code=#{resp.status}"
93
- $stdout.puts resp.body.to_s if options.debug
93
+ $stdout.puts resp.env[:raw_body].to_s if options.debug
94
94
  exit 1
95
95
  end
96
96
 
97
-
98
97
  rescue => e
99
98
  $stderr.print "#{e.class}: " unless e.class == RuntimeError
100
99
  $stderr.puts e.message
@@ -1,15 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday_middleware/response_middleware'
4
+
1
5
  module SAPOCI
2
6
  module Connect
3
7
  module Middleware
4
- class BackgroundSearch < Faraday::Response::Middleware
5
- def on_complete(env)
6
- case env[:status]
7
- when 200
8
- env[:sapoci] = SAPOCI::Document.from_html(env[:body])
9
- else
10
- end
8
+ # BackgroundSearch is a Faraday response middleware that parses
9
+ # the response body into a SAPOCI::Document.
10
+ #
11
+ # If you want Faraday to preserve the original HTTP response body,
12
+ # pass `preserve_raw: true` to the parser.
13
+ #
14
+ # Example:
15
+ #
16
+ # conn = Faraday.new("http://onlineshop.com/path", params: {"token" => "123"}) do |builder|
17
+ # builder.use SAPOCI::Connect::Middleware::FollowRedirects, {cookies: :all, limit: 5}
18
+ # builder.use SAPOCI::Connect::Middleware::BackgroundSearch, {preserve_raw: true}
19
+ # builder.adapter :net_http
20
+ # end
21
+ class BackgroundSearch < FaradayMiddleware::ResponseMiddleware
22
+ dependency 'sapoci'
23
+
24
+ define_parser do |body, parser_options|
25
+ ::SAPOCI::Document.from_html(body) unless body.empty?
11
26
  end
12
27
  end
28
+
29
+ # Register known middlewares under symbol
30
+ if Faraday::Middleware.respond_to?(:register_middleware)
31
+ Faraday::Middleware.register_middleware oci_background_search: -> { SAPOCI::Connect::Middleware::BackgroundSearch }
32
+ end
13
33
  end
14
34
  end
15
35
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'set'
3
5
  require 'webrick'
@@ -6,7 +8,7 @@ module SAPOCI
6
8
  module Connect
7
9
  module Middleware
8
10
  # Public: Exception thrown when the maximum amount of requests is exceeded.
9
- class RedirectLimitReached < Faraday::Error::ClientError
11
+ class RedirectLimitReached < Faraday::ClientError
10
12
  attr_reader :response
11
13
 
12
14
  def initialize(response)
@@ -14,9 +16,9 @@ module SAPOCI
14
16
  @response = response
15
17
  end
16
18
  end
17
-
19
+
18
20
  # Public: Exception thrown when client returns an empty location header
19
- class RedirectWithoutLocation < Faraday::Error::ClientError
21
+ class RedirectWithoutLocation < Faraday::ClientError
20
22
  attr_reader :response
21
23
 
22
24
  def initialize(response)
@@ -24,54 +26,62 @@ module SAPOCI
24
26
  @response = response
25
27
  end
26
28
  end
27
-
28
- # Public: Follow HTTP 301, 302, 303, and 307 redirects for GET, PATCH, POST,
29
- # PUT, and DELETE requests.
29
+
30
+ # Public: Follow HTTP 301, 302, 303, 307, and 308 redirects.
30
31
  #
31
- # This middleware does not follow the HTTP specification for HTTP 302, by
32
- # default, in that it follows the improper implementation used by most major
33
- # web browsers which forces the redirected request to become a GET request
34
- # regardless of the original request method.
32
+ # For HTTP 301, 302, and 303, the original GET, POST, PUT, DELETE, or PATCH
33
+ # request gets converted into a GET. With `standards_compliant: true`,
34
+ # however, the HTTP method after 301/302 remains unchanged. This allows you
35
+ # to opt into HTTP/1.1 compliance and act unlike the major web browsers.
35
36
  #
36
- # For HTTP 301, 302, and 303, the original request is transformed into a
37
- # GET request to the response Location, by default. However, with standards
38
- # compliance enabled, a 302 will instead act in accordance with the HTTP
39
- # specification, which will replay the original request to the received
40
- # Location, just as with a 307.
37
+ # This middleware currently only works with synchronous requests; i.e. it
38
+ # doesn't support parallelism.
41
39
  #
42
- # For HTTP 307, the original request is replayed to the response Location,
43
- # including original HTTP request method (GET, POST, PUT, DELETE, PATCH),
44
- # original headers, and original body.
40
+ # Example:
45
41
  #
46
- # This middleware currently only works with synchronous requests; in other
47
- # words, it doesn't support parallelism.
42
+ # Faraday.new(url: url) do |faraday|
43
+ # faraday.use SAPOCI::Connect::Middleware::FollowRedirects
44
+ # faraday.adapter Faraday.default_adapter
45
+ # end
48
46
  class FollowRedirects < Faraday::Middleware
49
47
  # HTTP methods for which 30x redirects can be followed
50
- ALLOWED_METHODS = Set.new [:get, :post, :put, :patch, :delete]
48
+ ALLOWED_METHODS = Set.new %i[head options get post put patch delete]
51
49
  # HTTP redirect status codes that this middleware implements
52
- REDIRECT_CODES = Set.new [301, 302, 303, 307]
50
+ REDIRECT_CODES = Set.new [301, 302, 303, 307, 308]
53
51
  # Keys in env hash which will get cleared between requests
54
- ENV_TO_CLEAR = Set.new [:status, :response, :response_headers]
52
+ ENV_TO_CLEAR = Set.new %i[status response response_headers]
55
53
 
56
54
  # Default value for max redirects followed
57
55
  FOLLOW_LIMIT = 3
58
56
 
57
+ # Regex that matches characters that need to be escaped in URLs, sans
58
+ # the "%" character which we assume already represents an escaped sequence.
59
+ URI_UNSAFE = %r{[^\-_.!~*'()a-zA-Z\d;/?:@&=+$,\[\]%]}.freeze
60
+
61
+ AUTH_HEADER = 'Authorization'
62
+
59
63
  # Public: Initialize the middleware.
60
64
  #
61
65
  # options - An options Hash (default: {}):
62
- # limit - A Numeric redirect limit (default: 3)
63
- # standards_compliant - A Boolean indicating whether to respect
64
- # the HTTP spec when following 302
65
- # (default: false)
66
+ # :limit - A Numeric redirect limit (default: 3)
67
+ # :standards_compliant - A Boolean indicating whether to respect
68
+ # the HTTP spec when following 301/302
69
+ # (default: false)
70
+ # :callback - A callable used on redirects
71
+ # with the old and new envs
72
+ # :cookies - An Array of Strings (e.g.
73
+ # ['cookie1', 'cookie2']) to choose
74
+ # cookies to be kept, or :all to keep
75
+ # all cookies (default: []).
76
+ # :clear_authorization_header - A Boolean indicating whether the request
77
+ # Authorization header should be cleared on
78
+ # redirects (default: true)
66
79
  def initialize(app, options = {})
67
80
  super(app)
68
81
  @options = options
69
82
 
70
- @options[:cookies] = :all
71
- @cookies = []
72
-
73
- @replay_request_codes = Set.new [307]
74
- @replay_request_codes << 302 if standards_compliant?
83
+ @convert_to_get = Set.new [303]
84
+ @convert_to_get << 301 << 302 unless standards_compliant?
75
85
  end
76
86
 
77
87
  def call(env)
@@ -80,72 +90,115 @@ module SAPOCI
80
90
 
81
91
  private
82
92
 
83
- def transform_into_get?(response)
84
- !@replay_request_codes.include? response.status
93
+ def convert_to_get?(response)
94
+ !%i[head options].include?(response.env[:method]) &&
95
+ @convert_to_get.include?(response.status)
85
96
  end
86
97
 
87
98
  def perform_with_redirection(env, follows)
88
99
  request_body = env[:body]
89
100
  response = @app.call(env)
90
101
 
91
- response.on_complete do |env|
92
- if follow_redirect?(env, response)
93
- raise RedirectLimitReached, response if follows.zero?
94
- env = update_env(env, request_body, response)
95
- response = perform_with_redirection(env, follows - 1)
102
+ response.on_complete do |response_env|
103
+ if follow_redirect?(response_env, response)
104
+ raise SAPOCI::Connect::Middleware::RedirectLimitReached, response if follows.zero?
105
+
106
+ new_request_env = update_env(response_env.dup, request_body, response)
107
+ callback&.call(response_env, new_request_env)
108
+ response = perform_with_redirection(new_request_env, follows - 1)
96
109
  end
97
110
  end
98
111
  response
99
112
  end
100
113
 
101
114
  def update_env(env, request_body, response)
102
- location = response['location']
103
- raise RedirectWithoutLocation, response if location.to_s.size == 0
104
- env[:url] += location
105
-
115
+ redirect_from_url = env[:url].to_s
116
+ redirect_to_url = safe_escape(response['location'] || '')
117
+ raise RedirectWithoutLocation, response if redirect_to_url.blank?
118
+ env[:url] += redirect_to_url
119
+
106
120
  if @options[:cookies] && cookie_string = collect_cookies(env)
107
121
  env[:request_headers]['Cookie'] = cookie_string
108
122
  end
109
123
 
110
- if transform_into_get?(response)
124
+ ENV_TO_CLEAR.each { |key| env.delete key }
125
+
126
+ if convert_to_get?(response)
111
127
  env[:method] = :get
112
128
  env[:body] = nil
113
129
  else
114
130
  env[:body] = request_body
115
131
  end
116
132
 
117
- ENV_TO_CLEAR.each {|key| env.delete key }
133
+ clear_authorization_header(env, redirect_from_url, redirect_to_url)
118
134
 
119
135
  env
120
136
  end
121
137
 
122
138
  def follow_redirect?(env, response)
123
- ALLOWED_METHODS.include? env[:method] and
124
- REDIRECT_CODES.include? response.status
139
+ ALLOWED_METHODS.include?(env[:method]) &&
140
+ REDIRECT_CODES.include?(response.status)
125
141
  end
126
142
 
127
143
  def follow_limit
128
144
  @options.fetch(:limit, FOLLOW_LIMIT)
129
145
  end
130
146
 
147
+ def standards_compliant?
148
+ @options.fetch(:standards_compliant, false)
149
+ end
150
+
151
+ def callback
152
+ @options[:callback]
153
+ end
154
+
155
+ # Internal: escapes unsafe characters from an URL which might be a path
156
+ # component only or a fully qualified URI so that it can be joined onto an
157
+ # URI:HTTP using the `+` operator. Doesn't escape "%" characters so to not
158
+ # risk double-escaping.
159
+ def safe_escape(uri)
160
+ uri = uri.split('#')[0] # we want to remove the fragment if present
161
+ uri.to_s.gsub(URI_UNSAFE) do |match|
162
+ '%' + match.unpack('H2' * match.bytesize).join('%').upcase
163
+ end
164
+ end
165
+
166
+ def clear_authorization_header(env, from_url, to_url)
167
+ return env if redirect_to_same_host?(from_url, to_url)
168
+ return env unless @options.fetch(:clear_authorization_header, true)
169
+
170
+ env[:request_headers].delete(AUTH_HEADER)
171
+ end
172
+
173
+ def redirect_to_same_host?(from_url, to_url)
174
+ return true if to_url.start_with?('/')
175
+
176
+ from_uri = URI.parse(from_url)
177
+ to_uri = URI.parse(to_url)
178
+
179
+ [from_uri.scheme, from_uri.host, from_uri.port] ==
180
+ [to_uri.scheme, to_uri.host, to_uri.port]
181
+ end
182
+
131
183
  def collect_cookies(env)
132
184
  if response_cookies = env[:response_headers]['Set-Cookie']
133
185
  @cookies = WEBrick::Cookie.parse_set_cookies(response_cookies)
134
186
  @cookies.inject([]) do |result, cookie|
135
- # TODO only send back cookies where path is nil or
136
- # path matches according to env[:url]
137
- result << cookie.name + "=" + cookie.value
138
- end.uniq.join(";")
187
+ # only send back name and value
188
+ if @options[:cookies] == :all || (@options[:cookies].include?(cookie.name.to_sym) || @options[:cookies].include?(cookie.name.to_s))
189
+ result << cookie.name + "=" + cookie.value
190
+ end
191
+ end.to_a.uniq.join(";")
139
192
  else
140
193
  nil
141
194
  end
142
195
  end
196
+ end
143
197
 
144
- def standards_compliant?
145
- @options.fetch(:standards_compliant, false)
146
- end
198
+ # Register known middlewares under symbol
199
+ if Faraday::Middleware.respond_to?(:register_middleware)
200
+ Faraday::Middleware.register_middleware oci_follow_redirects: -> { SAPOCI::Connect::Middleware::FollowRedirects }
147
201
  end
148
202
  end
149
203
  end
150
204
  end
151
-
@@ -1,34 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
4
+ require 'faraday_middleware'
2
5
  require 'sapoci'
3
6
  require 'sapoci/connect/middleware/follow_redirects'
4
7
  require 'sapoci/connect/middleware/background_search'
5
8
 
6
9
  module SAPOCI
7
10
  module Connect
8
-
9
- # Register Faraday middleware
10
- if Faraday.respond_to?(:register_middleware)
11
- Faraday.register_middleware :response,
12
- :follow_redirects => lambda { SAPOCI::Connect::Middleware::FollowRedirects },
13
- :background_search => lambda { SAPOCI::Connect::Middleware::BackgroundSearch }
14
- end
15
-
16
11
  # Perform an OCI background search.
17
12
  #
18
13
  # If you need to follow redirects and pass cookies along, you should
19
14
  # initialize and use Faraday with this pattern:
20
15
  #
21
- # conn = Faraday.new("http://shop.com/path", :params => {"optional" => "value"}) do |builder|
22
- # builder.response :follow_redirects, :cookies => :all, :limit => 5, :standards_compliant => true
23
- # builder.response :background_search
24
- # builder.adapter Faraday.default_adapter
25
- # end
16
+ # conn = Faraday.new("http://shop.com/path", params: {"optional" => "value"})
26
17
  # conn.options[:timeout] = 3
27
18
  # conn.options[:open_timeout] = 5
19
+ #
28
20
  # resp = SAPOCI::Connect.search(:get, conn, "toner", "http://return.to/me")
29
- # puts resp.status # => 200
30
- # puts resp.body # => <SAPOCI::Document>
21
+ # puts resp.status # => 200
22
+ # puts resp.body # => <SAPOCI::Document>
23
+ # puts resp.env[:raw_body] # => "<html>...</html>"
31
24
  #
25
+ # Notice you can configure the Faraday connection:
26
+ #
27
+ # conn = Faraday.new("http://shop.com/path", params: {"optional" => "value"}) do |builder|
28
+ # builder.use SAPOCI::Connect::Middleware::FollowRedirects, {cookies: :all, limit: 5}
29
+ # builder.use SAPOCI::Connect::Middleware::BackgroundSearch, {preserve_raw: true}
30
+ # builder.adapter Faraday.default_adapter
31
+ # end
32
+ #
33
+ # ... or with symbols:
34
+ #
35
+ # conn = Faraday.new("http://shop.com/path", params: {"optional" => "value"}) do |builder|
36
+ # builder.use :oci_follow_redirects, {cookies: :all, limit: 5}
37
+ # builder.use :oci_background_search, {preserve_raw: true}
38
+ # builder.adapter Faraday.default_adapter
39
+ # end
32
40
  def self.search(method, connection, keywords, hook_url, extra_params = nil)
33
41
  params = {
34
42
  "FUNCTION" => "BACKGROUND_SEARCH",
@@ -37,8 +45,11 @@ module SAPOCI
37
45
  }
38
46
  params.update(extra_params) if extra_params
39
47
 
48
+ unless connection.builder.handlers.include?(SAPOCI::Connect::Middleware::FollowRedirects)
49
+ connection.use SAPOCI::Connect::Middleware::FollowRedirects, {cookies: :all, limit: 5}
50
+ end
40
51
  unless connection.builder.handlers.include?(SAPOCI::Connect::Middleware::BackgroundSearch)
41
- connection.response :background_search
52
+ connection.use SAPOCI::Connect::Middleware::BackgroundSearch, {preserve_raw: true}
42
53
  end
43
54
 
44
55
  case method.to_sym
@@ -48,7 +59,7 @@ module SAPOCI
48
59
  end
49
60
  when :post
50
61
  connection.post do |req|
51
- req.body = Faraday::Utils.build_nested_query params
62
+ req.body = Faraday::Utils.build_nested_query(params)
52
63
  end
53
64
  else
54
65
  raise "SAPOCI::Connect.search only allows :get or :post requests"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sapoci-connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Eilhard
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-30 00:00:00.000000000 Z
11
+ date: 2021-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -16,104 +16,146 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.8'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '0.9'
19
+ version: 1.4.1
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '0.8'
30
- - - "<"
26
+ version: 1.4.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
31
39
  - !ruby/object:Gem::Version
32
- version: '0.9'
40
+ version: 1.0.0
33
41
  - !ruby/object:Gem::Dependency
34
42
  name: rack
35
43
  requirement: !ruby/object:Gem::Requirement
36
44
  requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
37
48
  - - ">="
38
49
  - !ruby/object:Gem::Version
39
- version: 1.6.11
50
+ version: 2.0.9
40
51
  type: :runtime
41
52
  prerelease: false
42
53
  version_requirements: !ruby/object:Gem::Requirement
43
54
  requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '2.0'
44
58
  - - ">="
45
59
  - !ruby/object:Gem::Version
46
- version: 1.6.11
60
+ version: 2.0.9
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: sapoci
49
63
  requirement: !ruby/object:Gem::Requirement
50
64
  requirements:
51
65
  - - "~>"
52
66
  - !ruby/object:Gem::Version
53
- version: 0.4.0
67
+ version: 0.5.3
54
68
  type: :runtime
55
69
  prerelease: false
56
70
  version_requirements: !ruby/object:Gem::Requirement
57
71
  requirements:
58
72
  - - "~>"
59
73
  - !ruby/object:Gem::Version
60
- version: 0.4.0
74
+ version: 0.5.3
75
+ - !ruby/object:Gem::Dependency
76
+ name: webrick
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 1.6.1
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 1.6.1
61
89
  - !ruby/object:Gem::Dependency
62
90
  name: bundler
63
91
  requirement: !ruby/object:Gem::Requirement
64
92
  requirements:
65
93
  - - "~>"
66
94
  - !ruby/object:Gem::Version
67
- version: 2.0.1
95
+ version: 2.2.17
68
96
  type: :development
69
97
  prerelease: false
70
98
  version_requirements: !ruby/object:Gem::Requirement
71
99
  requirements:
72
100
  - - "~>"
73
101
  - !ruby/object:Gem::Version
74
- version: 2.0.1
102
+ version: 2.2.17
75
103
  - !ruby/object:Gem::Dependency
76
104
  name: rdoc
77
105
  requirement: !ruby/object:Gem::Requirement
78
106
  requirements:
79
107
  - - "~>"
80
108
  - !ruby/object:Gem::Version
81
- version: 3.12.1
109
+ version: 6.3.1
82
110
  type: :development
83
111
  prerelease: false
84
112
  version_requirements: !ruby/object:Gem::Requirement
85
113
  requirements:
86
114
  - - "~>"
87
115
  - !ruby/object:Gem::Version
88
- version: 3.12.1
116
+ version: 6.3.1
89
117
  - !ruby/object:Gem::Dependency
90
118
  name: rake
91
119
  requirement: !ruby/object:Gem::Requirement
92
120
  requirements:
93
121
  - - "~>"
94
122
  - !ruby/object:Gem::Version
95
- version: '10.1'
123
+ version: 13.0.3
96
124
  type: :development
97
125
  prerelease: false
98
126
  version_requirements: !ruby/object:Gem::Requirement
99
127
  requirements:
100
128
  - - "~>"
101
129
  - !ruby/object:Gem::Version
102
- version: '10.1'
130
+ version: 13.0.3
103
131
  - !ruby/object:Gem::Dependency
104
132
  name: sinatra
105
133
  requirement: !ruby/object:Gem::Requirement
106
134
  requirements:
107
- - - ">="
135
+ - - "~>"
108
136
  - !ruby/object:Gem::Version
109
- version: 1.4.8
137
+ version: '2.1'
110
138
  type: :development
111
139
  prerelease: false
112
140
  version_requirements: !ruby/object:Gem::Requirement
113
141
  requirements:
114
- - - ">="
142
+ - - "~>"
115
143
  - !ruby/object:Gem::Version
116
- version: 1.4.8
144
+ version: '2.1'
145
+ - !ruby/object:Gem::Dependency
146
+ name: sinatra-contrib
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '2.1'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '2.1'
117
159
  description: HTTP client library for working with SAP OCI compliant servers.
118
160
  email:
119
161
  - oliver.eilhard@gmail.com
@@ -136,7 +178,7 @@ homepage: http://github.com/meplato/sapoci-connect
136
178
  licenses:
137
179
  - MIT
138
180
  metadata: {}
139
- post_install_message:
181
+ post_install_message:
140
182
  rdoc_options:
141
183
  - "--charset=UTF-8"
142
184
  require_paths:
@@ -145,15 +187,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
145
187
  requirements:
146
188
  - - ">="
147
189
  - !ruby/object:Gem::Version
148
- version: '0'
190
+ version: '2.6'
149
191
  required_rubygems_version: !ruby/object:Gem::Requirement
150
192
  requirements:
151
193
  - - ">="
152
194
  - !ruby/object:Gem::Version
153
- version: 1.3.6
195
+ version: '0'
154
196
  requirements: []
155
- rubygems_version: 3.0.3
156
- signing_key:
197
+ rubygems_version: 3.2.22
198
+ signing_key:
157
199
  specification_version: 4
158
200
  summary: The library builds on the sapoci gem and adds working with remotes, parsing
159
201
  its results etc.