ruby-fcgi 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.config +20 -0
- data/.document +5 -0
- data/.gitignore +26 -0
- data/ChangeLog +33 -0
- data/InstalledFiles +1 -0
- data/LICENSE +20 -0
- data/README +110 -0
- data/README.rdoc +110 -0
- data/README.signals +76 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/ext/fcgi/MANIFEST +3 -0
- data/ext/fcgi/Makefile +181 -0
- data/ext/fcgi/extconf.rb +7 -0
- data/ext/fcgi/fcgi.c +558 -0
- data/install.rb +1551 -0
- data/lib/fcgi.rb +618 -0
- data/test/helper.rb +9 -0
- data/test/test_fcgi.rb +7 -0
- metadata +78 -0
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.8.8
|
data/ext/fcgi/MANIFEST
ADDED
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
|
data/ext/fcgi/extconf.rb
ADDED
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
|
+
}
|