ruby-fcgi 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.8.8
data/ext/fcgi/MANIFEST ADDED
@@ -0,0 +1,3 @@
1
+ MANIFEST
2
+ extconf.rb
3
+ fcgi.c
data/ext/fcgi/Makefile ADDED
@@ -0,0 +1,181 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ #### Start of system configuration section. ####
5
+
6
+ srcdir = /tmp/ruby-fcgi-0.8.7/ext/fcgi
7
+ topdir = /usr/include/ruby-1.9.1
8
+ hdrdir = /usr/include/ruby-1.9.1
9
+ arch_hdrdir = /usr/include/ruby-1.9.1/$(arch)
10
+ VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
11
+ prefix = $(DESTDIR)/usr
12
+ exec_prefix = $(prefix)
13
+ vendorhdrdir = $(rubyhdrdir)/vendor_ruby
14
+ sitehdrdir = $(rubyhdrdir)/site_ruby
15
+ rubyhdrdir = $(includedir)/ruby-$(ruby_version)
16
+ vendordir = $(DESTDIR)/usr/lib/ruby/vendor_ruby
17
+ sitedir = $(DESTDIR)/usr/local/lib/site_ruby
18
+ mandir = $(prefix)/share/man
19
+ localedir = $(datarootdir)/locale
20
+ libdir = $(exec_prefix)/lib
21
+ psdir = $(docdir)
22
+ pdfdir = $(docdir)
23
+ dvidir = $(docdir)
24
+ htmldir = $(docdir)
25
+ infodir = $(prefix)/share/info
26
+ docdir = $(datarootdir)/doc/$(PACKAGE)
27
+ oldincludedir = $(DESTDIR)/usr/include
28
+ includedir = $(prefix)/include
29
+ localstatedir = $(DESTDIR)/var
30
+ sharedstatedir = $(prefix)/com
31
+ sysconfdir = $(DESTDIR)/etc
32
+ datadir = $(datarootdir)
33
+ datarootdir = $(prefix)/share
34
+ libexecdir = $(prefix)/lib/ruby1.9.1
35
+ sbindir = $(exec_prefix)/sbin
36
+ bindir = $(exec_prefix)/bin
37
+ rubylibdir = $(libdir)/ruby/$(ruby_version)
38
+ archdir = $(rubylibdir)/$(arch)
39
+ sitelibdir = $(sitedir)/$(ruby_version)
40
+ sitearchdir = $(sitelibdir)/$(sitearch)
41
+ vendorlibdir = $(vendordir)/$(ruby_version)
42
+ vendorarchdir = $(vendorlibdir)/$(sitearch)
43
+
44
+ CC = cc
45
+ CXX = g++
46
+ LIBRUBY = $(LIBRUBY_SO)
47
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
48
+ LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
49
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
50
+ OUTFLAG = -o
51
+ COUTFLAG = -o
52
+
53
+ RUBY_EXTCONF_H =
54
+ cflags = $(optflags) $(debugflags) $(warnflags)
55
+ optflags = -O2
56
+ debugflags = -g
57
+ warnflags = -Wall -Wno-parentheses
58
+ CFLAGS = -fPIC -fno-strict-aliasing -g -g -O2 $(cflags) -fPIC
59
+ INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
60
+ DEFS = -D_FILE_OFFSET_BITS=64
61
+ CPPFLAGS = -DHAVE_FCGIAPP_H $(DEFS) $(cppflags)
62
+ CXXFLAGS = $(CFLAGS) -fno-strict-aliasing -g $(cxxflags)
63
+ ldflags = -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic
64
+ dldflags =
65
+ archflag =
66
+ DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
67
+ LDSHARED = $(CC) -shared
68
+ LDSHAREDXX = $(CXX) -shared
69
+ AR = ar
70
+ EXEEXT =
71
+
72
+ RUBY_INSTALL_NAME = ruby1.9.1
73
+ RUBY_SO_NAME = ruby-1.9.1
74
+ arch = i486-linux
75
+ sitearch = i486-linux
76
+ ruby_version = 1.9.1
77
+ ruby = /usr/bin/ruby1.9.1
78
+ RUBY = $(ruby)
79
+ RM = rm -f
80
+ RM_RF = $(RUBY) -run -e rm -- -rf
81
+ RMDIRS = $(RUBY) -run -e rmdir -- -p
82
+ MAKEDIRS = mkdir -p
83
+ INSTALL = /usr/bin/install -c
84
+ INSTALL_PROG = $(INSTALL) -m 0755
85
+ INSTALL_DATA = $(INSTALL) -m 644
86
+ COPY = cp
87
+
88
+ #### End of system configuration section. ####
89
+
90
+ preload =
91
+
92
+ libpath = . $(libdir)
93
+ LIBPATH = -L. -L$(libdir)
94
+ DEFFILE =
95
+
96
+ CLEANFILES = mkmf.log
97
+ DISTCLEANFILES =
98
+ DISTCLEANDIRS =
99
+
100
+ extout =
101
+ extout_prefix =
102
+ target_prefix =
103
+ LOCAL_LIBS =
104
+ LIBS = $(LIBRUBYARG_SHARED) -lfcgi -lpthread -lrt -ldl -lcrypt -lm -lc
105
+ SRCS = fcgi.c
106
+ OBJS = fcgi.o
107
+ TARGET = fcgi
108
+ DLLIB = $(TARGET).so
109
+ EXTSTATIC =
110
+ STATIC_LIB =
111
+
112
+ BINDIR = $(bindir)
113
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
114
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
115
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
116
+ HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
117
+ ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
118
+
119
+ TARGET_SO = $(DLLIB)
120
+ CLEANLIBS = $(TARGET).so
121
+ CLEANOBJS = *.o *.bak
122
+
123
+ all: $(DLLIB)
124
+ static: $(STATIC_LIB)
125
+
126
+ clean-rb-default::
127
+ clean-rb::
128
+ clean-so::
129
+ clean: clean-so clean-rb-default clean-rb
130
+ @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
131
+
132
+ distclean-rb-default::
133
+ distclean-rb::
134
+ distclean-so::
135
+ distclean: clean distclean-so distclean-rb-default distclean-rb
136
+ @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
137
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
138
+ @-$(RMDIRS) $(DISTCLEANDIRS)
139
+
140
+ realclean: distclean
141
+ install: install-so install-rb
142
+
143
+ install-so: $(RUBYARCHDIR)
144
+ install-so: $(RUBYARCHDIR)/$(DLLIB)
145
+ $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
146
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
147
+ install-rb: pre-install-rb install-rb-default
148
+ install-rb-default: pre-install-rb-default
149
+ pre-install-rb: Makefile
150
+ pre-install-rb-default: Makefile
151
+ $(RUBYARCHDIR):
152
+ $(MAKEDIRS) $@
153
+
154
+ site-install: site-install-so site-install-rb
155
+ site-install-so: install-so
156
+ site-install-rb: install-rb
157
+
158
+ .SUFFIXES: .c .m .cc .cxx .cpp .C .o
159
+
160
+ .cc.o:
161
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
162
+
163
+ .cxx.o:
164
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
165
+
166
+ .cpp.o:
167
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
168
+
169
+ .C.o:
170
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
171
+
172
+ .c.o:
173
+ $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
174
+
175
+ $(DLLIB): $(OBJS) Makefile
176
+ @-$(RM) $(@)
177
+ $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
178
+
179
+
180
+
181
+ $(OBJS): $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h
@@ -0,0 +1,7 @@
1
+ require "mkmf"
2
+
3
+ dir_config("fcgi")
4
+
5
+ if (have_header("fcgiapp.h") || have_header("fastcgi/fcgiapp.h")) && have_library("fcgi", "FCGX_Accept")
6
+ create_makefile("fcgi")
7
+ end
data/ext/fcgi/fcgi.c ADDED
@@ -0,0 +1,558 @@
1
+ /*
2
+ * fcgi.c
3
+ * Copyright (C) 1998-1999 Network Applied Communication Laboratory, Inc.
4
+ * Copyright (C) 2002-2006 MoonWolf <moonwolf@moonwolf.com>
5
+ */
6
+
7
+ #include <stdio.h>
8
+ #include <sys/types.h>
9
+ #include <unistd.h>
10
+ #include <errno.h>
11
+ #include <fcntl.h>
12
+
13
+ #include "ruby.h"
14
+ #ifdef HAVE_FASTCGI_FCGIAPP_H
15
+ #include <fastcgi/fcgiapp.h>
16
+ #else
17
+ #include "fcgiapp.h"
18
+ #endif
19
+
20
+ static VALUE cFCGI;
21
+ static VALUE eFCGIError;
22
+ static VALUE cFCGIStream;
23
+ static VALUE eFCGIStreamError;
24
+ static VALUE eFCGIStreamUnsupportedVersionError;
25
+ static VALUE eFCGIStreamProtocolError;
26
+ static VALUE eFCGIStreamParamsError;
27
+ static VALUE eFCGIStreamCallSeqError;
28
+
29
+ typedef struct fcgi_data {
30
+ FCGX_Request *req;
31
+ VALUE in;
32
+ VALUE out;
33
+ VALUE err;
34
+ VALUE env;
35
+ } fcgi_data;
36
+
37
+ static void fcgi_mark(fcgi_data *data)
38
+ {
39
+ /* rb_gc_mark(data->req); */
40
+ rb_gc_mark(data->in);
41
+ rb_gc_mark(data->out);
42
+ rb_gc_mark(data->err);
43
+ rb_gc_mark(data->env);
44
+ }
45
+
46
+ static void fcgi_free_req(fcgi_data *data)
47
+ {
48
+ free(data->req);
49
+ free(data);
50
+ }
51
+
52
+ static VALUE fcgi_s_accept(VALUE self)
53
+ {
54
+ int status;
55
+ FCGX_Request *req;
56
+ fd_set readfds;
57
+
58
+ req = ALLOC(FCGX_Request);
59
+
60
+ status = FCGX_InitRequest(req,0,0);
61
+ if (status != 0) {
62
+ rb_raise(eFCGIError, "FCGX_Init() failed");
63
+ return Qnil;
64
+ }
65
+
66
+ FD_ZERO(&readfds);
67
+ FD_SET(req->listen_sock, &readfds);
68
+ if (rb_thread_select(req->listen_sock+1, &readfds, NULL, NULL, NULL) < 1) {
69
+ return Qnil;
70
+ }
71
+
72
+ status = FCGX_Accept_r(req);
73
+ if (status >= 0) {
74
+ fcgi_data *data;
75
+ char **env;
76
+ VALUE obj,key, value;
77
+ char *pkey,*pvalue;
78
+ int flags, fd;
79
+
80
+ /* Unset NONBLOCKING */
81
+ fd = ((FCGX_Request*) req)->ipcFd;
82
+ flags = fcntl(fd, F_GETFL);
83
+
84
+ if (flags & O_NONBLOCK) {
85
+ fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
86
+ }
87
+
88
+ obj = Data_Make_Struct(self, fcgi_data, fcgi_mark, fcgi_free_req, data);
89
+ data->req = req;
90
+ data->in = Data_Wrap_Struct(cFCGIStream, 0, 0, req->in);
91
+ data->out = Data_Wrap_Struct(cFCGIStream, 0, 0, req->out);
92
+ data->err = Data_Wrap_Struct(cFCGIStream, 0, 0, req->err);
93
+ data->env = rb_hash_new();
94
+ env = req->envp;
95
+ for (; *env; env++) {
96
+ int size = 0;
97
+ pkey = *env;
98
+ pvalue = pkey;
99
+ while( *(pvalue++) != '=') size++;
100
+ key = rb_str_new(pkey, size);
101
+ value = rb_str_new2(pvalue);
102
+ OBJ_TAINT(key);
103
+ OBJ_TAINT(value);
104
+ rb_hash_aset(data->env, key, value);
105
+ }
106
+
107
+ return obj;
108
+ } else {
109
+ return Qnil;
110
+ }
111
+ }
112
+
113
+ static VALUE fcgi_s_each(VALUE self)
114
+ {
115
+ VALUE fcgi;
116
+
117
+ while ((fcgi = fcgi_s_accept(self)) != Qnil) {
118
+ rb_yield(fcgi);
119
+ }
120
+ return Qnil;
121
+ }
122
+
123
+ static VALUE fcgi_s_iscgi(VALUE self)
124
+ {
125
+ if (FCGX_IsCGI()) {
126
+ return Qtrue;
127
+ } else {
128
+ return Qfalse;
129
+ }
130
+ }
131
+
132
+ static VALUE fcgi_in(VALUE self)
133
+ {
134
+ fcgi_data *data;
135
+
136
+ Data_Get_Struct(self, fcgi_data, data);
137
+ return data->in;
138
+ }
139
+
140
+ static VALUE fcgi_out(VALUE self)
141
+ {
142
+ fcgi_data *data;
143
+
144
+ Data_Get_Struct(self, fcgi_data, data);
145
+ return data->out;
146
+ }
147
+
148
+ static VALUE fcgi_err(VALUE self)
149
+ {
150
+ fcgi_data *data;
151
+
152
+ Data_Get_Struct(self, fcgi_data, data);
153
+ return data->err;
154
+ }
155
+
156
+ static VALUE fcgi_env(VALUE self)
157
+ {
158
+ fcgi_data *data;
159
+
160
+ Data_Get_Struct(self, fcgi_data, data);
161
+ return data->env;
162
+ }
163
+
164
+ static VALUE fcgi_finish(VALUE self)
165
+ {
166
+ fcgi_data *data;
167
+
168
+ Data_Get_Struct(self, fcgi_data, data);
169
+
170
+ FCGX_Finish_r(data->req);
171
+
172
+ return Qtrue;
173
+ }
174
+
175
+ #define CHECK_STREAM_ERROR(stream) {\
176
+ int err = FCGX_GetError(stream);\
177
+ extern int errno; \
178
+ if (err) {\
179
+ if (err > 0) {\
180
+ errno = err;\
181
+ rb_sys_fail(NULL);\
182
+ }\
183
+ else {\
184
+ switch (err) {\
185
+ case FCGX_UNSUPPORTED_VERSION:\
186
+ rb_raise(eFCGIStreamUnsupportedVersionError, "unsupported version");\
187
+ break;\
188
+ case FCGX_PROTOCOL_ERROR:\
189
+ rb_raise(eFCGIStreamProtocolError, "protocol error");\
190
+ break;\
191
+ case FCGX_PARAMS_ERROR:\
192
+ rb_raise(eFCGIStreamProtocolError, "parameter error");\
193
+ break;\
194
+ case FCGX_CALL_SEQ_ERROR:\
195
+ rb_raise(eFCGIStreamCallSeqError, "preconditions are not met");\
196
+ break;\
197
+ default:\
198
+ rb_raise(eFCGIStreamError, "unknown error");\
199
+ break;\
200
+ }\
201
+ }\
202
+ }\
203
+ }
204
+
205
+ static VALUE fcgi_stream_putc(VALUE self, VALUE ch)
206
+ {
207
+ FCGX_Stream *stream;
208
+ int c;
209
+
210
+ rb_secure(4);
211
+ Data_Get_Struct(self, FCGX_Stream, stream);
212
+ if ((c = FCGX_PutChar(NUM2INT(ch), stream)) == EOF)
213
+ CHECK_STREAM_ERROR(stream);
214
+ return INT2NUM(c);
215
+ }
216
+
217
+ static VALUE fcgi_stream_write(VALUE self, VALUE str)
218
+ {
219
+ FCGX_Stream *stream;
220
+ int len;
221
+
222
+ rb_secure(4);
223
+ Data_Get_Struct(self, FCGX_Stream, stream);
224
+ str = rb_obj_as_string(str);
225
+ len = FCGX_PutStr(RSTRING_PTR(str), RSTRING_LEN(str), stream);
226
+ if (len == EOF) CHECK_STREAM_ERROR(stream);
227
+ return INT2NUM(len);
228
+ }
229
+
230
+ static VALUE fcgi_stream_print(int argc, VALUE *argv, VALUE out)
231
+ {
232
+ int i;
233
+ VALUE line;
234
+
235
+ /* if no argument given, print `$_' */
236
+ if (argc == 0) {
237
+ argc = 1;
238
+ line = rb_lastline_get();
239
+ argv = &line;
240
+ }
241
+ for (i=0; i<argc; i++) {
242
+ if (!NIL_P(rb_output_fs) && i>0) {
243
+ fcgi_stream_write(out, rb_output_fs);
244
+ }
245
+ switch (TYPE(argv[i])) {
246
+ case T_NIL:
247
+ fcgi_stream_write(out, rb_str_new2("nil"));
248
+ break;
249
+ default:
250
+ fcgi_stream_write(out, argv[i]);
251
+ break;
252
+ }
253
+ }
254
+ if (!NIL_P(rb_output_rs)) {
255
+ fcgi_stream_write(out, rb_output_rs);
256
+ }
257
+
258
+ return Qnil;
259
+ }
260
+
261
+ static VALUE fcgi_stream_printf(int argc, VALUE *argv, VALUE out)
262
+ {
263
+ fcgi_stream_write(out, rb_f_sprintf(argc, argv));
264
+ return Qnil;
265
+ }
266
+
267
+ static VALUE fcgi_stream_puts _((int, VALUE*, VALUE));
268
+
269
+ static VALUE fcgi_stream_puts_ary(VALUE ary, VALUE out)
270
+ {
271
+ VALUE tmp;
272
+ int i;
273
+
274
+ for (i=0; i<RARRAY_LEN(ary); i++) {
275
+ tmp = RARRAY_PTR(ary)[i];
276
+ if (rb_inspecting_p(tmp)) {
277
+ tmp = rb_str_new2("[...]");
278
+ }
279
+ fcgi_stream_puts(1, &tmp, out);
280
+ }
281
+ return Qnil;
282
+ }
283
+
284
+ static VALUE fcgi_stream_puts(int argc, VALUE *argv, VALUE out)
285
+ {
286
+ int i;
287
+ VALUE line;
288
+
289
+ /* if no argument given, print newline. */
290
+ if (argc == 0) {
291
+ fcgi_stream_write(out, rb_default_rs);
292
+ return Qnil;
293
+ }
294
+ for (i=0; i<argc; i++) {
295
+ switch (TYPE(argv[i])) {
296
+ case T_NIL:
297
+ line = rb_str_new2("nil");
298
+ break;
299
+ case T_ARRAY:
300
+ rb_protect_inspect(fcgi_stream_puts_ary, argv[i], out);
301
+ continue;
302
+ default:
303
+ line = argv[i];
304
+ break;
305
+ }
306
+ line = rb_obj_as_string(line);
307
+ fcgi_stream_write(out, line);
308
+ if (RSTRING_PTR(line)[RSTRING_LEN(line)-1] != '\n') {
309
+ fcgi_stream_write(out, rb_default_rs);
310
+ }
311
+ }
312
+
313
+ return Qnil;
314
+ }
315
+
316
+ static VALUE fcgi_stream_addstr(VALUE out, VALUE str)
317
+ {
318
+ fcgi_stream_write(out, str);
319
+ return out;
320
+ }
321
+
322
+ static VALUE fcgi_stream_flush(VALUE self)
323
+ {
324
+ FCGX_Stream *stream;
325
+
326
+ Data_Get_Struct(self, FCGX_Stream, stream);
327
+ if (FCGX_FFlush(stream) == EOF)
328
+ CHECK_STREAM_ERROR(stream);
329
+ return Qnil;
330
+ }
331
+
332
+ static VALUE fcgi_stream_getc(VALUE self)
333
+ {
334
+ FCGX_Stream *stream;
335
+ int c;
336
+
337
+ Data_Get_Struct(self, FCGX_Stream, stream);
338
+ if ((c = FCGX_GetChar(stream)) == EOF) {
339
+ CHECK_STREAM_ERROR(stream);
340
+ return Qnil;
341
+ }
342
+ else {
343
+ return INT2NUM(c);
344
+ }
345
+ }
346
+
347
+ static VALUE fcgi_stream_ungetc(VALUE self, VALUE ch)
348
+ {
349
+ FCGX_Stream *stream;
350
+ int c;
351
+
352
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
353
+ rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
354
+ }
355
+ Data_Get_Struct(self, FCGX_Stream, stream);
356
+ c = FCGX_UnGetChar(NUM2INT(ch), stream);
357
+ CHECK_STREAM_ERROR(stream);
358
+ return INT2NUM(c);
359
+ }
360
+
361
+ static VALUE fcgi_stream_gets(VALUE self)
362
+ {
363
+ FCGX_Stream *stream;
364
+ char buff[BUFSIZ];
365
+ VALUE str = rb_str_new("", 0);
366
+ OBJ_TAINT(str);
367
+
368
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
369
+ rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
370
+ }
371
+
372
+ Data_Get_Struct(self, FCGX_Stream, stream);
373
+
374
+ for (;;) {
375
+ if (FCGX_GetLine(buff, BUFSIZ, stream) == NULL) {
376
+ CHECK_STREAM_ERROR(stream);
377
+ break;
378
+ }
379
+ rb_str_cat(str, buff, strlen(buff));
380
+ if (strchr(buff, '\n')) break;
381
+ }
382
+ if (RSTRING_LEN(str) > 0)
383
+ return str;
384
+ else
385
+ return Qnil;
386
+ }
387
+
388
+ static VALUE fcgi_stream_read(int argc, VALUE *argv, VALUE self)
389
+ {
390
+ VALUE num,str;
391
+ FCGX_Stream *stream;
392
+ char *buff;
393
+ int n;
394
+
395
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
396
+ rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
397
+ }
398
+
399
+ Data_Get_Struct(self, FCGX_Stream, stream);
400
+
401
+ if (argc==0) {
402
+ buff = ALLOC_N(char, 16384);
403
+ n = FCGX_GetStr(buff, 16384, stream);
404
+ CHECK_STREAM_ERROR(stream);
405
+ if (n == 0) {
406
+ free(buff);
407
+ return Qnil;
408
+ }
409
+ str = rb_str_new(buff, n);
410
+ OBJ_TAINT(str);
411
+
412
+ while(!FCGX_HasSeenEOF(stream)) {
413
+ n = FCGX_GetStr(buff, 16384, stream);
414
+ CHECK_STREAM_ERROR(stream);
415
+ if (n > 0) {
416
+ rb_str_cat(str, buff, n);
417
+ } else {
418
+ free(buff);
419
+ return Qnil;
420
+ }
421
+ }
422
+ free(buff);
423
+ return str;
424
+ }
425
+
426
+ num = argv[0];
427
+ n = NUM2INT(num);
428
+
429
+ buff = ALLOC_N(char, n);
430
+ n = FCGX_GetStr(buff, n, stream);
431
+ CHECK_STREAM_ERROR(stream);
432
+ if (n > 0) {
433
+ str = rb_str_new(buff, n);
434
+ OBJ_TAINT(str);
435
+ free(buff);
436
+ return str;
437
+ }
438
+ else {
439
+ free(buff);
440
+ return Qnil;
441
+ }
442
+ }
443
+
444
+ static VALUE fcgi_stream_eof(VALUE self)
445
+ {
446
+ FCGX_Stream *stream;
447
+
448
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
449
+ rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
450
+ }
451
+ Data_Get_Struct(self, FCGX_Stream, stream);
452
+ return FCGX_HasSeenEOF(stream) ? Qtrue : Qfalse;
453
+ }
454
+
455
+ static VALUE fcgi_stream_close(VALUE self)
456
+ {
457
+ FCGX_Stream *stream;
458
+
459
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
460
+ rb_raise(rb_eSecurityError, "Insecure: can't close");
461
+ }
462
+ Data_Get_Struct(self, FCGX_Stream, stream);
463
+ if (FCGX_FClose(stream) == EOF)
464
+ CHECK_STREAM_ERROR(stream);
465
+ return Qnil;
466
+ }
467
+
468
+ static VALUE fcgi_stream_closed(VALUE self)
469
+ {
470
+ FCGX_Stream *stream;
471
+
472
+ Data_Get_Struct(self, FCGX_Stream, stream);
473
+ return stream->isClosed ? Qtrue : Qfalse;
474
+ }
475
+
476
+ static VALUE fcgi_stream_binmode(VALUE self)
477
+ {
478
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
479
+ rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
480
+ }
481
+ return self;
482
+ }
483
+
484
+ static VALUE fcgi_stream_isatty(VALUE self)
485
+ {
486
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
487
+ rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
488
+ }
489
+ return Qfalse;
490
+ }
491
+
492
+ static VALUE fcgi_stream_sync(VALUE self)
493
+ {
494
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
495
+ rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
496
+ }
497
+ return Qfalse;
498
+ }
499
+
500
+ static VALUE fcgi_stream_setsync(VALUE self,VALUE sync)
501
+ {
502
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
503
+ rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
504
+ }
505
+ return Qfalse;
506
+ }
507
+
508
+
509
+
510
+ void Init_fcgi() {
511
+
512
+ FCGX_Init();
513
+
514
+ cFCGI = rb_define_class("FCGI", rb_cObject);
515
+ eFCGIError =rb_define_class_under(cFCGI, "Error", rb_eStandardError);
516
+ rb_define_singleton_method(cFCGI, "accept", fcgi_s_accept, 0);
517
+ rb_define_singleton_method(cFCGI, "each", fcgi_s_each, 0);
518
+ rb_define_singleton_method(cFCGI, "each_request", fcgi_s_each, 0);
519
+ rb_define_singleton_method(cFCGI, "is_cgi?", fcgi_s_iscgi, 0);
520
+ rb_define_method(cFCGI, "in", fcgi_in, 0);
521
+ rb_define_method(cFCGI, "out", fcgi_out, 0);
522
+ rb_define_method(cFCGI, "err", fcgi_err, 0);
523
+ rb_define_method(cFCGI, "env", fcgi_env, 0);
524
+ rb_define_method(cFCGI, "finish", fcgi_finish, 0);
525
+
526
+ cFCGIStream = rb_define_class_under(cFCGI, "Stream", rb_cObject);
527
+ eFCGIStreamError =rb_define_class_under(cFCGIStream, "Error", rb_eStandardError);
528
+ eFCGIStreamUnsupportedVersionError =
529
+ rb_define_class_under(cFCGIStream, "UnsupportedVersionError",
530
+ eFCGIStreamError);
531
+ eFCGIStreamProtocolError = rb_define_class_under(cFCGIStream, "ProtocolError",
532
+ eFCGIStreamError);
533
+ eFCGIStreamParamsError = rb_define_class_under(cFCGIStream, "ParamsError",
534
+ eFCGIStreamError);
535
+ eFCGIStreamCallSeqError = rb_define_class_under(cFCGIStream, "CallSeqError",
536
+ eFCGIStreamError);
537
+ rb_undef_method(CLASS_OF(cFCGIStream), "new");
538
+ rb_define_method(cFCGIStream, "putc", fcgi_stream_putc, 1);
539
+ rb_define_method(cFCGIStream, "write", fcgi_stream_write, 1);
540
+ rb_define_method(cFCGIStream, "print", fcgi_stream_print, -1);
541
+ rb_define_method(cFCGIStream, "printf", fcgi_stream_printf, -1);
542
+ rb_define_method(cFCGIStream, "puts", fcgi_stream_puts, -1);
543
+ rb_define_method(cFCGIStream, "<<", fcgi_stream_addstr, 1);
544
+ rb_define_method(cFCGIStream, "flush", fcgi_stream_flush, 0);
545
+ rb_define_method(cFCGIStream, "getc", fcgi_stream_getc, 0);
546
+ rb_define_method(cFCGIStream, "ungetc", fcgi_stream_ungetc, 1);
547
+ rb_define_method(cFCGIStream, "gets", fcgi_stream_gets, 0);
548
+ rb_define_method(cFCGIStream, "read", fcgi_stream_read, -1);
549
+ rb_define_method(cFCGIStream, "eof", fcgi_stream_eof, 0);
550
+ rb_define_method(cFCGIStream, "eof?", fcgi_stream_eof, 0);
551
+ rb_define_method(cFCGIStream, "close", fcgi_stream_close, 0);
552
+ rb_define_method(cFCGIStream, "closed?", fcgi_stream_closed, 0);
553
+ rb_define_method(cFCGIStream, "binmode", fcgi_stream_binmode, 0);
554
+ rb_define_method(cFCGIStream, "isatty", fcgi_stream_isatty, 0);
555
+ rb_define_method(cFCGIStream, "tty?", fcgi_stream_isatty, 0);
556
+ rb_define_method(cFCGIStream, "sync", fcgi_stream_sync, 0);
557
+ rb_define_method(cFCGIStream, "sync=", fcgi_stream_setsync, 1);
558
+ }