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)
|
||||
* Simplify `Configuration.random_token` and remove insecure fallback (#2102)
|
||||
* 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
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package puma;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.runtime.load.BasicLibraryService;
|
||||
|
||||
|
@ -9,10 +9,9 @@ import org.jruby.puma.Http11;
|
|||
import org.jruby.puma.IOBuffer;
|
||||
import org.jruby.puma.MiniSSL;
|
||||
|
||||
public class PumaHttp11Service implements BasicLibraryService {
|
||||
public class PumaHttp11Service implements BasicLibraryService {
|
||||
public boolean basicLoad(final Ruby runtime) throws IOException {
|
||||
Http11.createHttp11(runtime);
|
||||
IOBuffer.createIOBuffer(runtime);
|
||||
MiniSSL.createMiniSSL(runtime);
|
||||
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;
|
||||
}
|
||||
|
||||
void Init_io_buffer(VALUE puma);
|
||||
void Init_mini_ssl(VALUE mod);
|
||||
|
||||
void Init_puma_http11()
|
||||
|
@ -464,6 +463,5 @@ void Init_puma_http11()
|
|||
rb_define_method(cHttpParser, "body", HttpParser_body, 0);
|
||||
init_common_fields();
|
||||
|
||||
Init_io_buffer(mPuma);
|
||||
Init_mini_ssl(mPuma);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'puma/detect'
|
||||
require 'puma/puma_http11'
|
||||
module Puma
|
||||
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/accept_nonblock'
|
||||
require 'puma/util'
|
||||
require 'puma/io_buffer'
|
||||
|
||||
require 'puma/puma_http11'
|
||||
|
||||
|
@ -297,7 +298,7 @@ module Puma
|
|||
|
||||
@thread_pool = ThreadPool.new(@min_threads,
|
||||
@max_threads,
|
||||
IOBuffer) do |client, buffer|
|
||||
::Puma::IOBuffer) do |client, buffer|
|
||||
|
||||
# Advertise this server into the thread
|
||||
Thread.current[ThreadLocalKey] = self
|
||||
|
|
|
@ -9,8 +9,7 @@ class TestIOBuffer < Minitest::Test
|
|||
end
|
||||
|
||||
def test_initial_size
|
||||
assert_equal 0, iobuf.used
|
||||
assert iobuf.capacity > 0
|
||||
assert_equal 0, iobuf.size
|
||||
end
|
||||
|
||||
def test_append_op
|
||||
|
@ -18,22 +17,21 @@ class TestIOBuffer < Minitest::Test
|
|||
assert_equal "abc", iobuf.to_s
|
||||
iobuf << "123"
|
||||
assert_equal "abc123", iobuf.to_s
|
||||
assert_equal 6, iobuf.used
|
||||
assert_equal 6, iobuf.size
|
||||
end
|
||||
|
||||
def test_append
|
||||
expected = "mary had a little lamb"
|
||||
iobuf.append("mary", " ", "had ", "a little", " lamb")
|
||||
assert_equal expected, iobuf.to_s
|
||||
assert_equal expected.length, iobuf.used
|
||||
assert_equal expected.length, iobuf.size
|
||||
end
|
||||
|
||||
def test_reset
|
||||
iobuf << "content"
|
||||
assert_equal "content", iobuf.to_s
|
||||
iobuf.reset
|
||||
assert_equal 0, iobuf.used
|
||||
assert_equal 0, iobuf.size
|
||||
assert_equal "", iobuf.to_s
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue