1584Salexander.borisov@nginx.com
2584Salexander.borisov@nginx.com /*
3584Salexander.borisov@nginx.com * Copyright (C) Alexander Borisov
4584Salexander.borisov@nginx.com * Copyright (C) NGINX, Inc.
5584Salexander.borisov@nginx.com */
6584Salexander.borisov@nginx.com
7584Salexander.borisov@nginx.com #include <ruby/nxt_ruby.h>
8743Smax.romanov@nginx.com #include <nxt_unit.h>
9584Salexander.borisov@nginx.com
10584Salexander.borisov@nginx.com
111687Smax.romanov@nginx.com static VALUE nxt_ruby_stream_io_new(VALUE class, VALUE arg);
12584Salexander.borisov@nginx.com static VALUE nxt_ruby_stream_io_initialize(int argc, VALUE *argv, VALUE self);
131337Smax.romanov@nginx.com static VALUE nxt_ruby_stream_io_gets(VALUE obj);
141337Smax.romanov@nginx.com static VALUE nxt_ruby_stream_io_each(VALUE obj);
15584Salexander.borisov@nginx.com static VALUE nxt_ruby_stream_io_read(VALUE obj, VALUE args);
161337Smax.romanov@nginx.com static VALUE nxt_ruby_stream_io_rewind(VALUE obj);
17584Salexander.borisov@nginx.com static VALUE nxt_ruby_stream_io_puts(VALUE obj, VALUE args);
18584Salexander.borisov@nginx.com static VALUE nxt_ruby_stream_io_write(VALUE obj, VALUE args);
191687Smax.romanov@nginx.com nxt_inline long nxt_ruby_stream_io_s_write(nxt_ruby_ctx_t *rctx, VALUE val);
201337Smax.romanov@nginx.com static VALUE nxt_ruby_stream_io_flush(VALUE obj);
21*2093Sz.hong@f5.com static VALUE nxt_ruby_stream_io_close(VALUE obj);
22584Salexander.borisov@nginx.com
23584Salexander.borisov@nginx.com
24584Salexander.borisov@nginx.com VALUE
nxt_ruby_stream_io_input_init(void)25584Salexander.borisov@nginx.com nxt_ruby_stream_io_input_init(void)
26584Salexander.borisov@nginx.com {
27584Salexander.borisov@nginx.com VALUE stream_io;
28584Salexander.borisov@nginx.com
291870So.canty@f5.com stream_io = rb_define_class("NGINX_Unit_Stream_IO_Read", rb_cObject);
301870So.canty@f5.com
311870So.canty@f5.com rb_undef_alloc_func(stream_io);
32584Salexander.borisov@nginx.com
33584Salexander.borisov@nginx.com rb_gc_register_address(&stream_io);
34584Salexander.borisov@nginx.com
35584Salexander.borisov@nginx.com rb_define_singleton_method(stream_io, "new", nxt_ruby_stream_io_new, 1);
361235Sigor@sysoev.ru rb_define_method(stream_io, "initialize",
371235Sigor@sysoev.ru nxt_ruby_stream_io_initialize, -1);
38584Salexander.borisov@nginx.com rb_define_method(stream_io, "gets", nxt_ruby_stream_io_gets, 0);
39584Salexander.borisov@nginx.com rb_define_method(stream_io, "each", nxt_ruby_stream_io_each, 0);
40584Salexander.borisov@nginx.com rb_define_method(stream_io, "read", nxt_ruby_stream_io_read, -2);
41584Salexander.borisov@nginx.com rb_define_method(stream_io, "rewind", nxt_ruby_stream_io_rewind, 0);
42*2093Sz.hong@f5.com rb_define_method(stream_io, "close", nxt_ruby_stream_io_close, 0);
43584Salexander.borisov@nginx.com
44584Salexander.borisov@nginx.com return stream_io;
45584Salexander.borisov@nginx.com }
46584Salexander.borisov@nginx.com
47584Salexander.borisov@nginx.com
48584Salexander.borisov@nginx.com VALUE
nxt_ruby_stream_io_error_init(void)49584Salexander.borisov@nginx.com nxt_ruby_stream_io_error_init(void)
50584Salexander.borisov@nginx.com {
51584Salexander.borisov@nginx.com VALUE stream_io;
52584Salexander.borisov@nginx.com
531870So.canty@f5.com stream_io = rb_define_class("NGINX_Unit_Stream_IO_Error", rb_cObject);
541870So.canty@f5.com
551870So.canty@f5.com rb_undef_alloc_func(stream_io);
56584Salexander.borisov@nginx.com
57584Salexander.borisov@nginx.com rb_gc_register_address(&stream_io);
58584Salexander.borisov@nginx.com
59584Salexander.borisov@nginx.com rb_define_singleton_method(stream_io, "new", nxt_ruby_stream_io_new, 1);
601235Sigor@sysoev.ru rb_define_method(stream_io, "initialize",
611235Sigor@sysoev.ru nxt_ruby_stream_io_initialize, -1);
62584Salexander.borisov@nginx.com rb_define_method(stream_io, "puts", nxt_ruby_stream_io_puts, -2);
63584Salexander.borisov@nginx.com rb_define_method(stream_io, "write", nxt_ruby_stream_io_write, -2);
64584Salexander.borisov@nginx.com rb_define_method(stream_io, "flush", nxt_ruby_stream_io_flush, 0);
65*2093Sz.hong@f5.com rb_define_method(stream_io, "close", nxt_ruby_stream_io_close, 0);
66584Salexander.borisov@nginx.com
67584Salexander.borisov@nginx.com return stream_io;
68584Salexander.borisov@nginx.com }
69584Salexander.borisov@nginx.com
70584Salexander.borisov@nginx.com
71584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_new(VALUE class,VALUE arg)721687Smax.romanov@nginx.com nxt_ruby_stream_io_new(VALUE class, VALUE arg)
73584Salexander.borisov@nginx.com {
741687Smax.romanov@nginx.com VALUE self;
75584Salexander.borisov@nginx.com
761687Smax.romanov@nginx.com self = Data_Wrap_Struct(class, 0, 0, (void *) (uintptr_t) arg);
77584Salexander.borisov@nginx.com
78584Salexander.borisov@nginx.com rb_obj_call_init(self, 0, NULL);
79584Salexander.borisov@nginx.com
80584Salexander.borisov@nginx.com return self;
81584Salexander.borisov@nginx.com }
82584Salexander.borisov@nginx.com
83584Salexander.borisov@nginx.com
84584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_initialize(int argc,VALUE * argv,VALUE self)85584Salexander.borisov@nginx.com nxt_ruby_stream_io_initialize(int argc, VALUE *argv, VALUE self)
86584Salexander.borisov@nginx.com {
87584Salexander.borisov@nginx.com return self;
88584Salexander.borisov@nginx.com }
89584Salexander.borisov@nginx.com
90584Salexander.borisov@nginx.com
91584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_gets(VALUE obj)921337Smax.romanov@nginx.com nxt_ruby_stream_io_gets(VALUE obj)
93584Salexander.borisov@nginx.com {
94743Smax.romanov@nginx.com VALUE buf;
951398Smax.romanov@nginx.com ssize_t res;
961687Smax.romanov@nginx.com nxt_ruby_ctx_t *rctx;
97743Smax.romanov@nginx.com nxt_unit_request_info_t *req;
98584Salexander.borisov@nginx.com
991687Smax.romanov@nginx.com Data_Get_Struct(obj, nxt_ruby_ctx_t, rctx);
1001687Smax.romanov@nginx.com req = rctx->req;
101743Smax.romanov@nginx.com
102743Smax.romanov@nginx.com if (req->content_length == 0) {
103584Salexander.borisov@nginx.com return Qnil;
104584Salexander.borisov@nginx.com }
105584Salexander.borisov@nginx.com
1061398Smax.romanov@nginx.com res = nxt_unit_request_readline_size(req, SSIZE_MAX);
1071398Smax.romanov@nginx.com if (nxt_slow_path(res < 0)) {
108584Salexander.borisov@nginx.com return Qnil;
109584Salexander.borisov@nginx.com }
110584Salexander.borisov@nginx.com
1111398Smax.romanov@nginx.com buf = rb_str_buf_new(res);
112743Smax.romanov@nginx.com
1131398Smax.romanov@nginx.com if (nxt_slow_path(buf == Qnil)) {
1141398Smax.romanov@nginx.com return Qnil;
1151398Smax.romanov@nginx.com }
1161398Smax.romanov@nginx.com
1171398Smax.romanov@nginx.com res = nxt_unit_request_read(req, RSTRING_PTR(buf), res);
1181398Smax.romanov@nginx.com
1191398Smax.romanov@nginx.com rb_str_set_len(buf, res);
120584Salexander.borisov@nginx.com
121584Salexander.borisov@nginx.com return buf;
122584Salexander.borisov@nginx.com }
123584Salexander.borisov@nginx.com
124584Salexander.borisov@nginx.com
125584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_each(VALUE obj)1261337Smax.romanov@nginx.com nxt_ruby_stream_io_each(VALUE obj)
127584Salexander.borisov@nginx.com {
128584Salexander.borisov@nginx.com VALUE chunk;
129584Salexander.borisov@nginx.com
130584Salexander.borisov@nginx.com if (rb_block_given_p() == 0) {
131584Salexander.borisov@nginx.com rb_raise(rb_eArgError, "Expected block on rack.input 'each' method");
132584Salexander.borisov@nginx.com }
133584Salexander.borisov@nginx.com
134584Salexander.borisov@nginx.com for ( ;; ) {
1351337Smax.romanov@nginx.com chunk = nxt_ruby_stream_io_gets(obj);
136584Salexander.borisov@nginx.com
137584Salexander.borisov@nginx.com if (chunk == Qnil) {
138584Salexander.borisov@nginx.com return Qnil;
139584Salexander.borisov@nginx.com }
140584Salexander.borisov@nginx.com
141584Salexander.borisov@nginx.com rb_yield(chunk);
142584Salexander.borisov@nginx.com }
143584Salexander.borisov@nginx.com
144584Salexander.borisov@nginx.com return Qnil;
145584Salexander.borisov@nginx.com }
146584Salexander.borisov@nginx.com
147584Salexander.borisov@nginx.com
148584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_read(VALUE obj,VALUE args)149584Salexander.borisov@nginx.com nxt_ruby_stream_io_read(VALUE obj, VALUE args)
150584Salexander.borisov@nginx.com {
1511687Smax.romanov@nginx.com VALUE buf;
1521687Smax.romanov@nginx.com long copy_size, u_size;
1531687Smax.romanov@nginx.com nxt_ruby_ctx_t *rctx;
154584Salexander.borisov@nginx.com
1551687Smax.romanov@nginx.com Data_Get_Struct(obj, nxt_ruby_ctx_t, rctx);
156584Salexander.borisov@nginx.com
1571687Smax.romanov@nginx.com copy_size = rctx->req->content_length;
158584Salexander.borisov@nginx.com
159584Salexander.borisov@nginx.com if (RARRAY_LEN(args) > 0 && TYPE(RARRAY_PTR(args)[0]) == T_FIXNUM) {
160584Salexander.borisov@nginx.com u_size = NUM2LONG(RARRAY_PTR(args)[0]);
161584Salexander.borisov@nginx.com
162584Salexander.borisov@nginx.com if (u_size < 0 || copy_size == 0) {
163584Salexander.borisov@nginx.com return Qnil;
164584Salexander.borisov@nginx.com }
165584Salexander.borisov@nginx.com
166584Salexander.borisov@nginx.com if (copy_size > u_size) {
167584Salexander.borisov@nginx.com copy_size = u_size;
168584Salexander.borisov@nginx.com }
169584Salexander.borisov@nginx.com }
170584Salexander.borisov@nginx.com
171584Salexander.borisov@nginx.com if (copy_size == 0) {
172584Salexander.borisov@nginx.com return rb_str_new_cstr("");
173584Salexander.borisov@nginx.com }
174584Salexander.borisov@nginx.com
175584Salexander.borisov@nginx.com buf = rb_str_buf_new(copy_size);
176584Salexander.borisov@nginx.com
177584Salexander.borisov@nginx.com if (nxt_slow_path(buf == Qnil)) {
178584Salexander.borisov@nginx.com return Qnil;
179584Salexander.borisov@nginx.com }
180584Salexander.borisov@nginx.com
1811687Smax.romanov@nginx.com copy_size = nxt_unit_request_read(rctx->req, RSTRING_PTR(buf), copy_size);
182584Salexander.borisov@nginx.com
183584Salexander.borisov@nginx.com if (RARRAY_LEN(args) > 1 && TYPE(RARRAY_PTR(args)[1]) == T_STRING) {
184584Salexander.borisov@nginx.com
185584Salexander.borisov@nginx.com rb_str_set_len(RARRAY_PTR(args)[1], 0);
186584Salexander.borisov@nginx.com rb_str_cat(RARRAY_PTR(args)[1], RSTRING_PTR(buf), copy_size);
187584Salexander.borisov@nginx.com }
188584Salexander.borisov@nginx.com
189743Smax.romanov@nginx.com rb_str_set_len(buf, copy_size);
190584Salexander.borisov@nginx.com
191584Salexander.borisov@nginx.com return buf;
192584Salexander.borisov@nginx.com }
193584Salexander.borisov@nginx.com
194584Salexander.borisov@nginx.com
195584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_rewind(VALUE obj)1961337Smax.romanov@nginx.com nxt_ruby_stream_io_rewind(VALUE obj)
197584Salexander.borisov@nginx.com {
198584Salexander.borisov@nginx.com return Qnil;
199584Salexander.borisov@nginx.com }
200584Salexander.borisov@nginx.com
201584Salexander.borisov@nginx.com
202584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_puts(VALUE obj,VALUE args)203584Salexander.borisov@nginx.com nxt_ruby_stream_io_puts(VALUE obj, VALUE args)
204584Salexander.borisov@nginx.com {
2051687Smax.romanov@nginx.com nxt_ruby_ctx_t *rctx;
206584Salexander.borisov@nginx.com
207584Salexander.borisov@nginx.com if (RARRAY_LEN(args) != 1) {
208584Salexander.borisov@nginx.com return Qnil;
209584Salexander.borisov@nginx.com }
210584Salexander.borisov@nginx.com
2111687Smax.romanov@nginx.com Data_Get_Struct(obj, nxt_ruby_ctx_t, rctx);
212584Salexander.borisov@nginx.com
2131687Smax.romanov@nginx.com nxt_ruby_stream_io_s_write(rctx, RARRAY_PTR(args)[0]);
214584Salexander.borisov@nginx.com
215584Salexander.borisov@nginx.com return Qnil;
216584Salexander.borisov@nginx.com }
217584Salexander.borisov@nginx.com
218584Salexander.borisov@nginx.com
219584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_write(VALUE obj,VALUE args)220584Salexander.borisov@nginx.com nxt_ruby_stream_io_write(VALUE obj, VALUE args)
221584Salexander.borisov@nginx.com {
2221687Smax.romanov@nginx.com long len;
2231687Smax.romanov@nginx.com nxt_ruby_ctx_t *rctx;
224584Salexander.borisov@nginx.com
225584Salexander.borisov@nginx.com if (RARRAY_LEN(args) != 1) {
226584Salexander.borisov@nginx.com return Qnil;
227584Salexander.borisov@nginx.com }
228584Salexander.borisov@nginx.com
2291687Smax.romanov@nginx.com Data_Get_Struct(obj, nxt_ruby_ctx_t, rctx);
230584Salexander.borisov@nginx.com
2311687Smax.romanov@nginx.com len = nxt_ruby_stream_io_s_write(rctx, RARRAY_PTR(args)[0]);
232584Salexander.borisov@nginx.com
233584Salexander.borisov@nginx.com return LONG2FIX(len);
234584Salexander.borisov@nginx.com }
235584Salexander.borisov@nginx.com
236584Salexander.borisov@nginx.com
237584Salexander.borisov@nginx.com nxt_inline long
nxt_ruby_stream_io_s_write(nxt_ruby_ctx_t * rctx,VALUE val)2381687Smax.romanov@nginx.com nxt_ruby_stream_io_s_write(nxt_ruby_ctx_t *rctx, VALUE val)
239584Salexander.borisov@nginx.com {
240584Salexander.borisov@nginx.com if (nxt_slow_path(val == Qnil)) {
241584Salexander.borisov@nginx.com return 0;
242584Salexander.borisov@nginx.com }
243584Salexander.borisov@nginx.com
244584Salexander.borisov@nginx.com if (TYPE(val) != T_STRING) {
245584Salexander.borisov@nginx.com val = rb_funcall(val, rb_intern("to_s"), 0);
246584Salexander.borisov@nginx.com
247584Salexander.borisov@nginx.com if (TYPE(val) != T_STRING) {
248584Salexander.borisov@nginx.com return 0;
249584Salexander.borisov@nginx.com }
250584Salexander.borisov@nginx.com }
251584Salexander.borisov@nginx.com
2521687Smax.romanov@nginx.com nxt_unit_req_error(rctx->req, "Ruby: %s", RSTRING_PTR(val));
253584Salexander.borisov@nginx.com
254584Salexander.borisov@nginx.com return RSTRING_LEN(val);
255584Salexander.borisov@nginx.com }
256584Salexander.borisov@nginx.com
257584Salexander.borisov@nginx.com
258584Salexander.borisov@nginx.com static VALUE
nxt_ruby_stream_io_flush(VALUE obj)2591337Smax.romanov@nginx.com nxt_ruby_stream_io_flush(VALUE obj)
260584Salexander.borisov@nginx.com {
261584Salexander.borisov@nginx.com return Qnil;
262584Salexander.borisov@nginx.com }
263*2093Sz.hong@f5.com
264*2093Sz.hong@f5.com
265*2093Sz.hong@f5.com static VALUE
nxt_ruby_stream_io_close(VALUE obj)266*2093Sz.hong@f5.com nxt_ruby_stream_io_close(VALUE obj)
267*2093Sz.hong@f5.com {
268*2093Sz.hong@f5.com return Qnil;
269*2093Sz.hong@f5.com }
270