puma 1.6.3 → 2.0.0.b1
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.
- data/History.txt +13 -0
- data/Manifest.txt +18 -0
- data/Rakefile +6 -0
- data/docs/config.md +0 -0
- data/docs/nginx.md +85 -0
- data/examples/puma/keystore.jks +0 -0
- data/ext/puma_http11/PumaHttp11Service.java +2 -0
- data/ext/puma_http11/extconf.rb +3 -0
- data/ext/puma_http11/io_buffer.c +146 -0
- data/ext/puma_http11/mini_ssl.c +189 -0
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +289 -0
- data/ext/puma_http11/puma_http11.c +6 -0
- data/lib/puma/accept_nonblock.rb +23 -0
- data/lib/puma/binder.rb +253 -0
- data/lib/puma/cli.rb +212 -114
- data/lib/puma/client.rb +28 -3
- data/lib/puma/configuration.rb +11 -4
- data/lib/puma/const.rb +12 -1
- data/lib/puma/delegation.rb +11 -0
- data/lib/puma/events.rb +18 -0
- data/lib/puma/io_buffer.rb +7 -0
- data/lib/puma/java_io_buffer.rb +45 -0
- data/lib/puma/minissl.rb +124 -0
- data/lib/puma/puma_http11.bundle +0 -0
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/reactor.rb +4 -1
- data/lib/puma/server.rb +67 -144
- data/lib/puma/thread_pool.rb +5 -2
- data/puma.gemspec +5 -5
- data/test/test_integration.rb +53 -2
- data/test/test_iobuffer.rb +38 -0
- data/test/test_puma_server.rb +12 -7
- data/tools/jungle/README.md +54 -0
- data/tools/jungle/puma +332 -0
- data/tools/jungle/run-puma +3 -0
- metadata +24 -5
data/History.txt
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
=== 2.0.0.b1 / 2012-09-11
|
2
|
+
|
3
|
+
* 1 major feature:
|
4
|
+
* Optional worker process mode (-w) to allow for process scaling in
|
5
|
+
addition to thread scaling
|
6
|
+
|
7
|
+
* 1 bug fix:
|
8
|
+
* Introduce Puma::MiniSSL to be able to properly control doing
|
9
|
+
nonblocking SSL
|
10
|
+
|
11
|
+
NOTE: SSL support in JRuby is not supported at present. Support will
|
12
|
+
be added back in a future date when a java Puma::MiniSSL is added.
|
13
|
+
|
1
14
|
=== 1.6.3 / 2012-09-04
|
2
15
|
|
3
16
|
* 1 bug fix:
|
data/Manifest.txt
CHANGED
@@ -9,6 +9,8 @@ Rakefile
|
|
9
9
|
TODO
|
10
10
|
bin/puma
|
11
11
|
bin/pumactl
|
12
|
+
docs/config.md
|
13
|
+
docs/nginx.md
|
12
14
|
examples/CA/cacert.pem
|
13
15
|
examples/CA/newcerts/cert_1.pem
|
14
16
|
examples/CA/newcerts/cert_2.pem
|
@@ -17,6 +19,7 @@ examples/CA/serial
|
|
17
19
|
examples/config.rb
|
18
20
|
examples/puma/cert_puma.pem
|
19
21
|
examples/puma/csr_puma.pem
|
22
|
+
examples/puma/keystore.jks
|
20
23
|
examples/puma/puma_keypair.pem
|
21
24
|
examples/qc_config.rb
|
22
25
|
ext/puma_http11/PumaHttp11Service.java
|
@@ -27,21 +30,32 @@ ext/puma_http11/http11_parser.h
|
|
27
30
|
ext/puma_http11/http11_parser.java.rl
|
28
31
|
ext/puma_http11/http11_parser.rl
|
29
32
|
ext/puma_http11/http11_parser_common.rl
|
33
|
+
ext/puma_http11/io_buffer.c
|
34
|
+
ext/puma_http11/mini_ssl.c
|
30
35
|
ext/puma_http11/org/jruby/puma/Http11.java
|
31
36
|
ext/puma_http11/org/jruby/puma/Http11Parser.java
|
37
|
+
ext/puma_http11/org/jruby/puma/MiniSSL.java
|
32
38
|
ext/puma_http11/puma_http11.c
|
33
39
|
lib/puma.rb
|
40
|
+
lib/puma/accept_nonblock.rb
|
34
41
|
lib/puma/app/status.rb
|
42
|
+
lib/puma/binder.rb
|
35
43
|
lib/puma/cli.rb
|
36
44
|
lib/puma/client.rb
|
37
45
|
lib/puma/compat.rb
|
38
46
|
lib/puma/configuration.rb
|
39
47
|
lib/puma/const.rb
|
40
48
|
lib/puma/control_cli.rb
|
49
|
+
lib/puma/delegation.rb
|
41
50
|
lib/puma/detect.rb
|
42
51
|
lib/puma/events.rb
|
52
|
+
lib/puma/io_buffer.rb
|
53
|
+
lib/puma/java_io_buffer.rb
|
43
54
|
lib/puma/jruby_restart.rb
|
55
|
+
lib/puma/minissl.rb
|
44
56
|
lib/puma/null_io.rb
|
57
|
+
lib/puma/puma_http11.bundle
|
58
|
+
lib/puma/puma_http11.jar
|
45
59
|
lib/puma/rack_patch.rb
|
46
60
|
lib/puma/reactor.rb
|
47
61
|
lib/puma/server.rb
|
@@ -61,6 +75,7 @@ test/test_config.rb
|
|
61
75
|
test/test_http10.rb
|
62
76
|
test/test_http11.rb
|
63
77
|
test/test_integration.rb
|
78
|
+
test/test_iobuffer.rb
|
64
79
|
test/test_null_io.rb
|
65
80
|
test/test_persistent.rb
|
66
81
|
test/test_puma_server.rb
|
@@ -70,4 +85,7 @@ test/test_thread_pool.rb
|
|
70
85
|
test/test_unix_socket.rb
|
71
86
|
test/test_ws.rb
|
72
87
|
test/testhelp.rb
|
88
|
+
tools/jungle/README.md
|
89
|
+
tools/jungle/puma
|
90
|
+
tools/jungle/run-puma
|
73
91
|
tools/trickletest.rb
|
data/Rakefile
CHANGED
@@ -60,6 +60,8 @@ file 'ext/puma_http11/org/jruby/puma/Http11Parser.java' => ['ext/puma_http11/htt
|
|
60
60
|
end
|
61
61
|
task :ragel => ['ext/puma_http11/org/jruby/puma/Http11Parser.java']
|
62
62
|
|
63
|
+
if !IS_JRUBY
|
64
|
+
|
63
65
|
# compile extensions using rake-compiler
|
64
66
|
# C (MRI, Rubinius)
|
65
67
|
Rake::ExtensionTask.new("puma_http11", HOE.spec) do |ext|
|
@@ -77,11 +79,15 @@ Rake::ExtensionTask.new("puma_http11", HOE.spec) do |ext|
|
|
77
79
|
CLEAN.include "lib/puma/puma_http11.rb"
|
78
80
|
end
|
79
81
|
|
82
|
+
else
|
83
|
+
|
80
84
|
# Java (JRuby)
|
81
85
|
Rake::JavaExtensionTask.new("puma_http11", HOE.spec) do |ext|
|
82
86
|
ext.lib_dir = "lib/puma"
|
83
87
|
end
|
84
88
|
|
89
|
+
end
|
90
|
+
|
85
91
|
# the following is a fat-binary stub that will be used when
|
86
92
|
# require 'puma/puma_http11' and will use either 1.8 or 1.9 version depending
|
87
93
|
# on RUBY_VERSION
|
data/docs/config.md
ADDED
File without changes
|
data/docs/nginx.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Nginx configuration example file
|
2
|
+
|
3
|
+
This is a very common setup using an upstream. It was adapted from some Capistrano recipe I found on the Internet a while ago.
|
4
|
+
|
5
|
+
```
|
6
|
+
upstream myapp {
|
7
|
+
server unix:///myapp/tmp/puma.sock;
|
8
|
+
}
|
9
|
+
|
10
|
+
server {
|
11
|
+
listen 80;
|
12
|
+
server_name myapp.com;
|
13
|
+
|
14
|
+
# ~2 seconds is often enough for most folks to parse HTML/CSS and
|
15
|
+
# retrieve needed images/icons/frames, connections are cheap in
|
16
|
+
# nginx so increasing this is generally safe...
|
17
|
+
keepalive_timeout 5;
|
18
|
+
|
19
|
+
# path for static files
|
20
|
+
root /myapp/public;
|
21
|
+
access_log /myapp/log/nginx.access.log;
|
22
|
+
error_log /myapp/log/nginx.error.log info;
|
23
|
+
|
24
|
+
# this rewrites all the requests to the maintenance.html
|
25
|
+
# page if it exists in the doc root. This is for capistrano's
|
26
|
+
# disable web task
|
27
|
+
if (-f $document_root/maintenance.html) {
|
28
|
+
rewrite ^(.*)$ /maintenance.html last;
|
29
|
+
break;
|
30
|
+
}
|
31
|
+
|
32
|
+
location / {
|
33
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
34
|
+
proxy_set_header Host $http_host;
|
35
|
+
|
36
|
+
# If the file exists as a static file serve it directly without
|
37
|
+
# running all the other rewite tests on it
|
38
|
+
if (-f $request_filename) {
|
39
|
+
break;
|
40
|
+
}
|
41
|
+
|
42
|
+
# check for index.html for directory index
|
43
|
+
# if its there on the filesystem then rewite
|
44
|
+
# the url to add /index.html to the end of it
|
45
|
+
# and then break to send it to the next config rules.
|
46
|
+
if (-f $request_filename/index.html) {
|
47
|
+
rewrite (.*) $1/index.html break;
|
48
|
+
}
|
49
|
+
|
50
|
+
# this is the meat of the rack page caching config
|
51
|
+
# it adds .html to the end of the url and then checks
|
52
|
+
# the filesystem for that file. If it exists, then we
|
53
|
+
# rewite the url to have explicit .html on the end
|
54
|
+
# and then send it on its way to the next config rule.
|
55
|
+
# if there is no file on the fs then it sets all the
|
56
|
+
# necessary headers and proxies to our upstream mongrels
|
57
|
+
if (-f $request_filename.html) {
|
58
|
+
rewrite (.*) $1.html break;
|
59
|
+
}
|
60
|
+
|
61
|
+
if (!-f $request_filename) {
|
62
|
+
proxy_pass http://myapp;
|
63
|
+
break;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
# Now this supposedly should work as it gets the filenames with querystrings that Rails provides.
|
68
|
+
# BUT there's a chance it could break the ajax calls.
|
69
|
+
location ~* \.(ico|css|gif|jpe?g|png)(\?[0-9]+)?$ {
|
70
|
+
expires max;
|
71
|
+
break;
|
72
|
+
}
|
73
|
+
|
74
|
+
location ~ ^/javascripts/.*\.js(\?[0-9]+)?$ {
|
75
|
+
expires max;
|
76
|
+
break;
|
77
|
+
}
|
78
|
+
|
79
|
+
# Error pages
|
80
|
+
# error_page 500 502 503 504 /500.html;
|
81
|
+
location = /500.html {
|
82
|
+
root /myapp/current/public;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
```
|
Binary file
|
@@ -6,10 +6,12 @@ import org.jruby.Ruby;
|
|
6
6
|
import org.jruby.runtime.load.BasicLibraryService;
|
7
7
|
|
8
8
|
import org.jruby.puma.Http11;
|
9
|
+
import org.jruby.puma.MiniSSL;
|
9
10
|
|
10
11
|
public class PumaHttp11Service implements BasicLibraryService {
|
11
12
|
public boolean basicLoad(final Ruby runtime) throws IOException {
|
12
13
|
Http11.createHttp11(runtime);
|
14
|
+
MiniSSL.createMiniSSL(runtime);
|
13
15
|
return true;
|
14
16
|
}
|
15
17
|
}
|
data/ext/puma_http11/extconf.rb
CHANGED
@@ -0,0 +1,146 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
#include <sys/types.h>
|
4
|
+
|
5
|
+
struct buf_int {
|
6
|
+
uint8_t* top;
|
7
|
+
uint8_t* cur;
|
8
|
+
|
9
|
+
size_t size;
|
10
|
+
};
|
11
|
+
|
12
|
+
#define BUF_DEFAULT_SIZE 4096
|
13
|
+
#define BUF_TOLERANCE 32
|
14
|
+
|
15
|
+
static void buf_free(struct buf_int* internal) {
|
16
|
+
free(internal->top);
|
17
|
+
free(internal);
|
18
|
+
}
|
19
|
+
|
20
|
+
static VALUE buf_alloc(VALUE self) {
|
21
|
+
VALUE buf;
|
22
|
+
struct buf_int* internal;
|
23
|
+
|
24
|
+
buf = Data_Make_Struct(self, struct buf_int, 0, buf_free, internal);
|
25
|
+
|
26
|
+
internal->size = BUF_DEFAULT_SIZE;
|
27
|
+
internal->top = malloc(BUF_DEFAULT_SIZE);
|
28
|
+
internal->cur = internal->top;
|
29
|
+
|
30
|
+
return buf;
|
31
|
+
}
|
32
|
+
|
33
|
+
static VALUE buf_append(VALUE self, VALUE str) {
|
34
|
+
struct buf_int* b;
|
35
|
+
size_t used, str_len, new_size;
|
36
|
+
|
37
|
+
Data_Get_Struct(self, struct buf_int, b);
|
38
|
+
|
39
|
+
used = b->cur - b->top;
|
40
|
+
|
41
|
+
StringValue(str);
|
42
|
+
str_len = RSTRING_LEN(str);
|
43
|
+
|
44
|
+
new_size = used + str_len;
|
45
|
+
|
46
|
+
if(new_size > b->size) {
|
47
|
+
size_t n = b->size + (b->size / 2);
|
48
|
+
uint8_t* top;
|
49
|
+
|
50
|
+
new_size = (n > new_size ? n : new_size + BUF_TOLERANCE);
|
51
|
+
|
52
|
+
top = malloc(new_size);
|
53
|
+
memcpy(top, b->top, used);
|
54
|
+
b->top = top;
|
55
|
+
b->cur = top + used;
|
56
|
+
b->size = new_size;
|
57
|
+
}
|
58
|
+
|
59
|
+
memcpy(b->cur, RSTRING_PTR(str), str_len);
|
60
|
+
b->cur += str_len;
|
61
|
+
|
62
|
+
return self;
|
63
|
+
}
|
64
|
+
|
65
|
+
static VALUE buf_append2(int argc, VALUE* argv, VALUE self) {
|
66
|
+
struct buf_int* b;
|
67
|
+
size_t used, new_size;
|
68
|
+
int i;
|
69
|
+
VALUE str;
|
70
|
+
|
71
|
+
Data_Get_Struct(self, struct buf_int, b);
|
72
|
+
|
73
|
+
used = b->cur - b->top;
|
74
|
+
new_size = used;
|
75
|
+
|
76
|
+
for(i = 0; i < argc; i++) {
|
77
|
+
StringValue(argv[i]);
|
78
|
+
|
79
|
+
str = argv[i];
|
80
|
+
|
81
|
+
new_size += RSTRING_LEN(str);
|
82
|
+
}
|
83
|
+
|
84
|
+
if(new_size > b->size) {
|
85
|
+
size_t n = b->size + (b->size / 2);
|
86
|
+
uint8_t* top;
|
87
|
+
|
88
|
+
new_size = (n > new_size ? n : new_size + BUF_TOLERANCE);
|
89
|
+
|
90
|
+
top = malloc(new_size);
|
91
|
+
memcpy(top, b->top, used);
|
92
|
+
b->top = top;
|
93
|
+
b->cur = top + used;
|
94
|
+
b->size = new_size;
|
95
|
+
}
|
96
|
+
|
97
|
+
for(i = 0; i < argc; i++) {
|
98
|
+
long str_len;
|
99
|
+
str = argv[i];
|
100
|
+
str_len = RSTRING_LEN(str);
|
101
|
+
memcpy(b->cur, RSTRING_PTR(str), str_len);
|
102
|
+
b->cur += str_len;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
static VALUE buf_to_str(VALUE self) {
|
107
|
+
struct buf_int* b;
|
108
|
+
Data_Get_Struct(self, struct buf_int, b);
|
109
|
+
|
110
|
+
return rb_str_new(b->top, b->cur - b->top);
|
111
|
+
}
|
112
|
+
|
113
|
+
static VALUE buf_used(VALUE self) {
|
114
|
+
struct buf_int* b;
|
115
|
+
Data_Get_Struct(self, struct buf_int, b);
|
116
|
+
|
117
|
+
return INT2FIX(b->cur - b->top);
|
118
|
+
}
|
119
|
+
|
120
|
+
static VALUE buf_capa(VALUE self) {
|
121
|
+
struct buf_int* b;
|
122
|
+
Data_Get_Struct(self, struct buf_int, b);
|
123
|
+
|
124
|
+
return INT2FIX(b->size);
|
125
|
+
}
|
126
|
+
|
127
|
+
static VALUE buf_reset(VALUE self) {
|
128
|
+
struct buf_int* b;
|
129
|
+
Data_Get_Struct(self, struct buf_int, b);
|
130
|
+
|
131
|
+
b->cur = b->top;
|
132
|
+
return self;
|
133
|
+
}
|
134
|
+
|
135
|
+
void Init_io_buffer(VALUE puma) {
|
136
|
+
VALUE buf = rb_define_class_under(puma, "IOBuffer", rb_cObject);
|
137
|
+
|
138
|
+
rb_define_alloc_func(buf, buf_alloc);
|
139
|
+
rb_define_method(buf, "<<", buf_append, 1);
|
140
|
+
rb_define_method(buf, "append", buf_append2, -1);
|
141
|
+
rb_define_method(buf, "to_str", buf_to_str, 0);
|
142
|
+
rb_define_method(buf, "to_s", buf_to_str, 0);
|
143
|
+
rb_define_method(buf, "used", buf_used, 0);
|
144
|
+
rb_define_method(buf, "capacity", buf_capa, 0);
|
145
|
+
rb_define_method(buf, "reset", buf_reset, 0);
|
146
|
+
}
|
@@ -0,0 +1,189 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <rubyio.h>
|
3
|
+
#include <openssl/bio.h>
|
4
|
+
#include <openssl/ssl.h>
|
5
|
+
#include <openssl/err.h>
|
6
|
+
|
7
|
+
typedef struct {
|
8
|
+
BIO* read;
|
9
|
+
BIO* write;
|
10
|
+
SSL* ssl;
|
11
|
+
SSL_CTX* ctx;
|
12
|
+
} ms_conn;
|
13
|
+
|
14
|
+
void engine_free(ms_conn* conn) {
|
15
|
+
BIO_free(conn->read);
|
16
|
+
BIO_free(conn->write);
|
17
|
+
|
18
|
+
free(conn);
|
19
|
+
}
|
20
|
+
|
21
|
+
ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
|
22
|
+
ms_conn* conn;
|
23
|
+
|
24
|
+
*obj = Data_Make_Struct(klass, ms_conn, 0, engine_free, conn);
|
25
|
+
|
26
|
+
conn->read = BIO_new(BIO_s_mem());
|
27
|
+
BIO_set_nbio(conn->read, 1);
|
28
|
+
|
29
|
+
conn->write = BIO_new(BIO_s_mem());
|
30
|
+
BIO_set_nbio(conn->write, 1);
|
31
|
+
|
32
|
+
conn->ssl = 0;
|
33
|
+
conn->ctx = 0;
|
34
|
+
|
35
|
+
return conn;
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE engine_init_server(VALUE self, VALUE key, VALUE cert) {
|
39
|
+
VALUE obj;
|
40
|
+
ms_conn* conn = engine_alloc(self, &obj);
|
41
|
+
|
42
|
+
StringValue(key);
|
43
|
+
StringValue(cert);
|
44
|
+
|
45
|
+
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
|
46
|
+
conn->ctx = ctx;
|
47
|
+
|
48
|
+
SSL_CTX_use_certificate_file(ctx, RSTRING_PTR(cert), SSL_FILETYPE_PEM);
|
49
|
+
SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
|
50
|
+
/* SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); */
|
51
|
+
|
52
|
+
SSL* ssl = SSL_new(ctx);
|
53
|
+
conn->ssl = ssl;
|
54
|
+
|
55
|
+
/* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
|
56
|
+
|
57
|
+
SSL_set_bio(ssl, conn->read, conn->write);
|
58
|
+
|
59
|
+
SSL_set_accept_state(ssl);
|
60
|
+
return obj;
|
61
|
+
}
|
62
|
+
|
63
|
+
VALUE engine_init_client(VALUE klass) {
|
64
|
+
VALUE obj;
|
65
|
+
ms_conn* conn = engine_alloc(klass, &obj);
|
66
|
+
|
67
|
+
conn->ctx = SSL_CTX_new(DTLSv1_method());
|
68
|
+
conn->ssl = SSL_new(conn->ctx);
|
69
|
+
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
70
|
+
|
71
|
+
SSL_set_bio(conn->ssl, conn->read, conn->write);
|
72
|
+
|
73
|
+
SSL_set_connect_state(conn->ssl);
|
74
|
+
return obj;
|
75
|
+
}
|
76
|
+
|
77
|
+
VALUE engine_inject(VALUE self, VALUE str) {
|
78
|
+
ms_conn* conn;
|
79
|
+
long used;
|
80
|
+
|
81
|
+
Data_Get_Struct(self, ms_conn, conn);
|
82
|
+
|
83
|
+
StringValue(str);
|
84
|
+
|
85
|
+
used = BIO_write(conn->read, RSTRING_PTR(str), RSTRING_LEN(str));
|
86
|
+
|
87
|
+
if(used == 0 || used == -1) {
|
88
|
+
return Qfalse;
|
89
|
+
}
|
90
|
+
|
91
|
+
return INT2FIX(used);
|
92
|
+
}
|
93
|
+
|
94
|
+
static VALUE eError;
|
95
|
+
|
96
|
+
void raise_error(SSL* ssl, int result) {
|
97
|
+
int error = SSL_get_error(ssl, result);
|
98
|
+
char* msg = ERR_error_string(error, NULL);
|
99
|
+
|
100
|
+
ERR_clear_error();
|
101
|
+
rb_raise(eError, "OpenSSL error: %s - %d", msg, error);
|
102
|
+
}
|
103
|
+
|
104
|
+
VALUE engine_read(VALUE self) {
|
105
|
+
ms_conn* conn;
|
106
|
+
char buf[512];
|
107
|
+
int bytes, n;
|
108
|
+
|
109
|
+
Data_Get_Struct(self, ms_conn, conn);
|
110
|
+
|
111
|
+
bytes = SSL_read(conn->ssl, (void*)buf, sizeof(buf));
|
112
|
+
|
113
|
+
if(bytes > 0) {
|
114
|
+
return rb_str_new(buf, bytes);
|
115
|
+
}
|
116
|
+
|
117
|
+
if(SSL_want_read(conn->ssl)) return Qnil;
|
118
|
+
|
119
|
+
if(SSL_get_error(conn->ssl, bytes) == SSL_ERROR_ZERO_RETURN) {
|
120
|
+
rb_eof_error();
|
121
|
+
}
|
122
|
+
|
123
|
+
raise_error(conn->ssl, bytes);
|
124
|
+
|
125
|
+
return Qnil;
|
126
|
+
}
|
127
|
+
|
128
|
+
VALUE engine_write(VALUE self, VALUE str) {
|
129
|
+
ms_conn* conn;
|
130
|
+
char buf[512];
|
131
|
+
int bytes;
|
132
|
+
|
133
|
+
Data_Get_Struct(self, ms_conn, conn);
|
134
|
+
|
135
|
+
StringValue(str);
|
136
|
+
|
137
|
+
bytes = SSL_write(conn->ssl, (void*)RSTRING_PTR(str), RSTRING_LEN(str));
|
138
|
+
if(bytes > 0) {
|
139
|
+
return INT2FIX(bytes);
|
140
|
+
}
|
141
|
+
|
142
|
+
if(SSL_want_write(conn->ssl)) return Qnil;
|
143
|
+
|
144
|
+
raise_error(conn->ssl, bytes);
|
145
|
+
|
146
|
+
return Qnil;
|
147
|
+
}
|
148
|
+
|
149
|
+
VALUE engine_extract(VALUE self) {
|
150
|
+
ms_conn* conn;
|
151
|
+
int bytes;
|
152
|
+
size_t pending;
|
153
|
+
char buf[512];
|
154
|
+
|
155
|
+
Data_Get_Struct(self, ms_conn, conn);
|
156
|
+
|
157
|
+
pending = BIO_pending(conn->write);
|
158
|
+
if(pending > 0) {
|
159
|
+
bytes = BIO_read(conn->write, buf, sizeof(buf));
|
160
|
+
if(bytes > 0) {
|
161
|
+
return rb_str_new(buf, bytes);
|
162
|
+
} else if(!BIO_should_retry(conn->write)) {
|
163
|
+
raise_error(conn->ssl, bytes);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
return Qnil;
|
168
|
+
}
|
169
|
+
|
170
|
+
void Init_mini_ssl(VALUE puma) {
|
171
|
+
SSL_library_init();
|
172
|
+
OpenSSL_add_ssl_algorithms();
|
173
|
+
SSL_load_error_strings();
|
174
|
+
ERR_load_crypto_strings();
|
175
|
+
|
176
|
+
VALUE mod = rb_define_module_under(puma, "MiniSSL");
|
177
|
+
VALUE eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
178
|
+
|
179
|
+
eError = rb_define_class_under(mod, "SSLError", rb_eStandardError);
|
180
|
+
|
181
|
+
rb_define_singleton_method(eng, "server", engine_init_server, 2);
|
182
|
+
rb_define_singleton_method(eng, "client", engine_init_client, 0);
|
183
|
+
|
184
|
+
rb_define_method(eng, "inject", engine_inject, 1);
|
185
|
+
rb_define_method(eng, "read", engine_read, 0);
|
186
|
+
|
187
|
+
rb_define_method(eng, "write", engine_write, 1);
|
188
|
+
rb_define_method(eng, "extract", engine_extract, 0);
|
189
|
+
}
|