flamboyant 0.1.0.rc2 → 0.1.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
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