scanii-ruby 1.1.0 → 1.2.0
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 +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +2 -0
- data/lib/scanii/client.rb +64 -0
- data/lib/scanii/processing_result.rb +12 -2
- data/lib/scanii/trace_event.rb +20 -0
- data/lib/scanii/trace_result.rb +33 -0
- data/lib/scanii/version.rb +1 -1
- data/lib/scanii.rb +2 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2b4cc56c7cdba5d949e11dd004f7dbaa29ada9dab5e7b64173f5a523dc4f4e51
|
|
4
|
+
data.tar.gz: 37b10fb0ee6aa5dfbabf6b9c097fbf837f297fd557e27f0dc97e49278ed355d6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 97c6569f83a40beb529c5d4a2189a57443201d17eafc9be2c75e693316ddf6d98e3306a9819d20346c6f573b0d3fbb182eea3493ad8269f4d8bdeef640b79096
|
|
7
|
+
data.tar.gz: 70cc50536847e7f83fce477098f6feb780ce6bf9ed3571d1ed92b0f8cd6b929eb5dd2fd2bd4cbdc5afc9d4b989f3df07ffdb86ae901e698e66de2884c95811c6
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `scanii-ruby` are documented here. Versions follow [SemVer](https://semver.org).
|
|
4
4
|
|
|
5
|
+
## [1.2.0] — v2.2 surface
|
|
6
|
+
|
|
7
|
+
### New API
|
|
8
|
+
|
|
9
|
+
- `Scanii::Client#retrieve_trace(id)` → `Scanii::TraceResult` or `nil` — retrieves the
|
|
10
|
+
ordered processing event trace for a scan via `GET /files/{id}/trace`. Returns `nil` on 404
|
|
11
|
+
(no trace for that id). v2.2 preview surface; API shape may shift before marked stable.
|
|
12
|
+
- `Scanii::Client#process_from_url(location, callback: nil, metadata: nil)` →
|
|
13
|
+
`Scanii::ProcessingResult` — submits a URL for synchronous scanning via `POST /files` with
|
|
14
|
+
`location` as a multipart/form-data field. Distinct from `fetch`, which submits to
|
|
15
|
+
`/files/fetch` for asynchronous server-side fetching. `location` must be a String URL.
|
|
16
|
+
v2.2 preview surface.
|
|
17
|
+
- `Scanii::TraceResult` — new result class with `id`, `events`, `request_id`, `host_id`,
|
|
18
|
+
`raw_response`.
|
|
19
|
+
- `Scanii::TraceEvent` — new model with `timestamp` (String) and `message` (String).
|
|
20
|
+
|
|
21
|
+
### Deprecations
|
|
22
|
+
|
|
23
|
+
- `Scanii::ProcessingResult#error` — deprecated. The server never populates this field on
|
|
24
|
+
successful responses; errors arrive as non-2xx HTTP responses that raise `Scanii::Error`
|
|
25
|
+
subclasses. The field still exists and emits a runtime `warn` on access. Will be removed
|
|
26
|
+
in a future major version.
|
|
27
|
+
|
|
5
28
|
## 1.1.0 — Streaming standardization
|
|
6
29
|
|
|
7
30
|
Adds stream-based `process` and `process_async` methods, aligning scanii-ruby with the
|
data/README.md
CHANGED
|
@@ -60,8 +60,10 @@ puts "findings: #{result.findings.inspect}"
|
|
|
60
60
|
| `process_file(path, metadata:, callback:)` | `POST /files` | `Scanii::ProcessingResult` |
|
|
61
61
|
| `process_async(io, filename:, content_type:, metadata:, callback:)` | `POST /files/async` | `Scanii::PendingResult` |
|
|
62
62
|
| `process_async_file(path, metadata:, callback:)` | `POST /files/async` | `Scanii::PendingResult` |
|
|
63
|
+
| `process_from_url(location, callback:, metadata:)` | `POST /files` | `Scanii::ProcessingResult` (v2.2 preview) |
|
|
63
64
|
| `fetch(url, metadata:, callback:)` | `POST /files/fetch` | `Scanii::PendingResult` |
|
|
64
65
|
| `retrieve(id)` | `GET /files/{id}` | `Scanii::ProcessingResult` |
|
|
66
|
+
| `retrieve_trace(id)` | `GET /files/{id}/trace` | `Scanii::TraceResult` or `nil` (v2.2 preview) |
|
|
65
67
|
| `ping` | `GET /ping` | `true` |
|
|
66
68
|
| `create_auth_token(timeout_seconds)` | `POST /auth/tokens` | `Scanii::AuthToken` |
|
|
67
69
|
| `retrieve_auth_token(id)` | `GET /auth/tokens/{id}` | `Scanii::AuthToken` |
|
data/lib/scanii/client.rb
CHANGED
|
@@ -184,6 +184,70 @@ module Scanii
|
|
|
184
184
|
ProcessingResult.from_response(resp_body, headers)
|
|
185
185
|
end
|
|
186
186
|
|
|
187
|
+
# Retrieve the processing event trace for a previously submitted scan.
|
|
188
|
+
#
|
|
189
|
+
# Returns nil when no trace exists for the given id (HTTP 404).
|
|
190
|
+
#
|
|
191
|
+
# This is a v2.2 preview surface; the API shape may shift before it is
|
|
192
|
+
# marked stable.
|
|
193
|
+
#
|
|
194
|
+
# @param id [String] processing id returned by process or process_file
|
|
195
|
+
# @see https://scanii.github.io/openapi/v22/ GET /files/{id}/trace
|
|
196
|
+
# @return [Scanii::TraceResult, nil]
|
|
197
|
+
def retrieve_trace(id)
|
|
198
|
+
raise ArgumentError, "id must not be empty" if id.nil? || id.empty?
|
|
199
|
+
|
|
200
|
+
status, resp_body, headers = request("GET", "/files/#{url_encode(id)}/trace")
|
|
201
|
+
return nil if status == 404
|
|
202
|
+
|
|
203
|
+
raise_for_status(status, resp_body, headers) unless status == 200
|
|
204
|
+
TraceResult.from_response(resp_body, headers)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Submit a remote URL for synchronous scanning.
|
|
208
|
+
#
|
|
209
|
+
# Sends the URL as a +location+ field in a multipart/form-data POST to
|
|
210
|
+
# +/files+. The Scanii server fetches and scans the URL synchronously and
|
|
211
|
+
# returns a ProcessingResult. This is distinct from {#fetch}, which submits
|
|
212
|
+
# to +/files/fetch+ for asynchronous server-side fetching.
|
|
213
|
+
#
|
|
214
|
+
# +location+ must be a String URL. This matches the existing {#fetch}
|
|
215
|
+
# String-URL convention and the Java reference (processFromUrl(String)).
|
|
216
|
+
#
|
|
217
|
+
# This is a v2.2 preview surface; the API shape may shift before it is
|
|
218
|
+
# marked stable.
|
|
219
|
+
#
|
|
220
|
+
# @param location [String] URL of the content to scan
|
|
221
|
+
# @param callback [String, nil] URL to POST the result to on completion
|
|
222
|
+
# @param metadata [Hash{String=>String}, nil] arbitrary key/value pairs attached to the result
|
|
223
|
+
# @see https://scanii.github.io/openapi/v22/ POST /files
|
|
224
|
+
# @return [Scanii::ProcessingResult]
|
|
225
|
+
def process_from_url(location, callback: nil, metadata: nil)
|
|
226
|
+
raise ArgumentError, "location must not be empty" if location.nil? || location.to_s.empty?
|
|
227
|
+
|
|
228
|
+
fields = build_text_fields(metadata, callback)
|
|
229
|
+
fields["location"] = location.to_s
|
|
230
|
+
|
|
231
|
+
boundary = Multipart.make_boundary
|
|
232
|
+
body = String.new(encoding: Encoding::BINARY)
|
|
233
|
+
fields.each do |name, value|
|
|
234
|
+
body << "--#{boundary}\r\n".b
|
|
235
|
+
body << "Content-Disposition: form-data; name=\"#{name}\"\r\n".b
|
|
236
|
+
body << "Content-Type: text/plain; charset=UTF-8\r\n\r\n".b
|
|
237
|
+
body << value.to_s.b
|
|
238
|
+
body << "\r\n".b
|
|
239
|
+
end
|
|
240
|
+
body << "--#{boundary}--\r\n".b
|
|
241
|
+
|
|
242
|
+
status, resp_body, headers = post(
|
|
243
|
+
"/files",
|
|
244
|
+
body: body,
|
|
245
|
+
content_type: Multipart.make_content_type(boundary)
|
|
246
|
+
)
|
|
247
|
+
raise_for_status(status, resp_body, headers) unless status == 201
|
|
248
|
+
ProcessingResult.from_response(resp_body, headers)
|
|
249
|
+
end
|
|
250
|
+
|
|
187
251
|
# Verify that the configured credentials reach the API.
|
|
188
252
|
#
|
|
189
253
|
# @see https://scanii.github.io/openapi/v22/ GET /ping
|
|
@@ -9,7 +9,7 @@ module Scanii
|
|
|
9
9
|
# @see https://scanii.github.io/openapi/v22/
|
|
10
10
|
class ProcessingResult
|
|
11
11
|
attr_reader :id, :findings, :checksum, :content_length, :content_type,
|
|
12
|
-
:metadata, :creation_date,
|
|
12
|
+
:metadata, :creation_date,
|
|
13
13
|
:request_id, :host_id, :resource_location, :raw_response
|
|
14
14
|
|
|
15
15
|
def initialize(id:, findings:, checksum:, content_length:, content_type:,
|
|
@@ -22,13 +22,23 @@ module Scanii
|
|
|
22
22
|
@content_type = content_type
|
|
23
23
|
@metadata = metadata
|
|
24
24
|
@creation_date = creation_date
|
|
25
|
-
@
|
|
25
|
+
@_error = error
|
|
26
26
|
@request_id = request_id
|
|
27
27
|
@host_id = host_id
|
|
28
28
|
@resource_location = resource_location
|
|
29
29
|
@raw_response = raw_response
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
# @deprecated The server never populates this field on successful responses;
|
|
33
|
+
# errors arrive as non-2xx HTTP responses that raise Scanii::Error
|
|
34
|
+
# subclasses. Will be removed in a future major version.
|
|
35
|
+
def error
|
|
36
|
+
warn "[DEPRECATION] `Scanii::ProcessingResult#error` is deprecated; " \
|
|
37
|
+
"rescue Scanii::Error (and its subclasses) to handle server-side errors. " \
|
|
38
|
+
"Will be removed in a future major version."
|
|
39
|
+
@_error
|
|
40
|
+
end
|
|
41
|
+
|
|
32
42
|
def self.from_response(body, headers)
|
|
33
43
|
json = body.nil? || body.empty? ? {} : JSON.parse(body)
|
|
34
44
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Scanii
|
|
2
|
+
# A single processing event in a {Scanii::TraceResult}.
|
|
3
|
+
#
|
|
4
|
+
# @see https://scanii.github.io/openapi/v22/
|
|
5
|
+
class TraceEvent
|
|
6
|
+
attr_reader :timestamp, :message
|
|
7
|
+
|
|
8
|
+
def initialize(timestamp:, message:)
|
|
9
|
+
@timestamp = timestamp
|
|
10
|
+
@message = message
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.from_hash(hash)
|
|
14
|
+
new(
|
|
15
|
+
timestamp: hash["timestamp"]&.to_s,
|
|
16
|
+
message: hash["message"]&.to_s
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module Scanii
|
|
4
|
+
# Result of Client#retrieve_trace — ordered processing events for a scan.
|
|
5
|
+
#
|
|
6
|
+
# This is a v2.2 preview surface; the API shape may shift before it is
|
|
7
|
+
# marked stable.
|
|
8
|
+
#
|
|
9
|
+
# @see https://scanii.github.io/openapi/v22/
|
|
10
|
+
class TraceResult
|
|
11
|
+
attr_reader :id, :events, :request_id, :host_id, :raw_response
|
|
12
|
+
|
|
13
|
+
def initialize(id:, events:, request_id:, host_id:, raw_response:)
|
|
14
|
+
@id = id
|
|
15
|
+
@events = events
|
|
16
|
+
@request_id = request_id
|
|
17
|
+
@host_id = host_id
|
|
18
|
+
@raw_response = raw_response
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.from_response(body, headers)
|
|
22
|
+
json = body.nil? || body.empty? ? {} : JSON.parse(body)
|
|
23
|
+
|
|
24
|
+
new(
|
|
25
|
+
id: (json["id"] || "").to_s,
|
|
26
|
+
events: Array(json["events"]).map { |e| TraceEvent.from_hash(e) },
|
|
27
|
+
request_id: headers["x-scanii-request-id"],
|
|
28
|
+
host_id: headers["x-scanii-host-id"],
|
|
29
|
+
raw_response: body
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/scanii/version.rb
CHANGED
data/lib/scanii.rb
CHANGED
|
@@ -3,6 +3,8 @@ require_relative "scanii/error"
|
|
|
3
3
|
require_relative "scanii/processing_result"
|
|
4
4
|
require_relative "scanii/pending_result"
|
|
5
5
|
require_relative "scanii/auth_token"
|
|
6
|
+
require_relative "scanii/trace_event"
|
|
7
|
+
require_relative "scanii/trace_result"
|
|
6
8
|
require_relative "scanii/multipart"
|
|
7
9
|
require_relative "scanii/client"
|
|
8
10
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scanii-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Scanii
|
|
@@ -80,6 +80,8 @@ files:
|
|
|
80
80
|
- lib/scanii/multipart.rb
|
|
81
81
|
- lib/scanii/pending_result.rb
|
|
82
82
|
- lib/scanii/processing_result.rb
|
|
83
|
+
- lib/scanii/trace_event.rb
|
|
84
|
+
- lib/scanii/trace_result.rb
|
|
83
85
|
- lib/scanii/version.rb
|
|
84
86
|
homepage: https://github.com/scanii/scanii-ruby
|
|
85
87
|
licenses:
|