crawlberg 1.11.1-aarch64-linux → 1.12.2-aarch64-linux
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/ext/crawlberg_rb/native/Cargo.lock +104 -182
- data/ext/crawlberg_rb/native/Cargo.toml +3 -3
- data/ext/crawlberg_rb/src/lib.rs +475 -58
- data/lib/crawlberg/native.rb +5 -1
- data/lib/crawlberg/version.rb +2 -2
- data/lib/crawlberg_rb/3.3.0/crawlberg_rb.so +2 -2
- data/sig/types.rbs +23 -5
- metadata +2 -8
data/ext/crawlberg_rb/src/lib.rs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// This file is auto-generated by alef. DO NOT EDIT.
|
|
2
|
-
// alef:hash:
|
|
2
|
+
// alef:hash:5766b3fb05a187f88eec0ae0ee3c5e32d6bede7f1a3bc38b4305587073983bbd
|
|
3
3
|
// Re-generate with: alef generate
|
|
4
4
|
#![allow(dead_code, unused_imports, unused_variables)]
|
|
5
5
|
#![allow(
|
|
@@ -843,6 +843,9 @@ pub struct BrowserConfig {
|
|
|
843
843
|
session_affinity: bool,
|
|
844
844
|
chrome_path: Option<String>,
|
|
845
845
|
chrome_args: Vec<String>,
|
|
846
|
+
scroll_containers: bool,
|
|
847
|
+
dom_quiet_window: u64,
|
|
848
|
+
dom_quiet_cap: u64,
|
|
846
849
|
}
|
|
847
850
|
|
|
848
851
|
unsafe impl IntoValueFromNative for BrowserConfig {}
|
|
@@ -892,6 +895,9 @@ impl std::fmt::Debug for BrowserConfig {
|
|
|
892
895
|
debug.field("session_affinity", &self.session_affinity);
|
|
893
896
|
debug.field("chrome_path", &self.chrome_path);
|
|
894
897
|
debug.field("chrome_args", &"<redacted>");
|
|
898
|
+
debug.field("scroll_containers", &self.scroll_containers);
|
|
899
|
+
debug.field("dom_quiet_window", &self.dom_quiet_window);
|
|
900
|
+
debug.field("dom_quiet_cap", &self.dom_quiet_cap);
|
|
895
901
|
debug.finish()
|
|
896
902
|
}
|
|
897
903
|
}
|
|
@@ -1070,6 +1076,33 @@ impl BrowserConfig {
|
|
|
1070
1076
|
})?,
|
|
1071
1077
|
None => Default::default(),
|
|
1072
1078
|
},
|
|
1079
|
+
scroll_containers: match kwargs.get(ruby.to_symbol("scroll_containers")) {
|
|
1080
|
+
Some(v) => bool::try_convert(v).map_err(|e| {
|
|
1081
|
+
magnus::Error::new(
|
|
1082
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
1083
|
+
format!("invalid value for `scroll_containers`: {}", e),
|
|
1084
|
+
)
|
|
1085
|
+
})?,
|
|
1086
|
+
None => false,
|
|
1087
|
+
},
|
|
1088
|
+
dom_quiet_window: match kwargs.get(ruby.to_symbol("dom_quiet_window")) {
|
|
1089
|
+
Some(v) => u64::try_convert(v).map_err(|e| {
|
|
1090
|
+
magnus::Error::new(
|
|
1091
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
1092
|
+
format!("invalid value for `dom_quiet_window`: {}", e),
|
|
1093
|
+
)
|
|
1094
|
+
})?,
|
|
1095
|
+
None => 150,
|
|
1096
|
+
},
|
|
1097
|
+
dom_quiet_cap: match kwargs.get(ruby.to_symbol("dom_quiet_cap")) {
|
|
1098
|
+
Some(v) => u64::try_convert(v).map_err(|e| {
|
|
1099
|
+
magnus::Error::new(
|
|
1100
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
1101
|
+
format!("invalid value for `dom_quiet_cap`: {}", e),
|
|
1102
|
+
)
|
|
1103
|
+
})?,
|
|
1104
|
+
None => 4000,
|
|
1105
|
+
},
|
|
1073
1106
|
})
|
|
1074
1107
|
}
|
|
1075
1108
|
|
|
@@ -1140,6 +1173,18 @@ impl BrowserConfig {
|
|
|
1140
1173
|
fn chrome_args(&self) -> Vec<String> {
|
|
1141
1174
|
self.chrome_args.clone()
|
|
1142
1175
|
}
|
|
1176
|
+
|
|
1177
|
+
fn scroll_containers(&self) -> bool {
|
|
1178
|
+
self.scroll_containers
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
fn dom_quiet_window(&self) -> u64 {
|
|
1182
|
+
self.dom_quiet_window.clone()
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
fn dom_quiet_cap(&self) -> u64 {
|
|
1186
|
+
self.dom_quiet_cap.clone()
|
|
1187
|
+
}
|
|
1143
1188
|
}
|
|
1144
1189
|
|
|
1145
1190
|
#[derive(Clone, Debug, serde::Serialize)]
|
|
@@ -1444,6 +1489,10 @@ pub struct ContentConfig {
|
|
|
1444
1489
|
compact_tables: bool,
|
|
1445
1490
|
keep_inline_images_in: Vec<String>,
|
|
1446
1491
|
keep_hidden: bool,
|
|
1492
|
+
expand_abbreviations: bool,
|
|
1493
|
+
escape_misc: bool,
|
|
1494
|
+
escape_asterisks: bool,
|
|
1495
|
+
include_icon_labels: bool,
|
|
1447
1496
|
}
|
|
1448
1497
|
|
|
1449
1498
|
unsafe impl IntoValueFromNative for ContentConfig {}
|
|
@@ -1675,6 +1724,42 @@ impl ContentConfig {
|
|
|
1675
1724
|
})?,
|
|
1676
1725
|
None => false,
|
|
1677
1726
|
},
|
|
1727
|
+
expand_abbreviations: match kwargs.get(ruby.to_symbol("expand_abbreviations")) {
|
|
1728
|
+
Some(v) => bool::try_convert(v).map_err(|e| {
|
|
1729
|
+
magnus::Error::new(
|
|
1730
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
1731
|
+
format!("invalid value for `expand_abbreviations`: {}", e),
|
|
1732
|
+
)
|
|
1733
|
+
})?,
|
|
1734
|
+
None => true,
|
|
1735
|
+
},
|
|
1736
|
+
escape_misc: match kwargs.get(ruby.to_symbol("escape_misc")) {
|
|
1737
|
+
Some(v) => bool::try_convert(v).map_err(|e| {
|
|
1738
|
+
magnus::Error::new(
|
|
1739
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
1740
|
+
format!("invalid value for `escape_misc`: {}", e),
|
|
1741
|
+
)
|
|
1742
|
+
})?,
|
|
1743
|
+
None => false,
|
|
1744
|
+
},
|
|
1745
|
+
escape_asterisks: match kwargs.get(ruby.to_symbol("escape_asterisks")) {
|
|
1746
|
+
Some(v) => bool::try_convert(v).map_err(|e| {
|
|
1747
|
+
magnus::Error::new(
|
|
1748
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
1749
|
+
format!("invalid value for `escape_asterisks`: {}", e),
|
|
1750
|
+
)
|
|
1751
|
+
})?,
|
|
1752
|
+
None => false,
|
|
1753
|
+
},
|
|
1754
|
+
include_icon_labels: match kwargs.get(ruby.to_symbol("include_icon_labels")) {
|
|
1755
|
+
Some(v) => bool::try_convert(v).map_err(|e| {
|
|
1756
|
+
magnus::Error::new(
|
|
1757
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
1758
|
+
format!("invalid value for `include_icon_labels`: {}", e),
|
|
1759
|
+
)
|
|
1760
|
+
})?,
|
|
1761
|
+
None => true,
|
|
1762
|
+
},
|
|
1678
1763
|
})
|
|
1679
1764
|
}
|
|
1680
1765
|
|
|
@@ -1757,6 +1842,22 @@ impl ContentConfig {
|
|
|
1757
1842
|
fn keep_hidden(&self) -> bool {
|
|
1758
1843
|
self.keep_hidden
|
|
1759
1844
|
}
|
|
1845
|
+
|
|
1846
|
+
fn expand_abbreviations(&self) -> bool {
|
|
1847
|
+
self.expand_abbreviations
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
fn escape_misc(&self) -> bool {
|
|
1851
|
+
self.escape_misc
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
fn escape_asterisks(&self) -> bool {
|
|
1855
|
+
self.escape_asterisks
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
fn include_icon_labels(&self) -> bool {
|
|
1859
|
+
self.include_icon_labels
|
|
1860
|
+
}
|
|
1760
1861
|
}
|
|
1761
1862
|
|
|
1762
1863
|
#[derive(Clone, serde::Serialize, serde::Deserialize)]
|
|
@@ -1936,6 +2037,8 @@ pub struct CrawlConfig {
|
|
|
1936
2037
|
save_browser_profile: bool,
|
|
1937
2038
|
ssrf: SsrfPolicy,
|
|
1938
2039
|
ssrf_deny_private_explicit: Option<bool>,
|
|
2040
|
+
danger_accept_invalid_certs: bool,
|
|
2041
|
+
subdomain_header_allowlist: Vec<String>,
|
|
1939
2042
|
}
|
|
1940
2043
|
|
|
1941
2044
|
unsafe impl IntoValueFromNative for CrawlConfig {}
|
|
@@ -2023,6 +2126,8 @@ impl std::fmt::Debug for CrawlConfig {
|
|
|
2023
2126
|
debug.field("save_browser_profile", &self.save_browser_profile);
|
|
2024
2127
|
debug.field("ssrf", &self.ssrf);
|
|
2025
2128
|
debug.field("ssrf_deny_private_explicit", &self.ssrf_deny_private_explicit);
|
|
2129
|
+
debug.field("danger_accept_invalid_certs", &self.danger_accept_invalid_certs);
|
|
2130
|
+
debug.field("subdomain_header_allowlist", &self.subdomain_header_allowlist);
|
|
2026
2131
|
debug.finish()
|
|
2027
2132
|
}
|
|
2028
2133
|
}
|
|
@@ -2549,6 +2654,24 @@ impl CrawlConfig {
|
|
|
2549
2654
|
})?),
|
|
2550
2655
|
None => None,
|
|
2551
2656
|
},
|
|
2657
|
+
danger_accept_invalid_certs: match kwargs.get(ruby.to_symbol("danger_accept_invalid_certs")) {
|
|
2658
|
+
Some(v) => bool::try_convert(v).map_err(|e| {
|
|
2659
|
+
magnus::Error::new(
|
|
2660
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
2661
|
+
format!("invalid value for `danger_accept_invalid_certs`: {}", e),
|
|
2662
|
+
)
|
|
2663
|
+
})?,
|
|
2664
|
+
None => false,
|
|
2665
|
+
},
|
|
2666
|
+
subdomain_header_allowlist: match kwargs.get(ruby.to_symbol("subdomain_header_allowlist")) {
|
|
2667
|
+
Some(v) => <Vec<String>>::try_convert(v).map_err(|e| {
|
|
2668
|
+
magnus::Error::new(
|
|
2669
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
2670
|
+
format!("invalid value for `subdomain_header_allowlist`: {}", e),
|
|
2671
|
+
)
|
|
2672
|
+
})?,
|
|
2673
|
+
None => Default::default(),
|
|
2674
|
+
},
|
|
2552
2675
|
})
|
|
2553
2676
|
}
|
|
2554
2677
|
|
|
@@ -2772,6 +2895,14 @@ impl CrawlConfig {
|
|
|
2772
2895
|
self.ssrf_deny_private_explicit
|
|
2773
2896
|
}
|
|
2774
2897
|
|
|
2898
|
+
fn danger_accept_invalid_certs(&self) -> bool {
|
|
2899
|
+
self.danger_accept_invalid_certs
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
fn subdomain_header_allowlist(&self) -> Vec<String> {
|
|
2903
|
+
self.subdomain_header_allowlist.clone()
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2775
2906
|
fn validate(&self) -> Result<(), Error> {
|
|
2776
2907
|
#[allow(clippy::needless_update)]
|
|
2777
2908
|
let core_self = crawlberg::CrawlConfig {
|
|
@@ -2890,14 +3021,13 @@ impl CrawlConfig {
|
|
|
2890
3021
|
|
|
2891
3022
|
ssrf_deny_private_explicit: self.ssrf_deny_private_explicit,
|
|
2892
3023
|
|
|
3024
|
+
danger_accept_invalid_certs: self.danger_accept_invalid_certs,
|
|
3025
|
+
|
|
3026
|
+
subdomain_header_allowlist: self.subdomain_header_allowlist.clone(),
|
|
3027
|
+
|
|
2893
3028
|
..Default::default()
|
|
2894
3029
|
};
|
|
2895
|
-
let result = core_self.validate().map_err(
|
|
2896
|
-
magnus::Error::new(
|
|
2897
|
-
unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
|
|
2898
|
-
e.to_string(),
|
|
2899
|
-
)
|
|
2900
|
-
})?;
|
|
3030
|
+
let result = core_self.validate().map_err(alef_magnus_err)?;
|
|
2901
3031
|
Ok(result)
|
|
2902
3032
|
}
|
|
2903
3033
|
}
|
|
@@ -2948,12 +3078,7 @@ impl CrawlEngineHandle {
|
|
|
2948
3078
|
);
|
|
2949
3079
|
let stream = runtime
|
|
2950
3080
|
.block_on(async { inner.crawl_stream(core_req).await })
|
|
2951
|
-
.map_err(
|
|
2952
|
-
magnus::Error::new(
|
|
2953
|
-
unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
|
|
2954
|
-
e.to_string(),
|
|
2955
|
-
)
|
|
2956
|
-
})?;
|
|
3081
|
+
.map_err(alef_magnus_err)?;
|
|
2957
3082
|
let iterator = CrawlStreamIterator {
|
|
2958
3083
|
inner: Arc::new(tokio::sync::Mutex::new(Some(stream))),
|
|
2959
3084
|
runtime,
|
|
@@ -2993,12 +3118,7 @@ impl CrawlEngineHandle {
|
|
|
2993
3118
|
);
|
|
2994
3119
|
let stream = runtime
|
|
2995
3120
|
.block_on(async { inner.batch_crawl_stream(core_req).await })
|
|
2996
|
-
.map_err(
|
|
2997
|
-
magnus::Error::new(
|
|
2998
|
-
unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
|
|
2999
|
-
e.to_string(),
|
|
3000
|
-
)
|
|
3001
|
-
})?;
|
|
3121
|
+
.map_err(alef_magnus_err)?;
|
|
3002
3122
|
let iterator = BatchCrawlStreamIterator {
|
|
3003
3123
|
inner: Arc::new(tokio::sync::Mutex::new(Some(stream))),
|
|
3004
3124
|
runtime,
|
|
@@ -3454,7 +3574,7 @@ impl CrawlPageResult {
|
|
|
3454
3574
|
}
|
|
3455
3575
|
}
|
|
3456
3576
|
|
|
3457
|
-
#[derive(Clone, Debug, serde::Serialize
|
|
3577
|
+
#[derive(Clone, Debug, serde::Serialize)]
|
|
3458
3578
|
#[serde(default)]
|
|
3459
3579
|
#[magnus::wrap(class = "Crawlberg::CrawlResult")]
|
|
3460
3580
|
pub struct CrawlResult {
|
|
@@ -3466,6 +3586,7 @@ pub struct CrawlResult {
|
|
|
3466
3586
|
cookies: Vec<CookieInfo>,
|
|
3467
3587
|
stayed_on_domain: bool,
|
|
3468
3588
|
browser_used: bool,
|
|
3589
|
+
waf_block: Option<WafBlockDetails>,
|
|
3469
3590
|
}
|
|
3470
3591
|
|
|
3471
3592
|
unsafe impl IntoValueFromNative for CrawlResult {}
|
|
@@ -3495,6 +3616,14 @@ impl magnus::TryConvert for CrawlResult {
|
|
|
3495
3616
|
}
|
|
3496
3617
|
|
|
3497
3618
|
unsafe impl TryConvertOwned for CrawlResult {}
|
|
3619
|
+
impl<'de> serde::Deserialize<'de> for CrawlResult {
|
|
3620
|
+
fn deserialize<D>(deserializer: D) -> ::core::result::Result<Self, D::Error>
|
|
3621
|
+
where
|
|
3622
|
+
D: serde::Deserializer<'de>,
|
|
3623
|
+
{
|
|
3624
|
+
<crawlberg::CrawlResult as serde::Deserialize>::deserialize(deserializer).map(Into::into)
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3498
3627
|
|
|
3499
3628
|
impl Default for CrawlResult {
|
|
3500
3629
|
fn default() -> Self {
|
|
@@ -3581,6 +3710,15 @@ impl CrawlResult {
|
|
|
3581
3710
|
})?,
|
|
3582
3711
|
None => Default::default(),
|
|
3583
3712
|
},
|
|
3713
|
+
waf_block: match kwargs.get(ruby.to_symbol("waf_block")).filter(|v| !v.is_nil()) {
|
|
3714
|
+
Some(v) => Some(WafBlockDetails::try_convert(v).map_err(|e| {
|
|
3715
|
+
magnus::Error::new(
|
|
3716
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
3717
|
+
format!("invalid value for `waf_block`: {}", e),
|
|
3718
|
+
)
|
|
3719
|
+
})?),
|
|
3720
|
+
None => None,
|
|
3721
|
+
},
|
|
3584
3722
|
})
|
|
3585
3723
|
}
|
|
3586
3724
|
|
|
@@ -3616,6 +3754,10 @@ impl CrawlResult {
|
|
|
3616
3754
|
self.browser_used
|
|
3617
3755
|
}
|
|
3618
3756
|
|
|
3757
|
+
fn waf_block(&self) -> Option<WafBlockDetails> {
|
|
3758
|
+
self.waf_block.clone()
|
|
3759
|
+
}
|
|
3760
|
+
|
|
3619
3761
|
fn unique_normalized_urls(&self) -> usize {
|
|
3620
3762
|
#[allow(clippy::needless_update)]
|
|
3621
3763
|
let core_self = crawlberg::CrawlResult {
|
|
@@ -3635,6 +3777,8 @@ impl CrawlResult {
|
|
|
3635
3777
|
|
|
3636
3778
|
browser_used: self.browser_used,
|
|
3637
3779
|
|
|
3780
|
+
waf_block: self.waf_block.clone().map(Into::into),
|
|
3781
|
+
|
|
3638
3782
|
..Default::default()
|
|
3639
3783
|
};
|
|
3640
3784
|
core_self.unique_normalized_urls()
|
|
@@ -6845,6 +6989,99 @@ impl SsrfPolicy {
|
|
|
6845
6989
|
}
|
|
6846
6990
|
}
|
|
6847
6991
|
|
|
6992
|
+
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
|
6993
|
+
#[serde(default)]
|
|
6994
|
+
#[magnus::wrap(class = "Crawlberg::WafBlockDetails")]
|
|
6995
|
+
pub struct WafBlockDetails {
|
|
6996
|
+
vendor: String,
|
|
6997
|
+
status: Option<u16>,
|
|
6998
|
+
body_prefix: Option<String>,
|
|
6999
|
+
}
|
|
7000
|
+
|
|
7001
|
+
unsafe impl IntoValueFromNative for WafBlockDetails {}
|
|
7002
|
+
|
|
7003
|
+
impl magnus::TryConvert for WafBlockDetails {
|
|
7004
|
+
fn try_convert(val: magnus::Value) -> Result<Self, magnus::Error> {
|
|
7005
|
+
if let Ok(r) = <&WafBlockDetails as magnus::TryConvert>::try_convert(val) {
|
|
7006
|
+
return Ok(r.clone());
|
|
7007
|
+
}
|
|
7008
|
+
let json_str: String = if let Ok(s) = <String as magnus::TryConvert>::try_convert(val) {
|
|
7009
|
+
s
|
|
7010
|
+
} else {
|
|
7011
|
+
val.funcall::<_, _, String>("to_json", ()).map_err(|e| {
|
|
7012
|
+
magnus::Error::new(
|
|
7013
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
7014
|
+
format!("no implicit conversion into WafBlockDetails: {}", e),
|
|
7015
|
+
)
|
|
7016
|
+
})?
|
|
7017
|
+
};
|
|
7018
|
+
serde_json::from_str::<WafBlockDetails>(&json_str).map_err(|e| {
|
|
7019
|
+
magnus::Error::new(
|
|
7020
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
7021
|
+
format!("failed to deserialize WafBlockDetails: {}", e),
|
|
7022
|
+
)
|
|
7023
|
+
})
|
|
7024
|
+
}
|
|
7025
|
+
}
|
|
7026
|
+
|
|
7027
|
+
unsafe impl TryConvertOwned for WafBlockDetails {}
|
|
7028
|
+
|
|
7029
|
+
impl Default for WafBlockDetails {
|
|
7030
|
+
fn default() -> Self {
|
|
7031
|
+
crawlberg::WafBlockDetails::default().into()
|
|
7032
|
+
}
|
|
7033
|
+
}
|
|
7034
|
+
|
|
7035
|
+
impl WafBlockDetails {
|
|
7036
|
+
fn new(args: &[magnus::Value]) -> Result<Self, magnus::Error> {
|
|
7037
|
+
let ruby = unsafe { magnus::Ruby::get_unchecked() };
|
|
7038
|
+
let args = magnus::scan_args::scan_args::<(), (Option<magnus::RHash>,), (), (), (), ()>(args)?;
|
|
7039
|
+
let (kwargs_opt,) = args.optional;
|
|
7040
|
+
let kwargs = kwargs_opt.unwrap_or_else(|| ruby.hash_new());
|
|
7041
|
+
Ok(Self {
|
|
7042
|
+
vendor: match kwargs.get(ruby.to_symbol("vendor")) {
|
|
7043
|
+
Some(v) => String::try_convert(v).map_err(|e| {
|
|
7044
|
+
magnus::Error::new(
|
|
7045
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
7046
|
+
format!("invalid value for `vendor`: {}", e),
|
|
7047
|
+
)
|
|
7048
|
+
})?,
|
|
7049
|
+
None => Default::default(),
|
|
7050
|
+
},
|
|
7051
|
+
status: match kwargs.get(ruby.to_symbol("status")).filter(|v| !v.is_nil()) {
|
|
7052
|
+
Some(v) => Some(u16::try_convert(v).map_err(|e| {
|
|
7053
|
+
magnus::Error::new(
|
|
7054
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
7055
|
+
format!("invalid value for `status`: {}", e),
|
|
7056
|
+
)
|
|
7057
|
+
})?),
|
|
7058
|
+
None => None,
|
|
7059
|
+
},
|
|
7060
|
+
body_prefix: match kwargs.get(ruby.to_symbol("body_prefix")).filter(|v| !v.is_nil()) {
|
|
7061
|
+
Some(v) => Some(String::try_convert(v).map_err(|e| {
|
|
7062
|
+
magnus::Error::new(
|
|
7063
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_type_error(),
|
|
7064
|
+
format!("invalid value for `body_prefix`: {}", e),
|
|
7065
|
+
)
|
|
7066
|
+
})?),
|
|
7067
|
+
None => None,
|
|
7068
|
+
},
|
|
7069
|
+
})
|
|
7070
|
+
}
|
|
7071
|
+
|
|
7072
|
+
fn vendor(&self) -> String {
|
|
7073
|
+
self.vendor.clone()
|
|
7074
|
+
}
|
|
7075
|
+
|
|
7076
|
+
fn status(&self) -> Option<u16> {
|
|
7077
|
+
self.status
|
|
7078
|
+
}
|
|
7079
|
+
|
|
7080
|
+
fn body_prefix(&self) -> Option<String> {
|
|
7081
|
+
self.body_prefix.clone()
|
|
7082
|
+
}
|
|
7083
|
+
}
|
|
7084
|
+
|
|
6848
7085
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, serde::Serialize, serde::Deserialize)]
|
|
6849
7086
|
#[serde(rename_all = "snake_case")]
|
|
6850
7087
|
pub enum AssetCategory {
|
|
@@ -7612,6 +7849,8 @@ pub enum PageAction {
|
|
|
7612
7849
|
selector: Option<String>,
|
|
7613
7850
|
},
|
|
7614
7851
|
Screenshot {
|
|
7852
|
+
#[serde(rename = "fullPage")]
|
|
7853
|
+
#[serde(alias = "full_page")]
|
|
7615
7854
|
full_page: Option<bool>,
|
|
7616
7855
|
},
|
|
7617
7856
|
#[serde(rename = "executeJs")]
|
|
@@ -7735,11 +7974,11 @@ fn batch_crawl(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<BatchCraw
|
|
|
7735
7974
|
.enable_all()
|
|
7736
7975
|
.build()
|
|
7737
7976
|
.map_err(|e| e.to_string())?;
|
|
7738
|
-
rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await })
|
|
7739
|
-
.map_err(|e| e.to_string())
|
|
7977
|
+
Ok(rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await }))
|
|
7740
7978
|
});
|
|
7741
7979
|
let result = async_result
|
|
7742
7980
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
7981
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7743
7982
|
Ok(result.into())
|
|
7744
7983
|
}
|
|
7745
7984
|
|
|
@@ -7749,11 +7988,11 @@ fn batch_crawl_async(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<Bat
|
|
|
7749
7988
|
.enable_all()
|
|
7750
7989
|
.build()
|
|
7751
7990
|
.map_err(|e| e.to_string())?;
|
|
7752
|
-
rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await })
|
|
7753
|
-
.map_err(|e| e.to_string())
|
|
7991
|
+
Ok(rt.block_on(async { crawlberg::batch_crawl(&engine.inner, urls).await }))
|
|
7754
7992
|
});
|
|
7755
7993
|
let result = async_result
|
|
7756
7994
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
7995
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7757
7996
|
Ok(result.into())
|
|
7758
7997
|
}
|
|
7759
7998
|
|
|
@@ -7763,11 +8002,11 @@ fn batch_scrape(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<BatchScr
|
|
|
7763
8002
|
.enable_all()
|
|
7764
8003
|
.build()
|
|
7765
8004
|
.map_err(|e| e.to_string())?;
|
|
7766
|
-
rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await })
|
|
7767
|
-
.map_err(|e| e.to_string())
|
|
8005
|
+
Ok(rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await }))
|
|
7768
8006
|
});
|
|
7769
8007
|
let result = async_result
|
|
7770
8008
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8009
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7771
8010
|
Ok(result.into())
|
|
7772
8011
|
}
|
|
7773
8012
|
|
|
@@ -7777,11 +8016,11 @@ fn batch_scrape_async(engine: CrawlEngineHandle, urls: Vec<String>) -> Result<Ba
|
|
|
7777
8016
|
.enable_all()
|
|
7778
8017
|
.build()
|
|
7779
8018
|
.map_err(|e| e.to_string())?;
|
|
7780
|
-
rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await })
|
|
7781
|
-
.map_err(|e| e.to_string())
|
|
8019
|
+
Ok(rt.block_on(async { crawlberg::batch_scrape(&engine.inner, urls).await }))
|
|
7782
8020
|
});
|
|
7783
8021
|
let result = async_result
|
|
7784
8022
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8023
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7785
8024
|
Ok(result.into())
|
|
7786
8025
|
}
|
|
7787
8026
|
|
|
@@ -7791,11 +8030,11 @@ fn crawl(engine: CrawlEngineHandle, url: String) -> Result<CrawlResult, Error> {
|
|
|
7791
8030
|
.enable_all()
|
|
7792
8031
|
.build()
|
|
7793
8032
|
.map_err(|e| e.to_string())?;
|
|
7794
|
-
rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await })
|
|
7795
|
-
.map_err(|e| e.to_string())
|
|
8033
|
+
Ok(rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await }))
|
|
7796
8034
|
});
|
|
7797
8035
|
let result = async_result
|
|
7798
8036
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8037
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7799
8038
|
Ok(result.into())
|
|
7800
8039
|
}
|
|
7801
8040
|
|
|
@@ -7805,11 +8044,11 @@ fn crawl_async(engine: CrawlEngineHandle, url: String) -> Result<CrawlResult, Er
|
|
|
7805
8044
|
.enable_all()
|
|
7806
8045
|
.build()
|
|
7807
8046
|
.map_err(|e| e.to_string())?;
|
|
7808
|
-
rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await })
|
|
7809
|
-
.map_err(|e| e.to_string())
|
|
8047
|
+
Ok(rt.block_on(async { crawlberg::crawl(&engine.inner, &url).await }))
|
|
7810
8048
|
});
|
|
7811
8049
|
let result = async_result
|
|
7812
8050
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8051
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7813
8052
|
Ok(result.into())
|
|
7814
8053
|
}
|
|
7815
8054
|
|
|
@@ -7826,12 +8065,7 @@ fn create_engine(args: &[magnus::Value]) -> Result<CrawlEngineHandle, Error> {
|
|
|
7826
8065
|
}
|
|
7827
8066
|
_ => None,
|
|
7828
8067
|
};
|
|
7829
|
-
let result = crawlberg::create_engine(config.map(Into::into)).map_err(
|
|
7830
|
-
magnus::Error::new(
|
|
7831
|
-
unsafe { Ruby::get_unchecked() }.exception_runtime_error(),
|
|
7832
|
-
e.to_string(),
|
|
7833
|
-
)
|
|
7834
|
-
})?;
|
|
8068
|
+
let result = crawlberg::create_engine(config.map(Into::into)).map_err(alef_magnus_err)?;
|
|
7835
8069
|
Ok(CrawlEngineHandle {
|
|
7836
8070
|
inner: Arc::new(result),
|
|
7837
8071
|
})
|
|
@@ -7848,11 +8082,11 @@ fn interact(engine: CrawlEngineHandle, url: String, actions: Vec<PageAction>) ->
|
|
|
7848
8082
|
.enable_all()
|
|
7849
8083
|
.build()
|
|
7850
8084
|
.map_err(|e| e.to_string())?;
|
|
7851
|
-
rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await })
|
|
7852
|
-
.map_err(|e| e.to_string())
|
|
8085
|
+
Ok(rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await }))
|
|
7853
8086
|
});
|
|
7854
8087
|
let result = async_result
|
|
7855
8088
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8089
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7856
8090
|
Ok(result.into())
|
|
7857
8091
|
}
|
|
7858
8092
|
|
|
@@ -7867,11 +8101,11 @@ fn interact_async(
|
|
|
7867
8101
|
.enable_all()
|
|
7868
8102
|
.build()
|
|
7869
8103
|
.map_err(|e| e.to_string())?;
|
|
7870
|
-
rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await })
|
|
7871
|
-
.map_err(|e| e.to_string())
|
|
8104
|
+
Ok(rt.block_on(async { crawlberg::interact(&engine.inner, &url, actions_core).await }))
|
|
7872
8105
|
});
|
|
7873
8106
|
let result = async_result
|
|
7874
8107
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8108
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7875
8109
|
Ok(result.into())
|
|
7876
8110
|
}
|
|
7877
8111
|
|
|
@@ -7881,11 +8115,11 @@ fn map_urls(engine: CrawlEngineHandle, url: String) -> Result<MapResult, Error>
|
|
|
7881
8115
|
.enable_all()
|
|
7882
8116
|
.build()
|
|
7883
8117
|
.map_err(|e| e.to_string())?;
|
|
7884
|
-
rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await })
|
|
7885
|
-
.map_err(|e| e.to_string())
|
|
8118
|
+
Ok(rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await }))
|
|
7886
8119
|
});
|
|
7887
8120
|
let result = async_result
|
|
7888
8121
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8122
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7889
8123
|
Ok(result.into())
|
|
7890
8124
|
}
|
|
7891
8125
|
|
|
@@ -7895,11 +8129,11 @@ fn map_urls_async(engine: CrawlEngineHandle, url: String) -> Result<MapResult, E
|
|
|
7895
8129
|
.enable_all()
|
|
7896
8130
|
.build()
|
|
7897
8131
|
.map_err(|e| e.to_string())?;
|
|
7898
|
-
rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await })
|
|
7899
|
-
.map_err(|e| e.to_string())
|
|
8132
|
+
Ok(rt.block_on(async { crawlberg::map_urls(&engine.inner, &url).await }))
|
|
7900
8133
|
});
|
|
7901
8134
|
let result = async_result
|
|
7902
8135
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8136
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7903
8137
|
Ok(result.into())
|
|
7904
8138
|
}
|
|
7905
8139
|
|
|
@@ -7909,11 +8143,11 @@ fn scrape(engine: CrawlEngineHandle, url: String) -> Result<ScrapeResult, Error>
|
|
|
7909
8143
|
.enable_all()
|
|
7910
8144
|
.build()
|
|
7911
8145
|
.map_err(|e| e.to_string())?;
|
|
7912
|
-
rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await })
|
|
7913
|
-
.map_err(|e| e.to_string())
|
|
8146
|
+
Ok(rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await }))
|
|
7914
8147
|
});
|
|
7915
8148
|
let result = async_result
|
|
7916
8149
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8150
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7917
8151
|
Ok(result.into())
|
|
7918
8152
|
}
|
|
7919
8153
|
|
|
@@ -7923,11 +8157,11 @@ fn scrape_async(engine: CrawlEngineHandle, url: String) -> Result<ScrapeResult,
|
|
|
7923
8157
|
.enable_all()
|
|
7924
8158
|
.build()
|
|
7925
8159
|
.map_err(|e| e.to_string())?;
|
|
7926
|
-
rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await })
|
|
7927
|
-
.map_err(|e| e.to_string())
|
|
8160
|
+
Ok(rt.block_on(async { crawlberg::scrape(&engine.inner, &url).await }))
|
|
7928
8161
|
});
|
|
7929
8162
|
let result = async_result
|
|
7930
8163
|
.map_err(|message| magnus::Error::new(unsafe { Ruby::get_unchecked() }.exception_runtime_error(), message))?;
|
|
8164
|
+
let result = result.map_err(alef_magnus_err)?;
|
|
7931
8165
|
Ok(result.into())
|
|
7932
8166
|
}
|
|
7933
8167
|
|
|
@@ -8136,6 +8370,9 @@ impl From<BrowserConfig> for crawlberg::BrowserConfig {
|
|
|
8136
8370
|
session_affinity: val.session_affinity,
|
|
8137
8371
|
chrome_path: val.chrome_path.map(Into::into),
|
|
8138
8372
|
chrome_args: val.chrome_args.into_iter().collect(),
|
|
8373
|
+
scroll_containers: val.scroll_containers,
|
|
8374
|
+
dom_quiet_window: std::time::Duration::from_millis(val.dom_quiet_window),
|
|
8375
|
+
dom_quiet_cap: std::time::Duration::from_millis(val.dom_quiet_cap),
|
|
8139
8376
|
..Default::default()
|
|
8140
8377
|
}
|
|
8141
8378
|
}
|
|
@@ -8162,6 +8399,9 @@ impl From<crawlberg::BrowserConfig> for BrowserConfig {
|
|
|
8162
8399
|
session_affinity: val.session_affinity,
|
|
8163
8400
|
chrome_path: val.chrome_path.map(|p| p.to_string_lossy().to_string()),
|
|
8164
8401
|
chrome_args: val.chrome_args.into_iter().collect(),
|
|
8402
|
+
scroll_containers: val.scroll_containers,
|
|
8403
|
+
dom_quiet_window: val.dom_quiet_window.as_millis() as u64,
|
|
8404
|
+
dom_quiet_cap: val.dom_quiet_cap.as_millis() as u64,
|
|
8165
8405
|
}
|
|
8166
8406
|
}
|
|
8167
8407
|
}
|
|
@@ -8258,6 +8498,10 @@ impl From<ContentConfig> for crawlberg::ContentConfig {
|
|
|
8258
8498
|
compact_tables: val.compact_tables,
|
|
8259
8499
|
keep_inline_images_in: val.keep_inline_images_in.into_iter().collect(),
|
|
8260
8500
|
keep_hidden: val.keep_hidden,
|
|
8501
|
+
expand_abbreviations: val.expand_abbreviations,
|
|
8502
|
+
escape_misc: val.escape_misc,
|
|
8503
|
+
escape_asterisks: val.escape_asterisks,
|
|
8504
|
+
include_icon_labels: val.include_icon_labels,
|
|
8261
8505
|
..Default::default()
|
|
8262
8506
|
}
|
|
8263
8507
|
}
|
|
@@ -8286,6 +8530,10 @@ impl From<crawlberg::ContentConfig> for ContentConfig {
|
|
|
8286
8530
|
compact_tables: val.compact_tables,
|
|
8287
8531
|
keep_inline_images_in: val.keep_inline_images_in.into_iter().collect(),
|
|
8288
8532
|
keep_hidden: val.keep_hidden,
|
|
8533
|
+
expand_abbreviations: val.expand_abbreviations,
|
|
8534
|
+
escape_misc: val.escape_misc,
|
|
8535
|
+
escape_asterisks: val.escape_asterisks,
|
|
8536
|
+
include_icon_labels: val.include_icon_labels,
|
|
8289
8537
|
}
|
|
8290
8538
|
}
|
|
8291
8539
|
}
|
|
@@ -8379,6 +8627,8 @@ impl From<CrawlConfig> for crawlberg::CrawlConfig {
|
|
|
8379
8627
|
save_browser_profile: val.save_browser_profile,
|
|
8380
8628
|
ssrf: val.ssrf.into(),
|
|
8381
8629
|
ssrf_deny_private_explicit: val.ssrf_deny_private_explicit,
|
|
8630
|
+
danger_accept_invalid_certs: val.danger_accept_invalid_certs,
|
|
8631
|
+
subdomain_header_allowlist: val.subdomain_header_allowlist.into_iter().collect(),
|
|
8382
8632
|
..Default::default()
|
|
8383
8633
|
}
|
|
8384
8634
|
}
|
|
@@ -8447,6 +8697,8 @@ impl From<crawlberg::CrawlConfig> for CrawlConfig {
|
|
|
8447
8697
|
save_browser_profile: val.save_browser_profile,
|
|
8448
8698
|
ssrf: val.ssrf.into(),
|
|
8449
8699
|
ssrf_deny_private_explicit: val.ssrf_deny_private_explicit,
|
|
8700
|
+
danger_accept_invalid_certs: val.danger_accept_invalid_certs,
|
|
8701
|
+
subdomain_header_allowlist: val.subdomain_header_allowlist.into_iter().collect(),
|
|
8450
8702
|
}
|
|
8451
8703
|
}
|
|
8452
8704
|
}
|
|
@@ -8536,6 +8788,7 @@ impl From<CrawlResult> for crawlberg::CrawlResult {
|
|
|
8536
8788
|
cookies: val.cookies.into_iter().map(Into::into).collect(),
|
|
8537
8789
|
stayed_on_domain: val.stayed_on_domain,
|
|
8538
8790
|
browser_used: val.browser_used,
|
|
8791
|
+
waf_block: val.waf_block.map(Into::into),
|
|
8539
8792
|
..Default::default()
|
|
8540
8793
|
}
|
|
8541
8794
|
}
|
|
@@ -8553,6 +8806,7 @@ impl From<crawlberg::CrawlResult> for CrawlResult {
|
|
|
8553
8806
|
cookies: val.cookies.into_iter().map(Into::into).collect(),
|
|
8554
8807
|
stayed_on_domain: val.stayed_on_domain,
|
|
8555
8808
|
browser_used: val.browser_used,
|
|
8809
|
+
waf_block: val.waf_block.map(Into::into),
|
|
8556
8810
|
}
|
|
8557
8811
|
}
|
|
8558
8812
|
}
|
|
@@ -9214,6 +9468,29 @@ impl From<crawlberg::SsrfPolicy> for SsrfPolicy {
|
|
|
9214
9468
|
}
|
|
9215
9469
|
}
|
|
9216
9470
|
|
|
9471
|
+
#[allow(clippy::needless_update)]
|
|
9472
|
+
impl From<WafBlockDetails> for crawlberg::WafBlockDetails {
|
|
9473
|
+
fn from(val: WafBlockDetails) -> Self {
|
|
9474
|
+
Self {
|
|
9475
|
+
vendor: val.vendor,
|
|
9476
|
+
status: val.status,
|
|
9477
|
+
body_prefix: val.body_prefix,
|
|
9478
|
+
..Default::default()
|
|
9479
|
+
}
|
|
9480
|
+
}
|
|
9481
|
+
}
|
|
9482
|
+
|
|
9483
|
+
#[allow(clippy::redundant_closure)]
|
|
9484
|
+
impl From<crawlberg::WafBlockDetails> for WafBlockDetails {
|
|
9485
|
+
fn from(val: crawlberg::WafBlockDetails) -> Self {
|
|
9486
|
+
Self {
|
|
9487
|
+
vendor: val.vendor.to_string(),
|
|
9488
|
+
status: val.status,
|
|
9489
|
+
body_prefix: val.body_prefix.map(|v| v.to_string()),
|
|
9490
|
+
}
|
|
9491
|
+
}
|
|
9492
|
+
}
|
|
9493
|
+
|
|
9217
9494
|
impl From<AssetCategory> for crawlberg::AssetCategory {
|
|
9218
9495
|
fn from(val: AssetCategory) -> Self {
|
|
9219
9496
|
match val {
|
|
@@ -9570,18 +9847,92 @@ impl From<crawlberg::ScrollDirection> for ScrollDirection {
|
|
|
9570
9847
|
}
|
|
9571
9848
|
}
|
|
9572
9849
|
|
|
9573
|
-
/// Convert a
|
|
9850
|
+
/// Convert the error a core call returned into the typed Ruby exception of its family. An error
|
|
9851
|
+
/// of a type with no converter becomes a `RuntimeError` with the message.
|
|
9852
|
+
#[allow(dead_code)]
|
|
9853
|
+
fn alef_magnus_err<E: std::fmt::Display + 'static>(e: E) -> magnus::Error {
|
|
9854
|
+
let message = e.to_string();
|
|
9855
|
+
#[allow(unused_variables)]
|
|
9856
|
+
let any: Box<dyn std::any::Any> = Box::new(e);
|
|
9857
|
+
let any = match any.downcast::<crawlberg::CrawlError>() {
|
|
9858
|
+
Ok(typed) => return crawl_error_to_magnus_err(*typed),
|
|
9859
|
+
Err(any) => any,
|
|
9860
|
+
};
|
|
9861
|
+
let any = match any.downcast::<crawlberg::SsrfError>() {
|
|
9862
|
+
Ok(typed) => return ssrf_error_to_magnus_err(*typed),
|
|
9863
|
+
Err(any) => any,
|
|
9864
|
+
};
|
|
9865
|
+
let _ = any;
|
|
9866
|
+
magnus::Error::new(
|
|
9867
|
+
unsafe { magnus::Ruby::get_unchecked() }.exception_runtime_error(),
|
|
9868
|
+
message,
|
|
9869
|
+
)
|
|
9870
|
+
}
|
|
9871
|
+
|
|
9872
|
+
/// Convert a `crawlberg::CrawlError` error to a typed Ruby exception.
|
|
9574
9873
|
#[allow(dead_code)]
|
|
9575
9874
|
fn crawl_error_to_magnus_err(e: crawlberg::CrawlError) -> magnus::Error {
|
|
9576
|
-
|
|
9577
|
-
|
|
9875
|
+
use magnus::prelude::*;
|
|
9876
|
+
let message = e.to_string();
|
|
9877
|
+
let ruby = unsafe { magnus::Ruby::get_unchecked() };
|
|
9878
|
+
#[allow(unreachable_patterns)]
|
|
9879
|
+
let class_name = match &e {
|
|
9880
|
+
crawlberg::CrawlError::NotFound { .. } => "NotFoundError",
|
|
9881
|
+
crawlberg::CrawlError::Unauthorized { .. } => "UnauthorizedError",
|
|
9882
|
+
crawlberg::CrawlError::Forbidden { .. } => "ForbiddenError",
|
|
9883
|
+
crawlberg::CrawlError::WafBlocked { .. } => "WafBlockedError",
|
|
9884
|
+
crawlberg::CrawlError::Timeout { .. } => "CrawlTimeoutError",
|
|
9885
|
+
crawlberg::CrawlError::RateLimited { .. } => "RateLimitedError",
|
|
9886
|
+
crawlberg::CrawlError::ServerError { .. } => "ServerError",
|
|
9887
|
+
crawlberg::CrawlError::BadGateway { .. } => "BadGatewayError",
|
|
9888
|
+
crawlberg::CrawlError::Gone { .. } => "GoneError",
|
|
9889
|
+
crawlberg::CrawlError::Connection { .. } => "CrawlConnectionError",
|
|
9890
|
+
crawlberg::CrawlError::Dns { .. } => "DnsError",
|
|
9891
|
+
crawlberg::CrawlError::Ssl { .. } => "SslError",
|
|
9892
|
+
crawlberg::CrawlError::DataLoss { .. } => "DataLossError",
|
|
9893
|
+
crawlberg::CrawlError::ConversionFailed { .. } => "ConversionFailedError",
|
|
9894
|
+
crawlberg::CrawlError::BrowserError { .. } => "BrowserError",
|
|
9895
|
+
crawlberg::CrawlError::BrowserTimeout { .. } => "BrowserTimeoutError",
|
|
9896
|
+
crawlberg::CrawlError::InvalidConfig { .. } => "InvalidConfigError",
|
|
9897
|
+
crawlberg::CrawlError::Unsupported { .. } => "UnsupportedError",
|
|
9898
|
+
crawlberg::CrawlError::TooManyRedirects { .. } => "TooManyRedirectsError",
|
|
9899
|
+
crawlberg::CrawlError::SsrfPolicyViolation { .. } => "SsrfPolicyViolationError",
|
|
9900
|
+
crawlberg::CrawlError::Other { .. } => "OtherError",
|
|
9901
|
+
_ => "CrawlError",
|
|
9902
|
+
};
|
|
9903
|
+
let build = || -> Result<magnus::Error, magnus::Error> {
|
|
9904
|
+
let module = ruby.define_module("Crawlberg")?;
|
|
9905
|
+
let class: magnus::ExceptionClass = module.const_get(class_name)?;
|
|
9906
|
+
let exception = class.new_instance((message.as_str(),))?;
|
|
9907
|
+
Ok(magnus::Error::from(exception))
|
|
9908
|
+
};
|
|
9909
|
+
build().unwrap_or_else(|_| magnus::Error::new(ruby.exception_runtime_error(), message))
|
|
9578
9910
|
}
|
|
9579
9911
|
|
|
9580
|
-
/// Convert a `crawlberg::SsrfError` error to a
|
|
9912
|
+
/// Convert a `crawlberg::SsrfError` error to a typed Ruby exception.
|
|
9581
9913
|
#[allow(dead_code)]
|
|
9582
9914
|
fn ssrf_error_to_magnus_err(e: crawlberg::SsrfError) -> magnus::Error {
|
|
9583
|
-
|
|
9584
|
-
|
|
9915
|
+
use magnus::prelude::*;
|
|
9916
|
+
let message = e.to_string();
|
|
9917
|
+
let ruby = unsafe { magnus::Ruby::get_unchecked() };
|
|
9918
|
+
#[allow(unreachable_patterns)]
|
|
9919
|
+
let class_name = match &e {
|
|
9920
|
+
crawlberg::SsrfError::DeniedByPolicy { .. } => "DeniedByPolicyError",
|
|
9921
|
+
crawlberg::SsrfError::NotOnAllowlist => "NotOnAllowlistError",
|
|
9922
|
+
crawlberg::SsrfError::InvalidCidr(..) => "InvalidCidrError",
|
|
9923
|
+
crawlberg::SsrfError::DnsResolutionFailed(..) => "DnsResolutionFailedError",
|
|
9924
|
+
crawlberg::SsrfError::InvalidUrl(..) => "InvalidUrlError",
|
|
9925
|
+
crawlberg::SsrfError::DisallowedScheme(..) => "DisallowedSchemeError",
|
|
9926
|
+
crawlberg::SsrfError::TooManyRedirects => "TooManyRedirectsError",
|
|
9927
|
+
_ => "SsrfError",
|
|
9928
|
+
};
|
|
9929
|
+
let build = || -> Result<magnus::Error, magnus::Error> {
|
|
9930
|
+
let module = ruby.define_module("Crawlberg")?;
|
|
9931
|
+
let class: magnus::ExceptionClass = module.const_get(class_name)?;
|
|
9932
|
+
let exception = class.new_instance((message.as_str(),))?;
|
|
9933
|
+
Ok(magnus::Error::from(exception))
|
|
9934
|
+
};
|
|
9935
|
+
build().unwrap_or_else(|_| magnus::Error::new(ruby.exception_runtime_error(), message))
|
|
9585
9936
|
}
|
|
9586
9937
|
|
|
9587
9938
|
#[derive(Clone)]
|
|
@@ -9629,7 +9980,7 @@ impl CrawlStreamIterator {
|
|
|
9629
9980
|
let binding: CrawlEvent = chunk.into();
|
|
9630
9981
|
Ok(binding.into_value_with(&ruby))
|
|
9631
9982
|
}
|
|
9632
|
-
Some(Err(e)) => Err(
|
|
9983
|
+
Some(Err(e)) => Err(alef_magnus_err(e)),
|
|
9633
9984
|
None => {
|
|
9634
9985
|
// Drop the stream to release any resources.
|
|
9635
9986
|
let inner = self.inner.clone();
|
|
@@ -9711,7 +10062,7 @@ impl BatchCrawlStreamIterator {
|
|
|
9711
10062
|
let binding: CrawlEvent = chunk.into();
|
|
9712
10063
|
Ok(binding.into_value_with(&ruby))
|
|
9713
10064
|
}
|
|
9714
|
-
Some(Err(e)) => Err(
|
|
10065
|
+
Some(Err(e)) => Err(alef_magnus_err(e)),
|
|
9715
10066
|
None => {
|
|
9716
10067
|
// Drop the stream to release any resources.
|
|
9717
10068
|
let inner = self.inner.clone();
|
|
@@ -9876,6 +10227,12 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
9876
10227
|
|
|
9877
10228
|
class.define_method("chrome_args", method!(BrowserConfig::chrome_args, 0))?;
|
|
9878
10229
|
|
|
10230
|
+
class.define_method("scroll_containers", method!(BrowserConfig::scroll_containers, 0))?;
|
|
10231
|
+
|
|
10232
|
+
class.define_method("dom_quiet_window", method!(BrowserConfig::dom_quiet_window, 0))?;
|
|
10233
|
+
|
|
10234
|
+
class.define_method("dom_quiet_cap", method!(BrowserConfig::dom_quiet_cap, 0))?;
|
|
10235
|
+
|
|
9879
10236
|
let class = module.define_class("BrowserExtras", ruby.class_object())?;
|
|
9880
10237
|
|
|
9881
10238
|
class.define_singleton_method("new", function!(BrowserExtras::new, -1))?;
|
|
@@ -9956,6 +10313,14 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
9956
10313
|
|
|
9957
10314
|
class.define_method("keep_hidden", method!(ContentConfig::keep_hidden, 0))?;
|
|
9958
10315
|
|
|
10316
|
+
class.define_method("expand_abbreviations", method!(ContentConfig::expand_abbreviations, 0))?;
|
|
10317
|
+
|
|
10318
|
+
class.define_method("escape_misc", method!(ContentConfig::escape_misc, 0))?;
|
|
10319
|
+
|
|
10320
|
+
class.define_method("escape_asterisks", method!(ContentConfig::escape_asterisks, 0))?;
|
|
10321
|
+
|
|
10322
|
+
class.define_method("include_icon_labels", method!(ContentConfig::include_icon_labels, 0))?;
|
|
10323
|
+
|
|
9959
10324
|
let class = module.define_class("CookieInfo", ruby.class_object())?;
|
|
9960
10325
|
|
|
9961
10326
|
class.define_singleton_method("new", function!(CookieInfo::new, -1))?;
|
|
@@ -10100,6 +10465,16 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
10100
10465
|
method!(CrawlConfig::ssrf_deny_private_explicit, 0),
|
|
10101
10466
|
)?;
|
|
10102
10467
|
|
|
10468
|
+
class.define_method(
|
|
10469
|
+
"danger_accept_invalid_certs",
|
|
10470
|
+
method!(CrawlConfig::danger_accept_invalid_certs, 0),
|
|
10471
|
+
)?;
|
|
10472
|
+
|
|
10473
|
+
class.define_method(
|
|
10474
|
+
"subdomain_header_allowlist",
|
|
10475
|
+
method!(CrawlConfig::subdomain_header_allowlist, 0),
|
|
10476
|
+
)?;
|
|
10477
|
+
|
|
10103
10478
|
class.define_method("validate", method!(CrawlConfig::validate, 0))?;
|
|
10104
10479
|
|
|
10105
10480
|
let class = module.define_class("CrawlEngineHandle", ruby.class_object())?;
|
|
@@ -10185,6 +10560,8 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
10185
10560
|
|
|
10186
10561
|
class.define_method("browser_used", method!(CrawlResult::browser_used, 0))?;
|
|
10187
10562
|
|
|
10563
|
+
class.define_method("waf_block", method!(CrawlResult::waf_block, 0))?;
|
|
10564
|
+
|
|
10188
10565
|
class.define_method(
|
|
10189
10566
|
"unique_normalized_urls",
|
|
10190
10567
|
method!(CrawlResult::unique_normalized_urls, 0),
|
|
@@ -10574,6 +10951,16 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
10574
10951
|
|
|
10575
10952
|
class.define_method("scheme_allowlist", method!(SsrfPolicy::scheme_allowlist, 0))?;
|
|
10576
10953
|
|
|
10954
|
+
let class = module.define_class("WafBlockDetails", ruby.class_object())?;
|
|
10955
|
+
|
|
10956
|
+
class.define_singleton_method("new", function!(WafBlockDetails::new, -1))?;
|
|
10957
|
+
|
|
10958
|
+
class.define_method("vendor", method!(WafBlockDetails::vendor, 0))?;
|
|
10959
|
+
|
|
10960
|
+
class.define_method("status", method!(WafBlockDetails::status, 0))?;
|
|
10961
|
+
|
|
10962
|
+
class.define_method("body_prefix", method!(WafBlockDetails::body_prefix, 0))?;
|
|
10963
|
+
|
|
10577
10964
|
let class = module.define_class("CrawlStreamIterator", ruby.class_object())?;
|
|
10578
10965
|
class.define_method("next_chunk", method!(CrawlStreamIterator::next_chunk, 0))?;
|
|
10579
10966
|
class.define_method("each", method!(CrawlStreamIterator::each, 0))?;
|
|
@@ -10603,5 +10990,35 @@ fn ruby_init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
10603
10990
|
|
|
10604
10991
|
module.define_module_function("batch_crawl_stream", function!(batch_crawl_stream, 2))?;
|
|
10605
10992
|
|
|
10993
|
+
let crawl_error_class = module.define_error("CrawlError", ruby.exception_standard_error())?;
|
|
10994
|
+
let not_found_error_class = module.define_error("NotFoundError", crawl_error_class)?;
|
|
10995
|
+
let unauthorized_error_class = module.define_error("UnauthorizedError", crawl_error_class)?;
|
|
10996
|
+
let forbidden_error_class = module.define_error("ForbiddenError", crawl_error_class)?;
|
|
10997
|
+
let waf_blocked_error_class = module.define_error("WafBlockedError", crawl_error_class)?;
|
|
10998
|
+
let crawl_timeout_error_class = module.define_error("CrawlTimeoutError", crawl_error_class)?;
|
|
10999
|
+
let rate_limited_error_class = module.define_error("RateLimitedError", crawl_error_class)?;
|
|
11000
|
+
let server_error_class = module.define_error("ServerError", crawl_error_class)?;
|
|
11001
|
+
let bad_gateway_error_class = module.define_error("BadGatewayError", crawl_error_class)?;
|
|
11002
|
+
let gone_error_class = module.define_error("GoneError", crawl_error_class)?;
|
|
11003
|
+
let crawl_connection_error_class = module.define_error("CrawlConnectionError", crawl_error_class)?;
|
|
11004
|
+
let dns_error_class = module.define_error("DnsError", crawl_error_class)?;
|
|
11005
|
+
let ssl_error_class = module.define_error("SslError", crawl_error_class)?;
|
|
11006
|
+
let data_loss_error_class = module.define_error("DataLossError", crawl_error_class)?;
|
|
11007
|
+
let conversion_failed_error_class = module.define_error("ConversionFailedError", crawl_error_class)?;
|
|
11008
|
+
let browser_error_class = module.define_error("BrowserError", crawl_error_class)?;
|
|
11009
|
+
let browser_timeout_error_class = module.define_error("BrowserTimeoutError", crawl_error_class)?;
|
|
11010
|
+
let invalid_config_error_class = module.define_error("InvalidConfigError", crawl_error_class)?;
|
|
11011
|
+
let unsupported_error_class = module.define_error("UnsupportedError", crawl_error_class)?;
|
|
11012
|
+
let ssrf_policy_violation_error_class = module.define_error("SsrfPolicyViolationError", crawl_error_class)?;
|
|
11013
|
+
let other_error_class = module.define_error("OtherError", crawl_error_class)?;
|
|
11014
|
+
let ssrf_error_class = module.define_error("SsrfError", crawl_error_class)?;
|
|
11015
|
+
let denied_by_policy_error_class = module.define_error("DeniedByPolicyError", ssrf_error_class)?;
|
|
11016
|
+
let not_on_allowlist_error_class = module.define_error("NotOnAllowlistError", ssrf_error_class)?;
|
|
11017
|
+
let invalid_cidr_error_class = module.define_error("InvalidCidrError", ssrf_error_class)?;
|
|
11018
|
+
let dns_resolution_failed_error_class = module.define_error("DnsResolutionFailedError", ssrf_error_class)?;
|
|
11019
|
+
let invalid_url_error_class = module.define_error("InvalidUrlError", ssrf_error_class)?;
|
|
11020
|
+
let disallowed_scheme_error_class = module.define_error("DisallowedSchemeError", ssrf_error_class)?;
|
|
11021
|
+
let too_many_redirects_error_class = module.define_error("TooManyRedirectsError", ssrf_error_class)?;
|
|
11022
|
+
|
|
10606
11023
|
Ok(())
|
|
10607
11024
|
}
|