outpunch 0.1.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f8205e1ea81ec7b911a0180ac666e3d68fbe898a4d7387a04aa4c3b488cf6c73
4
+ data.tar.gz: 87951c241fc7437be227e386c50dc6286c5fcb0e2fc52107dec249d597bb32a0
5
+ SHA512:
6
+ metadata.gz: 7abee70786092c2e5125de67dbeb9e529af696d2ac92530d99b35e5428accce9cf75e59cb2fd1a18e6b4b4c42ed8a10e8aae54f1b8ef1c533de162cb319846c3
7
+ data.tar.gz: '09ac444b6ac28cb1b10c3a49d4707d574f16ec551fc635569bd78a80a3a99e762d50c41006a38e91a155b7b849035d5388331ba647f8769ded2aeb34b77ae704'
@@ -0,0 +1,17 @@
1
+ [package]
2
+ name = "outpunch"
3
+ version = "0.1.0"
4
+ edition = "2024"
5
+
6
+ [lib]
7
+ name = "outpunch"
8
+ crate-type = ["cdylib"]
9
+
10
+ [dependencies]
11
+ outpunch-client = { version = "0.1.1", path = "../../../../crates/outpunch-client" }
12
+ magnus = { version = "0.8" }
13
+ rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
14
+ tokio = { version = "1.50.0", features = ["full"] }
15
+
16
+ [build-dependencies]
17
+ rb-sys-build = "0.9"
@@ -0,0 +1,4 @@
1
+ require "mkmf"
2
+ require "rb_sys/mkmf"
3
+
4
+ create_rust_makefile("outpunch")
@@ -0,0 +1,163 @@
1
+ use std::sync::Mutex;
2
+ use std::time::Duration;
3
+
4
+ use magnus::{function, method, prelude::*, wrap, Error, Ruby};
5
+
6
+ struct ClientConfigInner {
7
+ server_url: String,
8
+ secret: String,
9
+ service: String,
10
+ forward_to: String,
11
+ reconnect_delay: f64,
12
+ request_timeout: f64,
13
+ }
14
+
15
+ #[wrap(class = "Outpunch::ClientConfig", free_immediately, size)]
16
+ pub struct ClientConfig(Mutex<ClientConfigInner>);
17
+
18
+ impl ClientConfig {
19
+ fn new(
20
+ server_url: String,
21
+ secret: String,
22
+ service: String,
23
+ forward_to: Option<String>,
24
+ reconnect_delay: Option<f64>,
25
+ request_timeout: Option<f64>,
26
+ ) -> Self {
27
+ Self(Mutex::new(ClientConfigInner {
28
+ server_url,
29
+ secret,
30
+ service,
31
+ forward_to: forward_to.unwrap_or_else(|| "http://localhost:8080".into()),
32
+ reconnect_delay: reconnect_delay.unwrap_or(5.0),
33
+ request_timeout: request_timeout.unwrap_or(25.0),
34
+ }))
35
+ }
36
+
37
+ fn to_rust(&self) -> outpunch_client::ClientConfig {
38
+ let inner = self.0.lock().unwrap();
39
+ outpunch_client::ClientConfig {
40
+ server_url: inner.server_url.clone(),
41
+ secret: inner.secret.clone(),
42
+ service: inner.service.clone(),
43
+ forward_to: inner.forward_to.clone(),
44
+ reconnect_delay: Duration::from_secs_f64(inner.reconnect_delay),
45
+ request_timeout: Duration::from_secs_f64(inner.request_timeout),
46
+ }
47
+ }
48
+
49
+ fn server_url(&self) -> String {
50
+ self.0.lock().unwrap().server_url.clone()
51
+ }
52
+
53
+ fn set_server_url(&self, v: String) {
54
+ self.0.lock().unwrap().server_url = v;
55
+ }
56
+
57
+ fn secret(&self) -> String {
58
+ self.0.lock().unwrap().secret.clone()
59
+ }
60
+
61
+ fn set_secret(&self, v: String) {
62
+ self.0.lock().unwrap().secret = v;
63
+ }
64
+
65
+ fn service(&self) -> String {
66
+ self.0.lock().unwrap().service.clone()
67
+ }
68
+
69
+ fn set_service(&self, v: String) {
70
+ self.0.lock().unwrap().service = v;
71
+ }
72
+
73
+ fn forward_to(&self) -> String {
74
+ self.0.lock().unwrap().forward_to.clone()
75
+ }
76
+
77
+ fn set_forward_to(&self, v: String) {
78
+ self.0.lock().unwrap().forward_to = v;
79
+ }
80
+
81
+ fn reconnect_delay(&self) -> f64 {
82
+ self.0.lock().unwrap().reconnect_delay
83
+ }
84
+
85
+ fn set_reconnect_delay(&self, v: f64) {
86
+ self.0.lock().unwrap().reconnect_delay = v;
87
+ }
88
+
89
+ fn request_timeout(&self) -> f64 {
90
+ self.0.lock().unwrap().request_timeout
91
+ }
92
+
93
+ fn set_request_timeout(&self, v: f64) {
94
+ self.0.lock().unwrap().request_timeout = v;
95
+ }
96
+
97
+ fn inspect(&self) -> String {
98
+ let inner = self.0.lock().unwrap();
99
+ format!(
100
+ "#<Outpunch::ClientConfig server_url={:?} service={:?} forward_to={:?}>",
101
+ inner.server_url, inner.service, inner.forward_to
102
+ )
103
+ }
104
+ }
105
+
106
+ fn run(_ruby: &Ruby, config: &ClientConfig) -> Result<(), Error> {
107
+ let rust_config = config.to_rust();
108
+ tokio::runtime::Builder::new_current_thread()
109
+ .enable_all()
110
+ .build()
111
+ .unwrap()
112
+ .block_on(outpunch_client::run(&rust_config));
113
+ Ok(())
114
+ }
115
+
116
+ fn run_connection(ruby: &Ruby, config: &ClientConfig) -> Result<(), Error> {
117
+ let rust_config = config.to_rust();
118
+ let result = tokio::runtime::Builder::new_current_thread()
119
+ .enable_all()
120
+ .build()
121
+ .unwrap()
122
+ .block_on(outpunch_client::run_connection(&rust_config));
123
+ result.map_err(|e: Box<dyn std::error::Error + Send + Sync>| {
124
+ Error::new(ruby.exception_runtime_error(), e.to_string())
125
+ })
126
+ }
127
+
128
+ #[magnus::init]
129
+ fn init(ruby: &Ruby) -> Result<(), Error> {
130
+ let module = ruby.define_module("Outpunch")?;
131
+
132
+ let config_class = module.define_class("ClientConfig", ruby.class_object())?;
133
+ config_class.define_singleton_method("new", function!(ClientConfig::new, 6))?;
134
+ config_class.define_method("server_url", method!(ClientConfig::server_url, 0))?;
135
+ config_class.define_method("server_url=", method!(ClientConfig::set_server_url, 1))?;
136
+ config_class.define_method("secret", method!(ClientConfig::secret, 0))?;
137
+ config_class.define_method("secret=", method!(ClientConfig::set_secret, 1))?;
138
+ config_class.define_method("service", method!(ClientConfig::service, 0))?;
139
+ config_class.define_method("service=", method!(ClientConfig::set_service, 1))?;
140
+ config_class.define_method("forward_to", method!(ClientConfig::forward_to, 0))?;
141
+ config_class.define_method("forward_to=", method!(ClientConfig::set_forward_to, 1))?;
142
+ config_class.define_method("reconnect_delay", method!(ClientConfig::reconnect_delay, 0))?;
143
+ config_class.define_method(
144
+ "reconnect_delay=",
145
+ method!(ClientConfig::set_reconnect_delay, 1),
146
+ )?;
147
+ config_class.define_method("request_timeout", method!(ClientConfig::request_timeout, 0))?;
148
+ config_class.define_method(
149
+ "request_timeout=",
150
+ method!(ClientConfig::set_request_timeout, 1),
151
+ )?;
152
+ config_class.define_method("inspect", method!(ClientConfig::inspect, 0))?;
153
+ config_class.define_method("to_s", method!(ClientConfig::inspect, 0))?;
154
+
155
+ module.define_module_function("run", function!(run, 1))?;
156
+ module.define_module_function("run_connection", function!(run_connection, 1))?;
157
+
158
+ Ok(())
159
+ }
160
+
161
+ #[cfg(test)]
162
+ #[path = "lib_tests.rs"]
163
+ mod tests;
@@ -0,0 +1,36 @@
1
+ use super::ClientConfig;
2
+
3
+ #[test]
4
+ fn client_config_defaults() {
5
+ let config = ClientConfig::new(
6
+ "wss://example.com/ws".into(),
7
+ "secret".into(),
8
+ "my-service".into(),
9
+ None,
10
+ None,
11
+ None,
12
+ );
13
+ let rust = config.to_rust();
14
+ assert_eq!(rust.forward_to, "http://localhost:8080");
15
+ assert_eq!(rust.reconnect_delay.as_secs_f64(), 5.0);
16
+ assert_eq!(rust.request_timeout.as_secs_f64(), 25.0);
17
+ }
18
+
19
+ #[test]
20
+ fn client_config_custom_values() {
21
+ let config = ClientConfig::new(
22
+ "wss://example.com/ws".into(),
23
+ "mysecret".into(),
24
+ "stormsnap".into(),
25
+ Some("http://localhost:8081".into()),
26
+ Some(10.0),
27
+ Some(30.0),
28
+ );
29
+ let rust = config.to_rust();
30
+ assert_eq!(rust.server_url, "wss://example.com/ws");
31
+ assert_eq!(rust.secret, "mysecret");
32
+ assert_eq!(rust.service, "stormsnap");
33
+ assert_eq!(rust.forward_to, "http://localhost:8081");
34
+ assert_eq!(rust.reconnect_delay.as_secs_f64(), 10.0);
35
+ assert_eq!(rust.request_timeout.as_secs_f64(), 30.0);
36
+ }
data/lib/outpunch.rb ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "outpunch/outpunch"
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: outpunch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - TechyCorp
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-04-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rb_sys
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake-compiler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.12'
55
+ description:
56
+ email:
57
+ executables: []
58
+ extensions:
59
+ - ext/outpunch/extconf.rb
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ext/outpunch/Cargo.toml
63
+ - ext/outpunch/extconf.rb
64
+ - ext/outpunch/src/lib.rs
65
+ - ext/outpunch/src/lib_tests.rs
66
+ - lib/outpunch.rb
67
+ homepage:
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '3.1'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubygems_version: 3.5.22
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Ruby bindings for the outpunch tunnel client
90
+ test_files: []