puma 4.3.6 → 5.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +1346 -518
- data/LICENSE +23 -20
- data/README.md +74 -31
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +24 -20
- data/docs/compile_options.md +19 -0
- data/docs/deployment.md +15 -10
- data/docs/fork_worker.md +33 -0
- data/docs/jungle/README.md +9 -0
- data/{tools → docs}/jungle/rc.d/README.md +1 -1
- data/{tools → docs}/jungle/rc.d/puma +2 -2
- data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +2 -2
- data/docs/rails_dev_mode.md +29 -0
- data/docs/restart.md +46 -23
- data/docs/signals.md +7 -6
- data/docs/stats.md +142 -0
- data/docs/systemd.md +27 -67
- data/ext/puma_http11/PumaHttp11Service.java +2 -4
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +22 -8
- data/ext/puma_http11/http11_parser.c +45 -47
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +1 -1
- data/ext/puma_http11/http11_parser.rl +1 -1
- data/ext/puma_http11/mini_ssl.c +211 -118
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +5 -7
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +77 -18
- data/ext/puma_http11/puma_http11.c +31 -50
- data/lib/puma.rb +46 -0
- data/lib/puma/app/status.rb +47 -36
- data/lib/puma/binder.rb +177 -103
- data/lib/puma/cli.rb +11 -15
- data/lib/puma/client.rb +73 -74
- data/lib/puma/cluster.rb +184 -198
- data/lib/puma/cluster/worker.rb +183 -0
- data/lib/puma/cluster/worker_handle.rb +90 -0
- data/lib/puma/commonlogger.rb +2 -2
- data/lib/puma/configuration.rb +55 -49
- data/lib/puma/const.rb +13 -5
- data/lib/puma/control_cli.rb +93 -76
- data/lib/puma/detect.rb +24 -3
- data/lib/puma/dsl.rb +266 -92
- data/lib/puma/error_logger.rb +104 -0
- data/lib/puma/events.rb +55 -34
- data/lib/puma/io_buffer.rb +9 -2
- data/lib/puma/jruby_restart.rb +0 -58
- data/lib/puma/json.rb +96 -0
- data/lib/puma/launcher.rb +113 -45
- data/lib/puma/minissl.rb +114 -33
- data/lib/puma/minissl/context_builder.rb +6 -3
- data/lib/puma/null_io.rb +13 -1
- data/lib/puma/plugin.rb +1 -10
- data/lib/puma/queue_close.rb +26 -0
- data/lib/puma/rack/builder.rb +0 -4
- data/lib/puma/reactor.rb +85 -369
- data/lib/puma/request.rb +467 -0
- data/lib/puma/runner.rb +29 -58
- data/lib/puma/server.rb +267 -729
- data/lib/puma/single.rb +9 -65
- data/lib/puma/state_file.rb +8 -3
- data/lib/puma/systemd.rb +46 -0
- data/lib/puma/thread_pool.rb +119 -53
- data/lib/puma/util.rb +12 -0
- data/lib/rack/handler/puma.rb +2 -3
- data/tools/{docker/Dockerfile → Dockerfile} +0 -0
- metadata +25 -21
- data/docs/tcp_mode.md +0 -96
- data/ext/puma_http11/io_buffer.c +0 -155
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
- data/lib/puma/accept_nonblock.rb +0 -29
- data/lib/puma/tcp_logger.rb +0 -41
- data/tools/jungle/README.md +0 -19
- data/tools/jungle/init.d/README.md +0 -61
- data/tools/jungle/init.d/puma +0 -421
- data/tools/jungle/init.d/run-puma +0 -18
- data/tools/jungle/upstart/README.md +0 -61
- data/tools/jungle/upstart/puma-manager.conf +0 -31
- data/tools/jungle/upstart/puma.conf +0 -69
data/lib/puma/util.rb
CHANGED
@@ -23,6 +23,17 @@ module Puma
|
|
23
23
|
end
|
24
24
|
module_function :unescape
|
25
25
|
|
26
|
+
# @version 5.0.0
|
27
|
+
def nakayoshi_gc(events)
|
28
|
+
events.log "! Promoting existing objects to old generation..."
|
29
|
+
4.times { GC.start(full_mark: false) }
|
30
|
+
if GC.respond_to?(:compact)
|
31
|
+
events.log "! Compacting..."
|
32
|
+
GC.compact
|
33
|
+
end
|
34
|
+
events.log "! Friendly fork preparation complete."
|
35
|
+
end
|
36
|
+
|
26
37
|
DEFAULT_SEP = /[&;] */n
|
27
38
|
|
28
39
|
# Stolen from Mongrel, with some small modifications:
|
@@ -72,6 +83,7 @@ module Puma
|
|
72
83
|
end
|
73
84
|
end
|
74
85
|
|
86
|
+
# @!attribute [r] to_hash
|
75
87
|
def to_hash
|
76
88
|
hash = {}
|
77
89
|
each { |k,v| hash[k] = v }
|
data/lib/rack/handler/puma.rb
CHANGED
@@ -30,9 +30,8 @@ module Rack
|
|
30
30
|
end
|
31
31
|
|
32
32
|
conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
|
33
|
-
user_config.quiet
|
34
|
-
|
35
33
|
if options.delete(:Verbose)
|
34
|
+
require 'rack/common_logger'
|
36
35
|
app = Rack::CommonLogger.new(app, STDOUT)
|
37
36
|
end
|
38
37
|
|
@@ -61,7 +60,7 @@ module Rack
|
|
61
60
|
conf
|
62
61
|
end
|
63
62
|
|
64
|
-
def self.run(app, options
|
63
|
+
def self.run(app, **options)
|
65
64
|
conf = self.config(app, options)
|
66
65
|
|
67
66
|
events = options.delete(:Silent) ? ::Puma::Events.strings : ::Puma::Events.stdio
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -44,16 +44,24 @@ files:
|
|
44
44
|
- bin/puma-wild
|
45
45
|
- bin/pumactl
|
46
46
|
- docs/architecture.md
|
47
|
+
- docs/compile_options.md
|
47
48
|
- docs/deployment.md
|
49
|
+
- docs/fork_worker.md
|
48
50
|
- docs/images/puma-connection-flow-no-reactor.png
|
49
51
|
- docs/images/puma-connection-flow.png
|
50
52
|
- docs/images/puma-general-arch.png
|
53
|
+
- docs/jungle/README.md
|
54
|
+
- docs/jungle/rc.d/README.md
|
55
|
+
- docs/jungle/rc.d/puma
|
56
|
+
- docs/jungle/rc.d/puma.conf
|
57
|
+
- docs/kubernetes.md
|
51
58
|
- docs/nginx.md
|
52
59
|
- docs/plugins.md
|
60
|
+
- docs/rails_dev_mode.md
|
53
61
|
- docs/restart.md
|
54
62
|
- docs/signals.md
|
63
|
+
- docs/stats.md
|
55
64
|
- docs/systemd.md
|
56
|
-
- docs/tcp_mode.md
|
57
65
|
- ext/puma_http11/PumaHttp11Service.java
|
58
66
|
- ext/puma_http11/ext_help.h
|
59
67
|
- ext/puma_http11/extconf.rb
|
@@ -62,65 +70,61 @@ files:
|
|
62
70
|
- ext/puma_http11/http11_parser.java.rl
|
63
71
|
- ext/puma_http11/http11_parser.rl
|
64
72
|
- ext/puma_http11/http11_parser_common.rl
|
65
|
-
- ext/puma_http11/io_buffer.c
|
66
73
|
- ext/puma_http11/mini_ssl.c
|
74
|
+
- ext/puma_http11/no_ssl/PumaHttp11Service.java
|
67
75
|
- ext/puma_http11/org/jruby/puma/Http11.java
|
68
76
|
- ext/puma_http11/org/jruby/puma/Http11Parser.java
|
69
|
-
- ext/puma_http11/org/jruby/puma/IOBuffer.java
|
70
77
|
- ext/puma_http11/org/jruby/puma/MiniSSL.java
|
71
78
|
- ext/puma_http11/puma_http11.c
|
72
79
|
- lib/puma.rb
|
73
|
-
- lib/puma/accept_nonblock.rb
|
74
80
|
- lib/puma/app/status.rb
|
75
81
|
- lib/puma/binder.rb
|
76
82
|
- lib/puma/cli.rb
|
77
83
|
- lib/puma/client.rb
|
78
84
|
- lib/puma/cluster.rb
|
85
|
+
- lib/puma/cluster/worker.rb
|
86
|
+
- lib/puma/cluster/worker_handle.rb
|
79
87
|
- lib/puma/commonlogger.rb
|
80
88
|
- lib/puma/configuration.rb
|
81
89
|
- lib/puma/const.rb
|
82
90
|
- lib/puma/control_cli.rb
|
83
91
|
- lib/puma/detect.rb
|
84
92
|
- lib/puma/dsl.rb
|
93
|
+
- lib/puma/error_logger.rb
|
85
94
|
- lib/puma/events.rb
|
86
95
|
- lib/puma/io_buffer.rb
|
87
96
|
- lib/puma/jruby_restart.rb
|
97
|
+
- lib/puma/json.rb
|
88
98
|
- lib/puma/launcher.rb
|
89
99
|
- lib/puma/minissl.rb
|
90
100
|
- lib/puma/minissl/context_builder.rb
|
91
101
|
- lib/puma/null_io.rb
|
92
102
|
- lib/puma/plugin.rb
|
93
103
|
- lib/puma/plugin/tmp_restart.rb
|
104
|
+
- lib/puma/queue_close.rb
|
94
105
|
- lib/puma/rack/builder.rb
|
95
106
|
- lib/puma/rack/urlmap.rb
|
96
107
|
- lib/puma/rack_default.rb
|
97
108
|
- lib/puma/reactor.rb
|
109
|
+
- lib/puma/request.rb
|
98
110
|
- lib/puma/runner.rb
|
99
111
|
- lib/puma/server.rb
|
100
112
|
- lib/puma/single.rb
|
101
113
|
- lib/puma/state_file.rb
|
102
|
-
- lib/puma/
|
114
|
+
- lib/puma/systemd.rb
|
103
115
|
- lib/puma/thread_pool.rb
|
104
116
|
- lib/puma/util.rb
|
105
117
|
- lib/rack/handler/puma.rb
|
106
|
-
- tools/
|
107
|
-
- tools/jungle/README.md
|
108
|
-
- tools/jungle/init.d/README.md
|
109
|
-
- tools/jungle/init.d/puma
|
110
|
-
- tools/jungle/init.d/run-puma
|
111
|
-
- tools/jungle/rc.d/README.md
|
112
|
-
- tools/jungle/rc.d/puma
|
113
|
-
- tools/jungle/rc.d/puma.conf
|
114
|
-
- tools/jungle/upstart/README.md
|
115
|
-
- tools/jungle/upstart/puma-manager.conf
|
116
|
-
- tools/jungle/upstart/puma.conf
|
118
|
+
- tools/Dockerfile
|
117
119
|
- tools/trickletest.rb
|
118
|
-
homepage:
|
120
|
+
homepage: https://puma.io
|
119
121
|
licenses:
|
120
122
|
- BSD-3-Clause
|
121
123
|
metadata:
|
122
|
-
|
124
|
+
bug_tracker_uri: https://github.com/puma/puma/issues
|
123
125
|
changelog_uri: https://github.com/puma/puma/blob/master/History.md
|
126
|
+
homepage_uri: https://puma.io
|
127
|
+
source_code_uri: https://github.com/puma/puma
|
124
128
|
post_install_message:
|
125
129
|
rdoc_options: []
|
126
130
|
require_paths:
|
@@ -136,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
140
|
- !ruby/object:Gem::Version
|
137
141
|
version: '0'
|
138
142
|
requirements: []
|
139
|
-
rubygems_version: 3.
|
143
|
+
rubygems_version: 3.2.3
|
140
144
|
signing_key:
|
141
145
|
specification_version: 4
|
142
146
|
summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
|
data/docs/tcp_mode.md
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
# TCP mode
|
2
|
-
|
3
|
-
Puma also could be used as a TCP server to process incoming TCP
|
4
|
-
connections.
|
5
|
-
|
6
|
-
|
7
|
-
## Configuration
|
8
|
-
|
9
|
-
TCP mode can be enabled with CLI option `--tcp-mode`:
|
10
|
-
|
11
|
-
```
|
12
|
-
$ puma --tcp-mode
|
13
|
-
```
|
14
|
-
|
15
|
-
Default ip and port to listen to are `0.0.0.0` and `9292`. You can configure
|
16
|
-
them with `--port` and `--bind` options:
|
17
|
-
|
18
|
-
```
|
19
|
-
$ puma --tcp-mode --bind tcp://127.0.0.1:9293
|
20
|
-
$ puma --tcp-mode --port 9293
|
21
|
-
```
|
22
|
-
|
23
|
-
TCP mode could be set with a configuration file as well with `tcp_mode`
|
24
|
-
and `tcp_mode!` methods:
|
25
|
-
|
26
|
-
```
|
27
|
-
# config/puma.rb
|
28
|
-
tcp_mode
|
29
|
-
```
|
30
|
-
|
31
|
-
When Puma starts in the TCP mode it prints the corresponding message:
|
32
|
-
|
33
|
-
```
|
34
|
-
puma --tcp-mode
|
35
|
-
Puma starting in single mode...
|
36
|
-
...
|
37
|
-
* Mode: Lopez Express (tcp)
|
38
|
-
```
|
39
|
-
|
40
|
-
|
41
|
-
## How to declare an application
|
42
|
-
|
43
|
-
An application to process TCP connections should be declared as a
|
44
|
-
callable object which accepts `env` and `socket` arguments.
|
45
|
-
|
46
|
-
`env` argument is a Hash with following structure:
|
47
|
-
|
48
|
-
```ruby
|
49
|
-
{ "thread" => {}, "REMOTE_ADDR" => "127.0.0.1:51133", "log" => "#<Proc:0x000..." }
|
50
|
-
```
|
51
|
-
|
52
|
-
It consists of:
|
53
|
-
* `thread` - a Hash for each thread in the thread pool that could be
|
54
|
-
used to store information between requests
|
55
|
-
* `REMOTE_ADDR` - a client ip address
|
56
|
-
* `log` - a proc object to write something down
|
57
|
-
|
58
|
-
`log` object could be used this way:
|
59
|
-
|
60
|
-
```ruby
|
61
|
-
env['log'].call('message to log')
|
62
|
-
#> 19/Oct/2019 20:28:53 - 127.0.0.1:51266 - message to log
|
63
|
-
```
|
64
|
-
|
65
|
-
|
66
|
-
## Example of an application
|
67
|
-
|
68
|
-
Let's look at an example of a simple application which just echoes
|
69
|
-
incoming string:
|
70
|
-
|
71
|
-
```ruby
|
72
|
-
# config/puma.rb
|
73
|
-
app do |env, socket|
|
74
|
-
s = socket.gets
|
75
|
-
socket.puts "Echo #{s}"
|
76
|
-
end
|
77
|
-
```
|
78
|
-
|
79
|
-
We can easily access the TCP server with `telnet` command and receive an
|
80
|
-
echo:
|
81
|
-
|
82
|
-
```shell
|
83
|
-
telnet 0.0.0.0 9293
|
84
|
-
Trying 0.0.0.0...
|
85
|
-
Connected to 0.0.0.0.
|
86
|
-
Escape character is '^]'.
|
87
|
-
sssss
|
88
|
-
Echo sssss
|
89
|
-
^CConnection closed by foreign host.
|
90
|
-
```
|
91
|
-
|
92
|
-
|
93
|
-
## Socket management
|
94
|
-
|
95
|
-
After the application finishes, Puma closes the socket. In order to
|
96
|
-
prevent this, the application should set `env['detach'] = true`.
|
data/ext/puma_http11/io_buffer.c
DELETED
@@ -1,155 +0,0 @@
|
|
1
|
-
#define RSTRING_NOT_MODIFIED 1
|
2
|
-
#include "ruby.h"
|
3
|
-
|
4
|
-
#include <sys/types.h>
|
5
|
-
|
6
|
-
struct buf_int {
|
7
|
-
uint8_t* top;
|
8
|
-
uint8_t* cur;
|
9
|
-
|
10
|
-
size_t size;
|
11
|
-
};
|
12
|
-
|
13
|
-
#define BUF_DEFAULT_SIZE 4096
|
14
|
-
#define BUF_TOLERANCE 32
|
15
|
-
|
16
|
-
static void buf_free(struct buf_int* internal) {
|
17
|
-
xfree(internal->top);
|
18
|
-
xfree(internal);
|
19
|
-
}
|
20
|
-
|
21
|
-
static VALUE buf_alloc(VALUE self) {
|
22
|
-
VALUE buf;
|
23
|
-
struct buf_int* internal;
|
24
|
-
|
25
|
-
buf = Data_Make_Struct(self, struct buf_int, 0, buf_free, internal);
|
26
|
-
|
27
|
-
internal->size = BUF_DEFAULT_SIZE;
|
28
|
-
internal->top = ALLOC_N(uint8_t, BUF_DEFAULT_SIZE);
|
29
|
-
internal->cur = internal->top;
|
30
|
-
|
31
|
-
return buf;
|
32
|
-
}
|
33
|
-
|
34
|
-
static VALUE buf_append(VALUE self, VALUE str) {
|
35
|
-
struct buf_int* b;
|
36
|
-
size_t used, str_len, new_size;
|
37
|
-
|
38
|
-
Data_Get_Struct(self, struct buf_int, b);
|
39
|
-
|
40
|
-
used = b->cur - b->top;
|
41
|
-
|
42
|
-
StringValue(str);
|
43
|
-
str_len = RSTRING_LEN(str);
|
44
|
-
|
45
|
-
new_size = used + str_len;
|
46
|
-
|
47
|
-
if(new_size > b->size) {
|
48
|
-
size_t n = b->size + (b->size / 2);
|
49
|
-
uint8_t* top;
|
50
|
-
uint8_t* old;
|
51
|
-
|
52
|
-
new_size = (n > new_size ? n : new_size + BUF_TOLERANCE);
|
53
|
-
|
54
|
-
top = ALLOC_N(uint8_t, new_size);
|
55
|
-
old = b->top;
|
56
|
-
memcpy(top, old, used);
|
57
|
-
b->top = top;
|
58
|
-
b->cur = top + used;
|
59
|
-
b->size = new_size;
|
60
|
-
xfree(old);
|
61
|
-
}
|
62
|
-
|
63
|
-
memcpy(b->cur, RSTRING_PTR(str), str_len);
|
64
|
-
b->cur += str_len;
|
65
|
-
|
66
|
-
return self;
|
67
|
-
}
|
68
|
-
|
69
|
-
static VALUE buf_append2(int argc, VALUE* argv, VALUE self) {
|
70
|
-
struct buf_int* b;
|
71
|
-
size_t used, new_size;
|
72
|
-
int i;
|
73
|
-
VALUE str;
|
74
|
-
|
75
|
-
Data_Get_Struct(self, struct buf_int, b);
|
76
|
-
|
77
|
-
used = b->cur - b->top;
|
78
|
-
new_size = used;
|
79
|
-
|
80
|
-
for(i = 0; i < argc; i++) {
|
81
|
-
StringValue(argv[i]);
|
82
|
-
|
83
|
-
str = argv[i];
|
84
|
-
|
85
|
-
new_size += RSTRING_LEN(str);
|
86
|
-
}
|
87
|
-
|
88
|
-
if(new_size > b->size) {
|
89
|
-
size_t n = b->size + (b->size / 2);
|
90
|
-
uint8_t* top;
|
91
|
-
uint8_t* old;
|
92
|
-
|
93
|
-
new_size = (n > new_size ? n : new_size + BUF_TOLERANCE);
|
94
|
-
|
95
|
-
top = ALLOC_N(uint8_t, new_size);
|
96
|
-
old = b->top;
|
97
|
-
memcpy(top, old, used);
|
98
|
-
b->top = top;
|
99
|
-
b->cur = top + used;
|
100
|
-
b->size = new_size;
|
101
|
-
xfree(old);
|
102
|
-
}
|
103
|
-
|
104
|
-
for(i = 0; i < argc; i++) {
|
105
|
-
long str_len;
|
106
|
-
str = argv[i];
|
107
|
-
str_len = RSTRING_LEN(str);
|
108
|
-
memcpy(b->cur, RSTRING_PTR(str), str_len);
|
109
|
-
b->cur += str_len;
|
110
|
-
}
|
111
|
-
|
112
|
-
return self;
|
113
|
-
}
|
114
|
-
|
115
|
-
static VALUE buf_to_str(VALUE self) {
|
116
|
-
struct buf_int* b;
|
117
|
-
Data_Get_Struct(self, struct buf_int, b);
|
118
|
-
|
119
|
-
return rb_str_new((const char*)(b->top), b->cur - b->top);
|
120
|
-
}
|
121
|
-
|
122
|
-
static VALUE buf_used(VALUE self) {
|
123
|
-
struct buf_int* b;
|
124
|
-
Data_Get_Struct(self, struct buf_int, b);
|
125
|
-
|
126
|
-
return INT2FIX(b->cur - b->top);
|
127
|
-
}
|
128
|
-
|
129
|
-
static VALUE buf_capa(VALUE self) {
|
130
|
-
struct buf_int* b;
|
131
|
-
Data_Get_Struct(self, struct buf_int, b);
|
132
|
-
|
133
|
-
return INT2FIX(b->size);
|
134
|
-
}
|
135
|
-
|
136
|
-
static VALUE buf_reset(VALUE self) {
|
137
|
-
struct buf_int* b;
|
138
|
-
Data_Get_Struct(self, struct buf_int, b);
|
139
|
-
|
140
|
-
b->cur = b->top;
|
141
|
-
return self;
|
142
|
-
}
|
143
|
-
|
144
|
-
void Init_io_buffer(VALUE puma) {
|
145
|
-
VALUE buf = rb_define_class_under(puma, "IOBuffer", rb_cObject);
|
146
|
-
|
147
|
-
rb_define_alloc_func(buf, buf_alloc);
|
148
|
-
rb_define_method(buf, "<<", buf_append, 1);
|
149
|
-
rb_define_method(buf, "append", buf_append2, -1);
|
150
|
-
rb_define_method(buf, "to_str", buf_to_str, 0);
|
151
|
-
rb_define_method(buf, "to_s", buf_to_str, 0);
|
152
|
-
rb_define_method(buf, "used", buf_used, 0);
|
153
|
-
rb_define_method(buf, "capacity", buf_capa, 0);
|
154
|
-
rb_define_method(buf, "reset", buf_reset, 0);
|
155
|
-
}
|
@@ -1,72 +0,0 @@
|
|
1
|
-
package org.jruby.puma;
|
2
|
-
|
3
|
-
import org.jruby.*;
|
4
|
-
import org.jruby.anno.JRubyMethod;
|
5
|
-
import org.jruby.runtime.ObjectAllocator;
|
6
|
-
import org.jruby.runtime.ThreadContext;
|
7
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
8
|
-
import org.jruby.util.ByteList;
|
9
|
-
|
10
|
-
/**
|
11
|
-
* @author kares
|
12
|
-
*/
|
13
|
-
public class IOBuffer extends RubyObject {
|
14
|
-
|
15
|
-
private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
16
|
-
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
17
|
-
return new IOBuffer(runtime, klass);
|
18
|
-
}
|
19
|
-
};
|
20
|
-
|
21
|
-
public static void createIOBuffer(Ruby runtime) {
|
22
|
-
RubyModule mPuma = runtime.defineModule("Puma");
|
23
|
-
RubyClass cIOBuffer = mPuma.defineClassUnder("IOBuffer", runtime.getObject(), ALLOCATOR);
|
24
|
-
cIOBuffer.defineAnnotatedMethods(IOBuffer.class);
|
25
|
-
}
|
26
|
-
|
27
|
-
private static final int DEFAULT_SIZE = 4096;
|
28
|
-
|
29
|
-
final ByteList buffer = new ByteList(DEFAULT_SIZE);
|
30
|
-
|
31
|
-
IOBuffer(Ruby runtime, RubyClass klass) {
|
32
|
-
super(runtime, klass);
|
33
|
-
}
|
34
|
-
|
35
|
-
@JRubyMethod
|
36
|
-
public RubyInteger used(ThreadContext context) {
|
37
|
-
return context.runtime.newFixnum(buffer.getRealSize());
|
38
|
-
}
|
39
|
-
|
40
|
-
@JRubyMethod
|
41
|
-
public RubyInteger capacity(ThreadContext context) {
|
42
|
-
return context.runtime.newFixnum(buffer.unsafeBytes().length);
|
43
|
-
}
|
44
|
-
|
45
|
-
@JRubyMethod
|
46
|
-
public IRubyObject reset() {
|
47
|
-
buffer.setRealSize(0);
|
48
|
-
return this;
|
49
|
-
}
|
50
|
-
|
51
|
-
@JRubyMethod(name = { "to_s", "to_str" })
|
52
|
-
public RubyString to_s(ThreadContext context) {
|
53
|
-
return RubyString.newStringShared(context.runtime, buffer.unsafeBytes(), 0, buffer.getRealSize());
|
54
|
-
}
|
55
|
-
|
56
|
-
@JRubyMethod(name = "<<")
|
57
|
-
public IRubyObject add(IRubyObject str) {
|
58
|
-
addImpl(str.convertToString());
|
59
|
-
return this;
|
60
|
-
}
|
61
|
-
|
62
|
-
@JRubyMethod(rest = true)
|
63
|
-
public IRubyObject append(IRubyObject[] strs) {
|
64
|
-
for (IRubyObject str : strs) addImpl(str.convertToString());
|
65
|
-
return this;
|
66
|
-
}
|
67
|
-
|
68
|
-
private void addImpl(RubyString str) {
|
69
|
-
buffer.append(str.getByteList());
|
70
|
-
}
|
71
|
-
|
72
|
-
}
|