bidi2pdf 0.1.3 → 0.1.5
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/.rubocop.yml +19 -1
- data/CHANGELOG.md +40 -3
- data/README.md +145 -55
- data/docker/Dockerfile.chromedriver +5 -0
- data/docker/entrypoint.sh +11 -1
- data/lib/bidi2pdf/bidi/add_headers_interceptor.rb +18 -21
- data/lib/bidi2pdf/bidi/auth_interceptor.rb +31 -38
- data/lib/bidi2pdf/bidi/browser_tab.rb +47 -53
- data/lib/bidi2pdf/bidi/client.rb +24 -52
- data/lib/bidi2pdf/bidi/command_manager.rb +50 -28
- data/lib/bidi2pdf/bidi/commands/add_intercept.rb +41 -0
- data/lib/bidi2pdf/bidi/commands/base.rb +73 -0
- data/lib/bidi2pdf/bidi/commands/browser_close.rb +15 -0
- data/lib/bidi2pdf/bidi/commands/browser_create_user_context.rb +15 -0
- data/lib/bidi2pdf/bidi/commands/browsing_context_close.rb +25 -0
- data/lib/bidi2pdf/bidi/commands/browsing_context_navigate.rb +31 -0
- data/lib/bidi2pdf/bidi/commands/browsing_context_print.rb +28 -0
- data/lib/bidi2pdf/bidi/commands/cancel_auth.rb +26 -0
- data/lib/bidi2pdf/bidi/commands/create_tab.rb +11 -0
- data/lib/bidi2pdf/bidi/commands/create_window.rb +32 -0
- data/lib/bidi2pdf/bidi/commands/get_user_contexts.rb +15 -0
- data/lib/bidi2pdf/bidi/commands/network_continue.rb +29 -0
- data/lib/bidi2pdf/bidi/commands/print_parameters_validator.rb +116 -0
- data/lib/bidi2pdf/bidi/commands/provide_credentials.rb +33 -0
- data/lib/bidi2pdf/bidi/commands/script_evaluate.rb +33 -0
- data/lib/bidi2pdf/bidi/commands/session_end.rb +15 -0
- data/lib/bidi2pdf/bidi/commands/session_status.rb +15 -0
- data/lib/bidi2pdf/bidi/commands/session_subscribe.rb +25 -0
- data/lib/bidi2pdf/bidi/commands/set_tab_cookie.rb +71 -0
- data/lib/bidi2pdf/bidi/commands/set_usercontext_cookie.rb +67 -0
- data/lib/bidi2pdf/bidi/commands.rb +27 -0
- data/lib/bidi2pdf/bidi/connection_manager.rb +16 -13
- data/lib/bidi2pdf/bidi/event_manager.rb +2 -0
- data/lib/bidi2pdf/bidi/interceptor.rb +75 -0
- data/lib/bidi2pdf/bidi/network_events.rb +0 -1
- data/lib/bidi2pdf/bidi/session.rb +139 -65
- data/lib/bidi2pdf/bidi/user_context.rb +25 -31
- data/lib/bidi2pdf/bidi/web_socket_dispatcher.rb +2 -0
- data/lib/bidi2pdf/chromedriver_manager.rb +2 -1
- data/lib/bidi2pdf/cli.rb +12 -7
- data/lib/bidi2pdf/dsl.rb +45 -0
- data/lib/bidi2pdf/launcher.rb +6 -2
- data/lib/bidi2pdf/session_runner.rb +9 -2
- data/lib/bidi2pdf/version.rb +1 -1
- data/lib/bidi2pdf.rb +16 -1
- data/sig/bidi2pdf/bidi/command_manager.rbs +41 -0
- data/sig/bidi2pdf/bidi/commands/add_intercept.rbs +21 -0
- data/sig/bidi2pdf/bidi/commands/base.rbs +27 -0
- data/sig/bidi2pdf/bidi/commands/browser_close.rbs +9 -0
- data/sig/bidi2pdf/bidi/commands/browser_create_user_context.rbs +9 -0
- data/sig/bidi2pdf/bidi/commands/browsing_context_close.rbs +11 -0
- data/sig/bidi2pdf/bidi/commands/browsing_context_navigate.rbs +15 -0
- data/sig/bidi2pdf/bidi/commands/browsing_context_print.rbs +14 -0
- data/sig/bidi2pdf/bidi/commands/cancel_auth.rbs +11 -0
- data/sig/bidi2pdf/bidi/commands/create_tab.rbs +9 -0
- data/sig/bidi2pdf/bidi/commands/create_window.rbs +19 -0
- data/sig/bidi2pdf/bidi/commands/get_user_contexts.rbs +9 -0
- data/sig/bidi2pdf/bidi/commands/network_continue.rbs +19 -0
- data/sig/bidi2pdf/bidi/commands/print_parameters_validator.rbs +53 -0
- data/sig/bidi2pdf/bidi/commands/provide_credentials.rbs +15 -0
- data/sig/bidi2pdf/bidi/commands/script_evaluate.rbs +17 -0
- data/sig/bidi2pdf/bidi/commands/session_end.rbs +9 -0
- data/sig/bidi2pdf/bidi/commands/session_status.rbs +9 -0
- data/sig/bidi2pdf/bidi/commands/session_subscribe.rbs +15 -0
- data/sig/bidi2pdf/bidi/commands/set_tab_cookie.rbs +31 -0
- data/sig/bidi2pdf/bidi/commands/set_usercontext_cookie.rbs +27 -0
- data/sig/bidi2pdf/bidi/commands.rbs +6 -0
- data/sig/bidi2pdf/bidi/connection_manager.rbs +17 -0
- data/sig/bidi2pdf/bidi/interceptor.rbs +31 -0
- data/tasks/coverage.rake +16 -0
- metadata +66 -11
- data/lib/bidi2pdf/bidi/print_parameters_validator.rb +0 -114
- data/sig/bidi2pdf/bidi/print_parameters_validator.rbs +0 -44
- data/sig/bidi2pdf/chrome/chromedriver_downloader.rbs +0 -11
- data/sig/bidi2pdf/chrome/downloader_helper.rbs +0 -9
- data/sig/bidi2pdf/chrome/finder.rbs +0 -27
- data/sig/bidi2pdf/chrome/platform.rbs +0 -13
- data/sig/bidi2pdf/chrome/version_resolver.rbs +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b92ff566ca3ae322033cd9602818c94ae30da2594c7075bbb86f4c16351d58ce
|
4
|
+
data.tar.gz: 1b4d46aa7fe35c1810522a51400c3558f04d8fdc4093c7b3efa0f507a4959392
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63aa303c4dc6245510cb212adaf22523190d8e00892f4ffe9dc9ba9b65e966f74517ee748f4a232736701a3271ae086879fcbf0adc02ce9f9cd82d103ea3e70d
|
7
|
+
data.tar.gz: 320a0a03c399541157bd192b6389fecf5541c994cdcaa186694085887ecc8de0829b63badc2be5fa0cd2b8c9baa4ee60bfe7a2f457743d4f21506f1d4bb44850
|
data/.rubocop.yml
CHANGED
@@ -20,11 +20,29 @@ RSpec/ExampleLength:
|
|
20
20
|
Layout/MultilineMethodCallIndentation:
|
21
21
|
Enabled: false
|
22
22
|
|
23
|
+
Layout/FirstArgumentIndentation:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Layout/ClosingParenthesisIndentation:
|
27
|
+
Enabled: false
|
28
|
+
|
23
29
|
Layout/FirstHashElementIndentation:
|
24
30
|
EnforcedStyle: consistent
|
25
31
|
|
26
32
|
Layout/FirstArrayElementIndentation:
|
27
|
-
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
Layout/MultilineOperationIndentation:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
Layout/BeginEndAlignment:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Layout/ArrayAlignment:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
Layout/LineLength:
|
45
|
+
Enabled: false
|
28
46
|
|
29
47
|
RSpec/MultipleMemoizedHelpers:
|
30
48
|
Max: 10
|
data/CHANGELOG.md
CHANGED
@@ -6,12 +6,49 @@ All notable changes to this project will be documented in this file.
|
|
6
6
|
|
7
7
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
8
8
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
9
|
+
[unreleased]: https://github.com/dieter-medium/bidi2pdf/compare/v0.1.5..HEAD
|
9
10
|
|
10
|
-
|
11
|
+
<!-- generated by git-cliff end -->
|
11
12
|
|
12
|
-
[
|
13
|
+
## [0.1.5] - 2025-04-10
|
13
14
|
|
14
|
-
|
15
|
+
### 📝 Docs
|
16
|
+
|
17
|
+
- Improve README structure and update content by @dieter-medium
|
18
|
+
- Add step-by-step usage guide to README by @dieter-medium
|
19
|
+
|
20
|
+
### 🚀 Added
|
21
|
+
|
22
|
+
- Add support for rendering local HTML files or in memory HTML by @dieter-medium
|
23
|
+
- Add DSL and specs for generating PDFs with browser tabs by @dieter-medium
|
24
|
+
- Enhance print method with block support for PDF handling by @dieter-medium
|
25
|
+
|
26
|
+
## [0.1.4] - 2025-04-10
|
27
|
+
|
28
|
+
### 🎨 Refactored
|
29
|
+
|
30
|
+
- Modularize browser commands and remove redundancy by @dieter-medium
|
31
|
+
- Implement interceptor validation and unit tests by @dieter-medium
|
32
|
+
- Connection handling in ConnectionManager by @dieter-medium
|
33
|
+
- Interceptors to enforce common interface methods by @dieter-medium
|
34
|
+
- Interceptors to simplify client responsibilities by @dieter-medium
|
35
|
+
- Enhance error handling and modularize interceptors by @dieter-medium
|
36
|
+
|
37
|
+
### 🐛 Fixed
|
38
|
+
|
39
|
+
- Resolve race condition between event subscription and emission by @dieter-medium
|
40
|
+
- Close custom session on stop function by @dieter-medium
|
41
|
+
- Add custom error classes for session management and improve error handling and testability by @dieter-medium
|
42
|
+
- Add Chromedriver container support and helper methods for RSpec integration by @dieter-medium
|
43
|
+
|
44
|
+
### 🔄 Changed
|
45
|
+
|
46
|
+
- Enhance command manager with response handling by @dieter-medium
|
47
|
+
|
48
|
+
### 🚀 Added
|
49
|
+
|
50
|
+
- Add randomization to user data directory path by @dieter-medium
|
51
|
+
- Introduce command abstraction for improved modularity by @dieter-medium
|
15
52
|
|
16
53
|
## [0.1.3] - 2025-04-06
|
17
54
|
|
data/README.md
CHANGED
@@ -3,52 +3,58 @@
|
|
3
3
|
[](https://badge.fury.io/rb/bidi2pdf)
|
4
4
|
[](https://codeclimate.com/github/dieter-medium/bidi2pdf/test_coverage)
|
5
5
|
|
6
|
-
|
6
|
+
---
|
7
7
|
|
8
|
-
|
9
|
-
offers precise control over PDF generation with support for modern web technologies.
|
8
|
+
# 📄 Bidi2pdf – Bulletproof PDF generation via Chrome's BiDi Protocol
|
10
9
|
|
11
|
-
|
10
|
+
**Bidi2pdf** is a powerful Ruby gem that transforms modern web pages into high-fidelity PDFs using Chrome’s *
|
11
|
+
*BiDirectional (BiDi)** protocol. Whether you're automating reports, archiving websites, or shipping documentation,
|
12
|
+
Bidi2pdf gives you **precision, flexibility, and full control**.
|
12
13
|
|
13
|
-
|
14
|
-
- **Rich Configuration** - Customize with cookies, headers, and authentication
|
15
|
-
- **Waiting Conditions** - Wait for window loaded or network idle
|
16
|
-
- **Headless Support** - Run without a visible browser
|
17
|
-
- **Docker Ready** - Easy containerization
|
18
|
-
- **Modern Architecture** - Uses Chrome's BiDi protocol for better control
|
14
|
+
---
|
19
15
|
|
20
|
-
##
|
16
|
+
## ✨ Key Features
|
21
17
|
|
22
|
-
|
18
|
+
✅ **One-liner CLI** – From URL to PDF in a single command
|
19
|
+
✅ **Full customization** – Inject cookies, headers, auth credentials
|
20
|
+
✅ **Smart waiting** – Wait for complete page load or network idle
|
21
|
+
✅ **Headless support** – Run quietly in the background
|
22
|
+
✅ **Docker-ready** – Plug and play with containers
|
23
|
+
✅ **Modern architecture** – Built on Chrome's next-gen BiDi protocol
|
24
|
+
|
25
|
+
---
|
26
|
+
|
27
|
+
## 🚀 Installation
|
28
|
+
|
29
|
+
### Bundler
|
23
30
|
|
24
31
|
```ruby
|
25
32
|
gem 'bidi2pdf'
|
26
33
|
```
|
27
34
|
|
28
|
-
|
35
|
+
### Standalone
|
29
36
|
|
30
37
|
```bash
|
31
|
-
|
38
|
+
gem install bidi2pdf
|
32
39
|
```
|
33
40
|
|
34
|
-
###
|
41
|
+
### Requirements
|
35
42
|
|
36
|
-
- **Ruby
|
37
|
-
- **
|
38
|
-
|
39
|
-
Downloads and installs the ChromeDriver version matching your installed Chrome/Chromium browser
|
40
|
-
Eliminates the need to manually install or update ChromeDriver
|
41
|
-
Ensures compatibility between Chrome and ChromeDriver versions
|
43
|
+
- **Ruby** ≥ 3.3
|
44
|
+
- **Chrome/Chromium**
|
45
|
+
- Automatic ChromeDriver management via [chromedriver-binary](https://github.com/dieter-medium/chromedriver-binary)
|
42
46
|
|
43
|
-
|
47
|
+
---
|
44
48
|
|
45
|
-
|
49
|
+
## ⚙️ Basic Usage
|
50
|
+
|
51
|
+
### Command-line
|
46
52
|
|
47
53
|
```bash
|
48
54
|
bidi2pdf render --url https://example.com --output example.pdf
|
49
55
|
```
|
50
56
|
|
51
|
-
### Advanced Options
|
57
|
+
### Advanced CLI Options
|
52
58
|
|
53
59
|
```bash
|
54
60
|
bidi2pdf render \
|
@@ -62,14 +68,18 @@ bidi2pdf render \
|
|
62
68
|
--log-level debug
|
63
69
|
```
|
64
70
|
|
65
|
-
|
71
|
+
---
|
72
|
+
|
73
|
+
## 🧠 Programmatic API
|
74
|
+
|
75
|
+
### Classic Approach
|
66
76
|
|
67
77
|
```ruby
|
68
78
|
require 'bidi2pdf'
|
69
79
|
|
70
80
|
launcher = Bidi2pdf::Launcher.new(
|
71
81
|
url: 'https://example.com',
|
72
|
-
output: 'example.pdf',
|
82
|
+
output: 'example.pdf',
|
73
83
|
cookies: { 'session' => 'abc123' },
|
74
84
|
headers: { 'X-API-KEY' => 'token' },
|
75
85
|
auth: { username: 'admin', password: 'password' },
|
@@ -78,25 +88,90 @@ launcher = Bidi2pdf::Launcher.new(
|
|
78
88
|
)
|
79
89
|
|
80
90
|
launcher.launch
|
91
|
+
```
|
92
|
+
|
93
|
+
### DSL – Quick & Clean
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
require "bidi2pdf"
|
97
|
+
|
98
|
+
Bidi2pdf::DSL.with_tab(headless: true) do |tab|
|
99
|
+
tab.open_page("https://example.com")
|
100
|
+
tab.wait_until_all_finished
|
101
|
+
tab.print("example.pdf")
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
---
|
106
|
+
|
107
|
+
## 🧬 Deep Integration Example
|
108
|
+
|
109
|
+
Get fine-grained control using Chrome sessions, tabs, and BiDi commands:
|
110
|
+
|
111
|
+
<details>
|
112
|
+
<summary>🔍 Show full example</summary>
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
require "bidi2pdf"
|
116
|
+
|
117
|
+
# 1. Remote or local session?
|
118
|
+
session = Bidi2pdf::Bidi::Session.new(
|
119
|
+
session_url: "http://localhost:9092/session",
|
120
|
+
headless: true,
|
121
|
+
)
|
122
|
+
|
123
|
+
# Alternative: local session via ChromeDriver
|
124
|
+
# manager = Bidi2pdf::ChromedriverManager.new(headless: false)
|
125
|
+
# manager.start
|
126
|
+
# session = manager.session
|
127
|
+
|
128
|
+
session.start
|
129
|
+
session.client.on_close { puts "WebSocket session closed" }
|
130
|
+
|
131
|
+
# 2. Create browser/tab
|
132
|
+
browser = session.browser
|
133
|
+
context = browser.create_user_context
|
134
|
+
window = context.create_browser_window
|
135
|
+
tab = window.create_browser_tab
|
136
|
+
|
137
|
+
# 3. Inject configuration
|
138
|
+
tab.set_cookie(name: "auth", value: "secret", domain: "example.com", secure: true)
|
139
|
+
tab.add_headers(url_patterns: [{ type: "pattern", protocol: "https", hostname: "example.com", port: "443" }],
|
140
|
+
headers: [{ name: "X-API-KEY", value: "12345678" }])
|
141
|
+
tab.basic_auth(url_patterns: [{ type: "pattern", protocol: "https", hostname: "example.com", port: "443" }],
|
142
|
+
username: "username", password: "secret")
|
81
143
|
|
82
|
-
#
|
144
|
+
# 4. Render PDF
|
145
|
+
tab.open_page "https://example.com"
|
146
|
+
|
147
|
+
# Alternative: send html code to the browser
|
148
|
+
# tab.view_html_page("<html>...</html>")
|
149
|
+
|
150
|
+
tab.wait_until_all_finished
|
151
|
+
tab.print("my.pdf")
|
152
|
+
|
153
|
+
# 5. Cleanup
|
154
|
+
tab.close
|
155
|
+
window.close
|
156
|
+
session.close
|
83
157
|
```
|
84
158
|
|
85
|
-
|
159
|
+
</details>
|
160
|
+
|
161
|
+
---
|
162
|
+
|
163
|
+
## 🐳 Docker Support
|
86
164
|
|
87
|
-
Build
|
165
|
+
### Build & Run
|
88
166
|
|
89
167
|
```bash
|
90
|
-
# Build gem and Docker image
|
91
168
|
rake build
|
92
169
|
docker build -t bidi2pdf -f docker/Dockerfile .
|
93
|
-
|
94
|
-
# Generate PDF using Docker
|
95
170
|
docker run -it --rm -v ./output:/reports bidi2pdf \
|
96
171
|
bidi2pdf render --url=https://example.com --output /reports/example.pdf
|
97
172
|
```
|
98
173
|
|
99
|
-
###
|
174
|
+
### Docker Compose
|
100
175
|
|
101
176
|
```bash
|
102
177
|
rake build
|
@@ -105,6 +180,10 @@ docker compose -f docker/docker-compose.yml up -d
|
|
105
180
|
# simple example
|
106
181
|
docker compose -f docker/docker-compose.yml exec app bidi2pdf render --url=http://nginx/sample.html --wait_window_loaded --wait_network_idle --output /reports/simple.pdf
|
107
182
|
|
183
|
+
# with a local file
|
184
|
+
docker compose -f docker/docker-compose.yml exec app bidi2pdf render --url=file:///reports/sample.html--wait_network_idle --output /reports/simple.pdf
|
185
|
+
|
186
|
+
|
108
187
|
# basic auth example
|
109
188
|
docker compose -f docker/docker-compose.yml exec app bidi2pdf render --url=http://nginx/basic/sample.html --auth admin:secret --wait_window_loaded --wait_network_idle --output /reports/basic.pdf
|
110
189
|
|
@@ -120,31 +199,42 @@ docker compose -f docker/docker-compose.yml exec app bidi2pdf render --url=http:
|
|
120
199
|
docker compose -f docker/docker-compose.yml down
|
121
200
|
```
|
122
201
|
|
123
|
-
|
202
|
+
---
|
203
|
+
|
204
|
+
## 🧩 Configuration Options
|
205
|
+
|
206
|
+
| Flag | Description |
|
207
|
+
|------------------------|--------------------------------------------|
|
208
|
+
| `--url` | Target URL (required) |
|
209
|
+
| `--output` | Output PDF file (default: output.pdf) |
|
210
|
+
| `--cookie` | Set cookie in `name=value` format |
|
211
|
+
| `--header` | Inject custom header `name=value` |
|
212
|
+
| `--auth` | Basic auth as `user:pass` |
|
213
|
+
| `--headless` | Run Chrome headless (default: true) |
|
214
|
+
| `--port` | ChromeDriver port (0 = auto) |
|
215
|
+
| `--wait_window_loaded` | Wait until `window.loaded` is set to true |
|
216
|
+
| `--wait_network_idle` | Wait until network is idle |
|
217
|
+
| `--log_level` | Log level: debug, info, warn, error, fatal |
|
218
|
+
| `--remote_browser_url` | Connect to remote Chrome session |
|
219
|
+
| `--default_timeout` | Operation timeout (default: 60s) |
|
124
220
|
|
125
|
-
|
126
|
-
|------------------------|---------------------------------------------------------------------------------------------------------------------|
|
127
|
-
| `--url` | The URL to render (required) |
|
128
|
-
| `--output` | Output PDF filename (default: output.pdf) |
|
129
|
-
| `--cookie` | Cookies in name=value format |
|
130
|
-
| `--header` | HTTP headers in name=value format |
|
131
|
-
| `--auth` | Basic auth credentials (user:pass) |
|
132
|
-
| `--headless` | Run Chrome in headless mode (default: true) |
|
133
|
-
| `--port` | Port for ChromeDriver (0 = auto) |
|
134
|
-
| `--wait_window_loaded` | Wait for the window to be fully loaded. You need to set a variable `window.loaded`. See ./spec/fixtures/sample.html |
|
135
|
-
| `--wait_network_idle` | Wait for network to be idle |
|
136
|
-
| `--log_level` | Log level (debug, info, warn, error, fatal) |
|
137
|
-
| `--remote_browser_url` | URL of the remote Chrome instance (default: nil) |
|
138
|
-
| `--default_timeout` | Default timeout for operations (default: 60 seconds) |
|
221
|
+
---
|
139
222
|
|
140
|
-
## Development
|
223
|
+
## 🛠 Development
|
141
224
|
|
142
|
-
|
225
|
+
```bash
|
226
|
+
# Setup
|
227
|
+
bin/setup
|
228
|
+
|
229
|
+
# Run tests
|
230
|
+
rake spec
|
231
|
+
|
232
|
+
# Open interactive console
|
233
|
+
bin/console
|
234
|
+
```
|
143
235
|
|
144
|
-
|
145
|
-
2. Run `rake spec` to run the tests
|
146
|
-
3. Run `bin/console` for an interactive prompt
|
236
|
+
---
|
147
237
|
|
148
|
-
## License
|
238
|
+
## 📜 License
|
149
239
|
|
150
|
-
|
240
|
+
This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -1,5 +1,7 @@
|
|
1
1
|
FROM ruby:3.3
|
2
2
|
|
3
|
+
ARG CHROMEDRIVER_PORT=3000
|
4
|
+
|
3
5
|
# Install dependencies
|
4
6
|
RUN apt-get update && \
|
5
7
|
apt-get install -y \
|
@@ -30,4 +32,7 @@ USER appuser
|
|
30
32
|
|
31
33
|
RUN gem install chromedriver-binary && ruby -e 'require "chromedriver/binary"; puts Chromedriver::Binary::ChromedriverDownloader.update'
|
32
34
|
|
35
|
+
ENV CHROMEDRIVER_PORT=${CHROMEDRIVER_PORT}
|
36
|
+
EXPOSE ${CHROMEDRIVER_PORT}
|
37
|
+
|
33
38
|
CMD ["/usr/local/bin/entrypoint.sh"]
|
data/docker/entrypoint.sh
CHANGED
@@ -1,3 +1,13 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
|
3
|
-
|
3
|
+
USER_DATA_DIR=/home/appuser/.cache
|
4
|
+
mkdir -p ${USER_DATA_DIR}
|
5
|
+
|
6
|
+
/home/appuser/.webdrivers/chromedriver --port=${CHROMEDRIVER_PORT} \
|
7
|
+
--headless \
|
8
|
+
--whitelisted-ips="" \
|
9
|
+
--allowed-origins="*" \
|
10
|
+
--disable-dev-shm-usage \
|
11
|
+
--disable-gpu \
|
12
|
+
--user-data-dir=${USER_DATA_DIR} \
|
13
|
+
--verbose
|
@@ -1,13 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "interceptor"
|
4
|
+
|
3
5
|
module Bidi2pdf
|
4
6
|
module Bidi
|
5
7
|
class AddHeadersInterceptor
|
6
|
-
|
8
|
+
include Interceptor
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def phases = [Bidi2pdf::Bidi::Commands::AddIntercept::BEFORE_REQUEST]
|
12
|
+
|
13
|
+
def events = ["network.beforeRequestSent"]
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :headers, :url_patterns, :context
|
7
17
|
|
8
|
-
def initialize(
|
9
|
-
@id = id
|
10
|
-
@client = client
|
18
|
+
def initialize(headers:, url_patterns:, context:)
|
11
19
|
@headers = headers.map do |header|
|
12
20
|
{
|
13
21
|
name: header[:name],
|
@@ -17,26 +25,15 @@ module Bidi2pdf
|
|
17
25
|
}
|
18
26
|
}
|
19
27
|
end
|
20
|
-
end
|
21
28
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
return unless event_response["intercepts"]&.include?(id) && event_response["isBlocked"]
|
26
|
-
|
27
|
-
network_id = event_response["request"]["request"]
|
28
|
-
|
29
|
-
Bidi2pdf.logger.debug "Interceptor #{id} handle event: #{network_id}"
|
30
|
-
|
31
|
-
client.send_cmd "network.continueRequest", {
|
32
|
-
request: network_id,
|
33
|
-
headers: headers
|
34
|
-
}
|
29
|
+
@url_patterns = url_patterns
|
30
|
+
@context = context
|
35
31
|
end
|
36
32
|
|
37
|
-
|
38
|
-
|
39
|
-
|
33
|
+
def process_interception(_event_response, _navigation_id, network_id, _url)
|
34
|
+
cmd = Bidi2pdf::Bidi::Commands::NetworkContinue.new request: network_id, headers: headers
|
35
|
+
client.send_cmd cmd
|
36
|
+
end
|
40
37
|
end
|
41
38
|
end
|
42
39
|
end
|
@@ -1,67 +1,60 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "interceptor"
|
4
|
+
|
3
5
|
module Bidi2pdf
|
4
6
|
module Bidi
|
5
7
|
class AuthInterceptor
|
6
|
-
|
8
|
+
include Interceptor
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def phases = [Bidi2pdf::Bidi::Commands::AddIntercept::AUTH_REQUIRED]
|
12
|
+
|
13
|
+
def events = ["network.authRequired"]
|
14
|
+
end
|
7
15
|
|
8
|
-
|
9
|
-
|
10
|
-
|
16
|
+
attr_reader :headers, :url_patterns, :context, :username, :password, :network_ids
|
17
|
+
|
18
|
+
def initialize(username:, password:, url_patterns:, context:)
|
19
|
+
@url_patterns = url_patterns
|
20
|
+
@context = context
|
11
21
|
@username = username
|
12
22
|
@password = password
|
13
23
|
@network_ids = []
|
14
24
|
end
|
15
25
|
|
16
|
-
|
17
|
-
|
18
|
-
event_response = response["params"]
|
19
|
-
|
20
|
-
return unless event_response["intercepts"]&.include?(id) && event_response["isBlocked"]
|
21
|
-
|
22
|
-
navigation_id = event_response["navigation"]
|
23
|
-
network_id = event_response["request"]["request"]
|
24
|
-
url = event_response["request"]["url"]
|
25
|
-
|
26
|
-
handle_bad_credentials(navigation_id, network_id, url)
|
26
|
+
def process_interception(_event_response, navigation_id, network_id, url)
|
27
|
+
return if handled_bad_credentials(navigation_id, network_id, url)
|
27
28
|
|
28
29
|
network_ids << network_id
|
29
30
|
|
30
|
-
Bidi2pdf.
|
31
|
-
|
32
|
-
client.send_cmd("network.continueWithAuth", {
|
33
|
-
request: network_id,
|
34
|
-
action: "provideCredentials",
|
35
|
-
credentials: {
|
36
|
-
type: "password",
|
37
|
-
username: username,
|
38
|
-
password: password
|
39
|
-
}
|
40
|
-
})
|
41
|
-
end
|
31
|
+
cmd = Bidi2pdf::Bidi::Commands::ProvideCredentials.new request: network_id, username: username, password: password
|
42
32
|
|
43
|
-
|
33
|
+
client.send_cmd(cmd)
|
34
|
+
rescue StandardError => e
|
35
|
+
Bidi2pdf.logger.error "Error handling auth event: #{e.message}"
|
36
|
+
Bidi2pdf.logger.error e.backtrace.join("\n")
|
37
|
+
raise e
|
38
|
+
end
|
44
39
|
|
45
40
|
private
|
46
41
|
|
47
|
-
def
|
48
|
-
return unless network_ids.include?(network_id)
|
42
|
+
def handled_bad_credentials(navigation_id, network_id, url)
|
43
|
+
return false unless network_ids.include?(network_id)
|
49
44
|
|
50
45
|
network_ids.delete(network_id)
|
51
46
|
|
52
|
-
Bidi2pdf.logger.debug "Auth-Interceptor #{
|
47
|
+
Bidi2pdf.logger.debug "Auth-Interceptor #{interceptor_id} already handled event: #{navigation_id}/#{network_id}/#{url}"
|
53
48
|
|
54
|
-
# rubocop: disable Layout/LineLength
|
55
49
|
Bidi2pdf.logger.error "It seems that the same request is being intercepted multiple times. Check your credentials or the URL you are trying to access. If you are using a proxy, make sure it is configured correctly."
|
56
50
|
# rubocop: enable Layout/LineLength
|
57
51
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
})
|
62
|
-
end
|
52
|
+
cmd = Bidi2pdf::Bidi::Commands::CancelAuth.new request: network_id
|
53
|
+
|
54
|
+
client.send_cmd(cmd)
|
63
55
|
|
64
|
-
|
56
|
+
true
|
57
|
+
end
|
65
58
|
end
|
66
59
|
end
|
67
60
|
end
|