flamboyant 0.1.0.rc2 → 0.1.0.rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7eb8ae7d9160f1e30393cf2c904bb40ad2912094918e19e379913955da9e9548
4
- data.tar.gz: 10589ad1e067ada7db8b4b047e5520ec840bd828569382139157d84e560594a0
3
+ metadata.gz: aefbe664b3bbec05be72302a83305d6417d9bc038a1f0338818aadbd20858822
4
+ data.tar.gz: 96d72d47c5bd4031ce45b8b7c85b1d1ca685dd18973cc460a6714d408822e612
5
5
  SHA512:
6
- metadata.gz: 9eec00f10e25d25a8286a0605a0a36eb022584cec10c033086f3f01a1168557d6f676a38f61592ac7307ac3878c32873ebe9cbe744b43b290d82a596403ccb8c
7
- data.tar.gz: 410326bd0a6e2be836ce58fc35b141400fa832a9f06084d1c117e37853f5615c9d400f93ff634d948213c0c66bab73c5379e88c7b24f477302e8a522f4263a97
6
+ metadata.gz: 40e80f46edc87d49d827be31a8f9a0890b24b7c5dd0fd26cfc8b6e489a0254ee0b95d7cb7bb34175857b0fc5f92a58cbe3756f05e198a78d00e6af69ba308ce0
7
+ data.tar.gz: 9ba96477b13693ff47f21094dd9b24a0eaefa74d63040c47ae9d09fe5c10f7a1d6047ec18bc841e78c36565dcb0e9b01182f62409eeb5fb4d818658c6c17c513
data/Cargo.lock CHANGED
@@ -31,6 +31,12 @@ dependencies = [
31
31
  "winapi",
32
32
  ]
33
33
 
34
+ [[package]]
35
+ name = "autocfg"
36
+ version = "1.1.0"
37
+ source = "registry+https://github.com/rust-lang/crates.io-index"
38
+ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
39
+
34
40
  [[package]]
35
41
  name = "bindgen"
36
42
  version = "0.59.2"
@@ -153,6 +159,7 @@ dependencies = [
153
159
  "coffret",
154
160
  "ctrlc",
155
161
  "libc",
162
+ "nix",
156
163
  "rb-sys",
157
164
  ]
158
165
 
@@ -229,6 +236,15 @@ version = "2.5.0"
229
236
  source = "registry+https://github.com/rust-lang/crates.io-index"
230
237
  checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
231
238
 
239
+ [[package]]
240
+ name = "memoffset"
241
+ version = "0.6.5"
242
+ source = "registry+https://github.com/rust-lang/crates.io-index"
243
+ checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
244
+ dependencies = [
245
+ "autocfg",
246
+ ]
247
+
232
248
  [[package]]
233
249
  name = "minimal-lexical"
234
250
  version = "0.2.1"
@@ -244,6 +260,7 @@ dependencies = [
244
260
  "bitflags",
245
261
  "cfg-if",
246
262
  "libc",
263
+ "memoffset",
247
264
  ]
248
265
 
249
266
  [[package]]
data/Cargo.toml CHANGED
@@ -5,10 +5,11 @@ edition = "2021"
5
5
 
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
7
  [lib]
8
- crate-type = ["cdylib"]
8
+ crate-type = ["lib", "cdylib"]
9
9
 
10
10
  [dependencies]
11
11
  libc = "^0.2"
12
12
  rb-sys = { version = "^0.9", features = ["link-ruby"] }
13
13
  coffret = "0.0.3"
14
14
  ctrlc = "3.2.2"
15
+ nix = "0.24.1"
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- flamboyant (0.1.0.rc1)
4
+ flamboyant (0.1.0.rc3)
5
5
  rack
6
6
  webrick
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- rack (2.2.3)
11
+ rack (2.2.3.1)
12
12
  rake (13.0.6)
13
13
  webrick (1.7.0)
14
14
 
data/config.ru CHANGED
@@ -1,5 +1,5 @@
1
1
  app = lambda {|_env|
2
- return [200, {"Content-Type" => "text/plain"}, ["Hello rack app"]]
2
+ return [200, {"Content-Type" => "text/plain"}, ["Hello rack app\n"]]
3
3
  }
4
4
 
5
5
  run app
data/examples/serve.rs CHANGED
@@ -2,6 +2,9 @@ extern crate flamboyant;
2
2
 
3
3
  fn main() {
4
4
  unsafe {
5
- flamboyant::core::rb_flamboyant_serve(flamboyant::ruby_ext::Nil.into());
5
+ flamboyant::core::rb_flamboyant_serve(
6
+ flamboyant::ruby_ext::Nil.into(),
7
+ flamboyant::ruby_ext::Nil.into(),
8
+ );
6
9
  }
7
10
  }
@@ -1,3 +1,3 @@
1
1
  class Flamboyant
2
- VERSION = "0.1.0.rc2"
2
+ VERSION = "0.1.0.rc3"
3
3
  end
data/src/core.rs CHANGED
@@ -1,10 +1,21 @@
1
1
  use std::env;
2
+ use std::ffi::CStr;
2
3
  use std::ffi::CString;
3
- use std::io::prelude::*;
4
- use std::net::TcpListener;
5
- use std::net::TcpStream;
4
+ use std::os::unix::prelude::RawFd;
6
5
  use std::slice;
6
+ use std::sync::mpsc::*;
7
+ use std::sync::Arc;
8
+ use std::sync::Mutex;
9
+ use std::thread::spawn;
7
10
 
11
+ use libc::close;
12
+ use libc::FIONBIO;
13
+ use nix::errno::Errno;
14
+ use nix::sys::select;
15
+ use nix::sys::select::FdSet;
16
+ use nix::sys::socket::recv;
17
+ use nix::sys::socket::send;
18
+ use nix::sys::socket::MsgFlags;
8
19
  use rb_sys::*;
9
20
 
10
21
  const _HELLO: &'static str = "<!DOCTYPE html>
@@ -32,43 +43,157 @@ fn serve(app: RubyValue) {
32
43
  }
33
44
 
34
45
  let port = env::var("PORT").unwrap();
35
- let address = format!("127.0.0.1:{}", &port);
46
+ // let address = format!("127.0.0.1:{}", &port);
36
47
 
37
- let listner = TcpListener::bind(&address).unwrap();
38
- println!(
39
- "Listening: http://{}",
40
- listner.local_addr().unwrap().to_string()
41
- );
48
+ // let listner = TcpListener::bind(&address).unwrap();
49
+ // println!(
50
+ // "Listening: http://{}",
51
+ // listner.local_addr().unwrap().to_string()
52
+ // );
42
53
 
43
- for stream in listner.incoming() {
44
- let stream = stream.unwrap();
45
- handle_connection(app, stream);
54
+ use nix::sys::socket::*;
55
+ let sock = socket(
56
+ AddressFamily::Inet,
57
+ SockType::Stream,
58
+ SockFlag::empty(),
59
+ None,
60
+ )
61
+ .unwrap();
62
+ let on: i8 = 1;
63
+ unsafe {
64
+ if libc::ioctl(sock, FIONBIO, &on) < 0 {
65
+ panic!("ioctl failed");
66
+ }
67
+ }
68
+
69
+ let addr = SockaddrIn::new(127, 0, 0, 1, port.parse().unwrap());
70
+ bind(sock, &addr).unwrap();
71
+ listen(sock, 4096).unwrap();
72
+ println!("Listening");
73
+
74
+ let (sender, receiver) = sync_channel::<Vec<u8>>(4096);
75
+ let (out_sender, out_receiver) = sync_channel::<Vec<u8>>(4096);
76
+
77
+ let mut fdset = FdSet::new();
78
+ fdset.insert(sock);
79
+
80
+ let out_recvr = Arc::new(Mutex::new(out_receiver));
81
+ let sendr = Arc::new(Mutex::new(sender));
82
+
83
+ let th = spawn(move || loop {
84
+ match select::select(None, Some(&mut fdset), None, None, None) {
85
+ Ok(n) => {
86
+ let sock = fdset.highest().unwrap();
87
+ if n > 0 {
88
+ let go = sendr.clone();
89
+ let out = out_recvr.clone();
90
+ spawn(move || {
91
+ let fd: RawFd;
92
+ loop {
93
+ if let Ok(fd_) = accept(sock) {
94
+ fd = fd_;
95
+ break;
96
+ }
97
+ }
98
+ let data = process(fd);
99
+ go.lock().unwrap().send(data).unwrap();
100
+ let bytes = out.lock().unwrap().recv().unwrap();
101
+ //let bytes = out_receiver.recv().unwrap();
102
+ do_response(fd, &bytes);
103
+ unsafe { close(fd) };
104
+ });
105
+ }
106
+ }
107
+ Err(e) => match e {
108
+ Errno::EWOULDBLOCK => {}
109
+ _ => {
110
+ panic!("{}", e)
111
+ }
112
+ },
113
+ }
114
+ });
115
+
116
+ loop {
117
+ let data = receiver.recv().unwrap();
118
+ let req = String::from_utf8_lossy(&data);
119
+ let reqline = req.lines().collect::<Vec<&str>>()[0];
120
+ println!("{}", reqline);
121
+ let response = handle_connection(app, &data);
122
+ out_sender.send(response).unwrap();
46
123
  }
124
+
125
+ th.join().unwrap();
47
126
  }
48
127
 
49
- fn handle_connection(app: RubyValue, mut stream: TcpStream) {
128
+ //fn handle_connection(app: RubyValue, stream: &mut TcpStream) -> bool {
129
+ fn process(stream: RawFd) -> Vec<u8> {
50
130
  let mut buffer = [0; 4096];
51
131
 
52
- stream.read(&mut buffer).unwrap();
132
+ let mut read_bytes = 0;
133
+ loop {
134
+ match recv(stream, &mut buffer, MsgFlags::empty()) {
135
+ Ok(n) => {
136
+ if n > 0 {
137
+ read_bytes += n;
138
+ } else {
139
+ if read_bytes > 0 {
140
+ break;
141
+ }
142
+ }
143
+ }
144
+ Err(e) => match e {
145
+ Errno::EWOULDBLOCK => {
146
+ if read_bytes > 0 {
147
+ break;
148
+ }
149
+ }
150
+ _ => {
151
+ panic!("{}", e)
152
+ }
153
+ },
154
+ }
155
+ }
156
+
157
+ if read_bytes == 0 {
158
+ return vec![0];
159
+ }
160
+
53
161
  let index = buffer
54
162
  .iter()
55
163
  .enumerate()
56
164
  .find(|(_i, chr)| return **chr == ('\0' as u8))
57
165
  .unwrap();
58
- let string = CString::new(&buffer[..index.0]).unwrap();
59
166
 
60
- let reqstring = unsafe { rb_utf8_str_new_cstr(string.as_ptr()) };
167
+ let data = (&buffer[..(index.0 + 1)]).to_vec();
168
+ return data;
169
+ }
170
+
171
+ fn do_response(stream: RawFd, bytes: &[u8]) {
172
+ send(stream, &bytes, MsgFlags::empty()).unwrap();
173
+ //stream.write(&bytes).unwrap();
174
+ //stream.flush().unwrap();
175
+
176
+ return;
177
+ }
178
+
179
+ fn handle_connection(app: RubyValue, data: &[u8]) -> Vec<u8> {
180
+ let request = CStr::from_bytes_with_nul(data).unwrap();
181
+ let reqstring = unsafe { rb_utf8_str_new_cstr(request.as_ptr()) };
182
+
61
183
  let call = CString::new("call").unwrap();
62
184
  let args = vec![reqstring];
63
185
  let response = unsafe { rb_funcallv(app, rb_intern(call.as_ptr()), 1, args.as_ptr()) };
64
186
  let mut response = Box::new(response);
65
187
 
188
+ // unsafe {
189
+ // rb_p(*response.as_mut());
190
+ // }
191
+
66
192
  let bytes: *const i8 = unsafe { rb_string_value_ptr(response.as_mut()) };
67
193
  let len = unsafe { macros::RSTRING_LEN(response.as_ref().clone()) };
68
194
 
69
195
  let bytes_: &[i8] = unsafe { slice::from_raw_parts(bytes, len as usize) };
70
196
  let bytes: Vec<u8> = bytes_.iter().map(|v| *v as u8).collect();
71
197
 
72
- stream.write(&bytes).unwrap();
73
- stream.flush().unwrap();
198
+ bytes
74
199
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flamboyant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.rc2
4
+ version: 0.1.0.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio Kondo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-06 00:00:00.000000000 Z
11
+ date: 2022-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack