mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
IOBuffer back to Ruby (#1980)
This commit is contained in:
parent
a647a9a733
commit
510f39d330
8 changed files with 18 additions and 241 deletions
|
@ -19,6 +19,7 @@
|
||||||
* Remove unused loader argument from Plugin initializer (#2095)
|
* Remove unused loader argument from Plugin initializer (#2095)
|
||||||
* Simplify `Configuration.random_token` and remove insecure fallback (#2102)
|
* Simplify `Configuration.random_token` and remove insecure fallback (#2102)
|
||||||
* Simplify `Runner#start_control` URL parsing (#2111)
|
* Simplify `Runner#start_control` URL parsing (#2111)
|
||||||
|
* Removed the IOBuffer extension and replaced with Ruby (#1980)
|
||||||
|
|
||||||
## 4.3.2 and 3.12.3 / 2020-02-27
|
## 4.3.2 and 3.12.3 / 2020-02-27
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package puma;
|
package puma;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.jruby.Ruby;
|
import org.jruby.Ruby;
|
||||||
import org.jruby.runtime.load.BasicLibraryService;
|
import org.jruby.runtime.load.BasicLibraryService;
|
||||||
|
|
||||||
|
@ -9,10 +9,9 @@ import org.jruby.puma.Http11;
|
||||||
import org.jruby.puma.IOBuffer;
|
import org.jruby.puma.IOBuffer;
|
||||||
import org.jruby.puma.MiniSSL;
|
import org.jruby.puma.MiniSSL;
|
||||||
|
|
||||||
public class PumaHttp11Service implements BasicLibraryService {
|
public class PumaHttp11Service implements BasicLibraryService {
|
||||||
public boolean basicLoad(final Ruby runtime) throws IOException {
|
public boolean basicLoad(final Ruby runtime) throws IOException {
|
||||||
Http11.createHttp11(runtime);
|
Http11.createHttp11(runtime);
|
||||||
IOBuffer.createIOBuffer(runtime);
|
|
||||||
MiniSSL.createMiniSSL(runtime);
|
MiniSSL.createMiniSSL(runtime);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
#define RSTRING_NOT_MODIFIED 1
|
|
||||||
#include "ruby.h"
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
struct buf_int {
|
|
||||||
uint8_t* top;
|
|
||||||
uint8_t* cur;
|
|
||||||
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BUF_DEFAULT_SIZE 4096
|
|
||||||
#define BUF_TOLERANCE 32
|
|
||||||
|
|
||||||
static void buf_free(struct buf_int* internal) {
|
|
||||||
xfree(internal->top);
|
|
||||||
xfree(internal);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE buf_alloc(VALUE self) {
|
|
||||||
VALUE buf;
|
|
||||||
struct buf_int* internal;
|
|
||||||
|
|
||||||
buf = Data_Make_Struct(self, struct buf_int, 0, buf_free, internal);
|
|
||||||
|
|
||||||
internal->size = BUF_DEFAULT_SIZE;
|
|
||||||
internal->top = ALLOC_N(uint8_t, BUF_DEFAULT_SIZE);
|
|
||||||
internal->cur = internal->top;
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE buf_append(VALUE self, VALUE str) {
|
|
||||||
struct buf_int* b;
|
|
||||||
size_t used, str_len, new_size;
|
|
||||||
|
|
||||||
Data_Get_Struct(self, struct buf_int, b);
|
|
||||||
|
|
||||||
used = b->cur - b->top;
|
|
||||||
|
|
||||||
StringValue(str);
|
|
||||||
str_len = RSTRING_LEN(str);
|
|
||||||
|
|
||||||
new_size = used + str_len;
|
|
||||||
|
|
||||||
if(new_size > b->size) {
|
|
||||||
size_t n = b->size + (b->size / 2);
|
|
||||||
uint8_t* top;
|
|
||||||
uint8_t* old;
|
|
||||||
|
|
||||||
new_size = (n > new_size ? n : new_size + BUF_TOLERANCE);
|
|
||||||
|
|
||||||
top = ALLOC_N(uint8_t, new_size);
|
|
||||||
old = b->top;
|
|
||||||
memcpy(top, old, used);
|
|
||||||
b->top = top;
|
|
||||||
b->cur = top + used;
|
|
||||||
b->size = new_size;
|
|
||||||
xfree(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(b->cur, RSTRING_PTR(str), str_len);
|
|
||||||
b->cur += str_len;
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE buf_append2(int argc, VALUE* argv, VALUE self) {
|
|
||||||
struct buf_int* b;
|
|
||||||
size_t used, new_size;
|
|
||||||
int i;
|
|
||||||
VALUE str;
|
|
||||||
|
|
||||||
Data_Get_Struct(self, struct buf_int, b);
|
|
||||||
|
|
||||||
used = b->cur - b->top;
|
|
||||||
new_size = used;
|
|
||||||
|
|
||||||
for(i = 0; i < argc; i++) {
|
|
||||||
StringValue(argv[i]);
|
|
||||||
|
|
||||||
str = argv[i];
|
|
||||||
|
|
||||||
new_size += RSTRING_LEN(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(new_size > b->size) {
|
|
||||||
size_t n = b->size + (b->size / 2);
|
|
||||||
uint8_t* top;
|
|
||||||
uint8_t* old;
|
|
||||||
|
|
||||||
new_size = (n > new_size ? n : new_size + BUF_TOLERANCE);
|
|
||||||
|
|
||||||
top = ALLOC_N(uint8_t, new_size);
|
|
||||||
old = b->top;
|
|
||||||
memcpy(top, old, used);
|
|
||||||
b->top = top;
|
|
||||||
b->cur = top + used;
|
|
||||||
b->size = new_size;
|
|
||||||
xfree(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < argc; i++) {
|
|
||||||
long str_len;
|
|
||||||
str = argv[i];
|
|
||||||
str_len = RSTRING_LEN(str);
|
|
||||||
memcpy(b->cur, RSTRING_PTR(str), str_len);
|
|
||||||
b->cur += str_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE buf_to_str(VALUE self) {
|
|
||||||
struct buf_int* b;
|
|
||||||
Data_Get_Struct(self, struct buf_int, b);
|
|
||||||
|
|
||||||
return rb_str_new((const char*)(b->top), b->cur - b->top);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE buf_used(VALUE self) {
|
|
||||||
struct buf_int* b;
|
|
||||||
Data_Get_Struct(self, struct buf_int, b);
|
|
||||||
|
|
||||||
return INT2FIX(b->cur - b->top);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE buf_capa(VALUE self) {
|
|
||||||
struct buf_int* b;
|
|
||||||
Data_Get_Struct(self, struct buf_int, b);
|
|
||||||
|
|
||||||
return INT2FIX(b->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE buf_reset(VALUE self) {
|
|
||||||
struct buf_int* b;
|
|
||||||
Data_Get_Struct(self, struct buf_int, b);
|
|
||||||
|
|
||||||
b->cur = b->top;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init_io_buffer(VALUE puma) {
|
|
||||||
VALUE buf = rb_define_class_under(puma, "IOBuffer", rb_cObject);
|
|
||||||
|
|
||||||
rb_define_alloc_func(buf, buf_alloc);
|
|
||||||
rb_define_method(buf, "<<", buf_append, 1);
|
|
||||||
rb_define_method(buf, "append", buf_append2, -1);
|
|
||||||
rb_define_method(buf, "to_str", buf_to_str, 0);
|
|
||||||
rb_define_method(buf, "to_s", buf_to_str, 0);
|
|
||||||
rb_define_method(buf, "used", buf_used, 0);
|
|
||||||
rb_define_method(buf, "capacity", buf_capa, 0);
|
|
||||||
rb_define_method(buf, "reset", buf_reset, 0);
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package org.jruby.puma;
|
|
||||||
|
|
||||||
import org.jruby.*;
|
|
||||||
import org.jruby.anno.JRubyMethod;
|
|
||||||
import org.jruby.runtime.ObjectAllocator;
|
|
||||||
import org.jruby.runtime.ThreadContext;
|
|
||||||
import org.jruby.runtime.builtin.IRubyObject;
|
|
||||||
import org.jruby.util.ByteList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author kares
|
|
||||||
*/
|
|
||||||
public class IOBuffer extends RubyObject {
|
|
||||||
|
|
||||||
private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
|
|
||||||
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
|
||||||
return new IOBuffer(runtime, klass);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static void createIOBuffer(Ruby runtime) {
|
|
||||||
RubyModule mPuma = runtime.defineModule("Puma");
|
|
||||||
RubyClass cIOBuffer = mPuma.defineClassUnder("IOBuffer", runtime.getObject(), ALLOCATOR);
|
|
||||||
cIOBuffer.defineAnnotatedMethods(IOBuffer.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int DEFAULT_SIZE = 4096;
|
|
||||||
|
|
||||||
final ByteList buffer = new ByteList(DEFAULT_SIZE);
|
|
||||||
|
|
||||||
IOBuffer(Ruby runtime, RubyClass klass) {
|
|
||||||
super(runtime, klass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@JRubyMethod
|
|
||||||
public RubyInteger used(ThreadContext context) {
|
|
||||||
return context.runtime.newFixnum(buffer.getRealSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
@JRubyMethod
|
|
||||||
public RubyInteger capacity(ThreadContext context) {
|
|
||||||
return context.runtime.newFixnum(buffer.unsafeBytes().length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@JRubyMethod
|
|
||||||
public IRubyObject reset() {
|
|
||||||
buffer.setRealSize(0);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JRubyMethod(name = { "to_s", "to_str" })
|
|
||||||
public RubyString to_s(ThreadContext context) {
|
|
||||||
return RubyString.newStringShared(context.runtime, buffer.unsafeBytes(), 0, buffer.getRealSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
@JRubyMethod(name = "<<")
|
|
||||||
public IRubyObject add(IRubyObject str) {
|
|
||||||
addImpl(str.convertToString());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JRubyMethod(rest = true)
|
|
||||||
public IRubyObject append(IRubyObject[] strs) {
|
|
||||||
for (IRubyObject str : strs) addImpl(str.convertToString());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addImpl(RubyString str) {
|
|
||||||
buffer.append(str.getByteList());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -434,7 +434,6 @@ VALUE HttpParser_body(VALUE self) {
|
||||||
return http->body;
|
return http->body;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init_io_buffer(VALUE puma);
|
|
||||||
void Init_mini_ssl(VALUE mod);
|
void Init_mini_ssl(VALUE mod);
|
||||||
|
|
||||||
void Init_puma_http11()
|
void Init_puma_http11()
|
||||||
|
@ -464,6 +463,5 @@ void Init_puma_http11()
|
||||||
rb_define_method(cHttpParser, "body", HttpParser_body, 0);
|
rb_define_method(cHttpParser, "body", HttpParser_body, 0);
|
||||||
init_common_fields();
|
init_common_fields();
|
||||||
|
|
||||||
Init_io_buffer(mPuma);
|
|
||||||
Init_mini_ssl(mPuma);
|
Init_mini_ssl(mPuma);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'puma/detect'
|
module Puma
|
||||||
require 'puma/puma_http11'
|
class IOBuffer < String
|
||||||
|
def append(*args)
|
||||||
|
args.each { |a| concat(a) }
|
||||||
|
end
|
||||||
|
|
||||||
|
alias reset clear
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -11,6 +11,7 @@ require 'puma/client'
|
||||||
require 'puma/binder'
|
require 'puma/binder'
|
||||||
require 'puma/accept_nonblock'
|
require 'puma/accept_nonblock'
|
||||||
require 'puma/util'
|
require 'puma/util'
|
||||||
|
require 'puma/io_buffer'
|
||||||
|
|
||||||
require 'puma/puma_http11'
|
require 'puma/puma_http11'
|
||||||
|
|
||||||
|
@ -297,7 +298,7 @@ module Puma
|
||||||
|
|
||||||
@thread_pool = ThreadPool.new(@min_threads,
|
@thread_pool = ThreadPool.new(@min_threads,
|
||||||
@max_threads,
|
@max_threads,
|
||||||
IOBuffer) do |client, buffer|
|
::Puma::IOBuffer) do |client, buffer|
|
||||||
|
|
||||||
# Advertise this server into the thread
|
# Advertise this server into the thread
|
||||||
Thread.current[ThreadLocalKey] = self
|
Thread.current[ThreadLocalKey] = self
|
||||||
|
|
|
@ -9,8 +9,7 @@ class TestIOBuffer < Minitest::Test
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_initial_size
|
def test_initial_size
|
||||||
assert_equal 0, iobuf.used
|
assert_equal 0, iobuf.size
|
||||||
assert iobuf.capacity > 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_append_op
|
def test_append_op
|
||||||
|
@ -18,22 +17,21 @@ class TestIOBuffer < Minitest::Test
|
||||||
assert_equal "abc", iobuf.to_s
|
assert_equal "abc", iobuf.to_s
|
||||||
iobuf << "123"
|
iobuf << "123"
|
||||||
assert_equal "abc123", iobuf.to_s
|
assert_equal "abc123", iobuf.to_s
|
||||||
assert_equal 6, iobuf.used
|
assert_equal 6, iobuf.size
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_append
|
def test_append
|
||||||
expected = "mary had a little lamb"
|
expected = "mary had a little lamb"
|
||||||
iobuf.append("mary", " ", "had ", "a little", " lamb")
|
iobuf.append("mary", " ", "had ", "a little", " lamb")
|
||||||
assert_equal expected, iobuf.to_s
|
assert_equal expected, iobuf.to_s
|
||||||
assert_equal expected.length, iobuf.used
|
assert_equal expected.length, iobuf.size
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_reset
|
def test_reset
|
||||||
iobuf << "content"
|
iobuf << "content"
|
||||||
assert_equal "content", iobuf.to_s
|
assert_equal "content", iobuf.to_s
|
||||||
iobuf.reset
|
iobuf.reset
|
||||||
assert_equal 0, iobuf.used
|
assert_equal 0, iobuf.size
|
||||||
assert_equal "", iobuf.to_s
|
assert_equal "", iobuf.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue