ruby-lsapi 4.1 → 5.1
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.
- checksums.yaml +6 -14
- data/ext/lsapi/extconf.rb +3 -0
- data/ext/lsapi/lsapidef.h +13 -20
- data/ext/lsapi/lsapilib.c +1376 -377
- data/ext/lsapi/lsapilib.h +80 -36
- data/ext/lsapi/lsruby.c +482 -217
- data/lsapi.gemspec +16 -0
- metadata +8 -7
data/ext/lsapi/lsapilib.h
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
/*
|
2
|
-
Copyright (c)
|
2
|
+
Copyright (c) 2002-2018, Lite Speed Technologies Inc.
|
3
3
|
All rights reserved.
|
4
4
|
|
5
5
|
Redistribution and use in source and binary forms, with or without
|
6
6
|
modification, are permitted provided that the following conditions are
|
7
|
-
met:
|
7
|
+
met:
|
8
8
|
|
9
9
|
* Redistributions of source code must retain the above copyright
|
10
|
-
notice, this list of conditions and the following disclaimer.
|
10
|
+
notice, this list of conditions and the following disclaimer.
|
11
11
|
* Redistributions in binary form must reproduce the above
|
12
12
|
copyright notice, this list of conditions and the following
|
13
13
|
disclaimer in the documentation and/or other materials provided
|
14
|
-
with the distribution.
|
14
|
+
with the distribution.
|
15
15
|
* Neither the name of the Lite Speed Technologies Inc nor the
|
16
16
|
names of its contributors may be used to endorse or promote
|
17
17
|
products derived from this software without specific prior
|
18
|
-
written permission.
|
18
|
+
written permission.
|
19
19
|
|
20
20
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
21
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
@@ -27,17 +27,9 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
27
27
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
28
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
29
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
31
|
*/
|
32
32
|
|
33
|
-
/***************************************************************************
|
34
|
-
lsapilib.h - description
|
35
|
-
-------------------
|
36
|
-
begin : Mon Feb 21 2005
|
37
|
-
copyright : (C) 2005 by George Wang
|
38
|
-
email : gwang@litespeedtech.com
|
39
|
-
***************************************************************************/
|
40
|
-
|
41
33
|
|
42
34
|
#ifndef _LSAPILIB_H_
|
43
35
|
#define _LSAPILIB_H_
|
@@ -46,9 +38,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
46
38
|
extern "C" {
|
47
39
|
#endif
|
48
40
|
|
49
|
-
#include
|
50
|
-
#include <lsapidef.h>
|
41
|
+
#include "lsapidef.h"
|
51
42
|
|
43
|
+
#include <stddef.h>
|
52
44
|
#include <sys/time.h>
|
53
45
|
#include <sys/types.h>
|
54
46
|
|
@@ -60,8 +52,8 @@ struct LSAPI_key_value_pair
|
|
60
52
|
int valLen;
|
61
53
|
};
|
62
54
|
|
63
|
-
|
64
|
-
#define LSAPI_MAX_RESP_HEADERS
|
55
|
+
struct lsapi_child_status;
|
56
|
+
#define LSAPI_MAX_RESP_HEADERS 1000
|
65
57
|
|
66
58
|
typedef struct lsapi_request
|
67
59
|
{
|
@@ -73,7 +65,7 @@ typedef struct lsapi_request
|
|
73
65
|
|
74
66
|
char * m_pReqBuf;
|
75
67
|
int m_reqBufSize;
|
76
|
-
|
68
|
+
|
77
69
|
char * m_pRespBuf;
|
78
70
|
char * m_pRespBufEnd;
|
79
71
|
char * m_pRespBufPos;
|
@@ -81,12 +73,13 @@ typedef struct lsapi_request
|
|
81
73
|
char * m_pRespHeaderBuf;
|
82
74
|
char * m_pRespHeaderBufEnd;
|
83
75
|
char * m_pRespHeaderBufPos;
|
76
|
+
struct lsapi_child_status * child_status;
|
84
77
|
|
85
78
|
|
86
79
|
struct iovec * m_pIovec;
|
87
80
|
struct iovec * m_pIovecEnd;
|
88
81
|
struct iovec * m_pIovecCur;
|
89
|
-
struct iovec * m_pIovecToWrite;
|
82
|
+
struct iovec * m_pIovecToWrite;
|
90
83
|
|
91
84
|
struct lsapi_packet_header * m_respPktHeaderEnd;
|
92
85
|
|
@@ -98,7 +91,7 @@ typedef struct lsapi_request
|
|
98
91
|
|
99
92
|
struct lsapi_http_header_index * m_pHeaderIndex;
|
100
93
|
struct lsapi_header_offset * m_pUnknownHeader;
|
101
|
-
|
94
|
+
|
102
95
|
char * m_pScriptFile;
|
103
96
|
char * m_pScriptName;
|
104
97
|
char * m_pQueryString;
|
@@ -110,9 +103,9 @@ typedef struct lsapi_request
|
|
110
103
|
off_t m_reqBodyRead;
|
111
104
|
int m_bufProcessed;
|
112
105
|
int m_bufRead;
|
113
|
-
|
106
|
+
|
114
107
|
struct lsapi_packet_header m_respPktHeader[5];
|
115
|
-
|
108
|
+
|
116
109
|
struct lsapi_resp_header m_respHeader;
|
117
110
|
short m_respHeaderLen[LSAPI_MAX_RESP_HEADERS];
|
118
111
|
void * m_pAppData;
|
@@ -158,7 +151,6 @@ int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq,
|
|
158
151
|
LSAPI_CB_EnvHandler fn, void * arg );
|
159
152
|
|
160
153
|
char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name );
|
161
|
-
|
162
154
|
|
163
155
|
ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t len );
|
164
156
|
|
@@ -179,9 +171,12 @@ int LSAPI_Flush_r( LSAPI_Request * pReq );
|
|
179
171
|
|
180
172
|
int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len );
|
181
173
|
|
182
|
-
int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
|
174
|
+
int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
|
183
175
|
const char * pHeaderValue );
|
184
176
|
|
177
|
+
int LSAPI_ErrResponse_r( LSAPI_Request * pReq, int code, const char ** pRespHeaders,
|
178
|
+
const char * pBody, int bodyLen );
|
179
|
+
|
185
180
|
static inline int LSAPI_SetRespStatus_r( LSAPI_Request * pReq, int code )
|
186
181
|
{
|
187
182
|
if ( !pReq )
|
@@ -253,6 +248,10 @@ static inline off_t LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq )
|
|
253
248
|
}
|
254
249
|
|
255
250
|
|
251
|
+
int LSAPI_End_Response_r(LSAPI_Request * pReq);
|
252
|
+
|
253
|
+
|
254
|
+
|
256
255
|
int LSAPI_Is_Listen(void);
|
257
256
|
|
258
257
|
static inline int LSAPI_Accept( void )
|
@@ -280,28 +279,28 @@ static inline int LSAPI_ForeachSpecialEnv( LSAPI_CB_EnvHandler fn, void * arg )
|
|
280
279
|
static inline char * LSAPI_GetEnv( const char * name )
|
281
280
|
{ return LSAPI_GetEnv_r( &g_req, name ); }
|
282
281
|
|
283
|
-
static inline char * LSAPI_GetQueryString()
|
282
|
+
static inline char * LSAPI_GetQueryString(void)
|
284
283
|
{ return LSAPI_GetQueryString_r( &g_req ); }
|
285
284
|
|
286
|
-
static inline char * LSAPI_GetScriptFileName()
|
285
|
+
static inline char * LSAPI_GetScriptFileName(void)
|
287
286
|
{ return LSAPI_GetScriptFileName_r( &g_req ); }
|
288
287
|
|
289
|
-
static inline char * LSAPI_GetScriptName()
|
288
|
+
static inline char * LSAPI_GetScriptName(void)
|
290
289
|
{ return LSAPI_GetScriptName_r( &g_req ); }
|
291
290
|
|
292
|
-
static inline char * LSAPI_GetRequestMethod()
|
291
|
+
static inline char * LSAPI_GetRequestMethod(void)
|
293
292
|
{ return LSAPI_GetRequestMethod_r( &g_req ); }
|
294
293
|
|
295
|
-
static inline off_t LSAPI_GetReqBodyLen()
|
294
|
+
static inline off_t LSAPI_GetReqBodyLen(void)
|
296
295
|
{ return LSAPI_GetReqBodyLen_r( &g_req ); }
|
297
296
|
|
298
|
-
static inline off_t LSAPI_GetReqBodyRemain()
|
297
|
+
static inline off_t LSAPI_GetReqBodyRemain(void)
|
299
298
|
{ return LSAPI_GetReqBodyRemain_r( &g_req ); }
|
300
299
|
|
301
300
|
static inline ssize_t LSAPI_ReadReqBody( char * pBuf, size_t len )
|
302
301
|
{ return LSAPI_ReadReqBody_r( &g_req, pBuf, len ); }
|
303
302
|
|
304
|
-
static inline int LSAPI_ReqBodyGetChar()
|
303
|
+
static inline int LSAPI_ReqBodyGetChar(void)
|
305
304
|
{ return LSAPI_ReqBodyGetChar_r( &g_req ); }
|
306
305
|
|
307
306
|
static inline int LSAPI_ReqBodyGetLine( char * pBuf, int len, int *getLF )
|
@@ -317,13 +316,13 @@ static inline ssize_t LSAPI_Write( const char * pBuf, ssize_t len )
|
|
317
316
|
|
318
317
|
static inline ssize_t LSAPI_sendfile( int fdIn, off_t* off, size_t size )
|
319
318
|
{
|
320
|
-
return LSAPI_sendfile_r(&g_req, fdIn, off, size );
|
319
|
+
return LSAPI_sendfile_r(&g_req, fdIn, off, size );
|
321
320
|
}
|
322
321
|
|
323
322
|
static inline ssize_t LSAPI_Write_Stderr( const char * pBuf, ssize_t len )
|
324
323
|
{ return LSAPI_Write_Stderr_r( &g_req, pBuf, len ); }
|
325
324
|
|
326
|
-
static inline int LSAPI_Flush()
|
325
|
+
static inline int LSAPI_Flush(void)
|
327
326
|
{ return LSAPI_Flush_r( &g_req ); }
|
328
327
|
|
329
328
|
static inline int LSAPI_AppendRespHeader( char * pBuf, int len )
|
@@ -332,6 +331,12 @@ static inline int LSAPI_AppendRespHeader( char * pBuf, int len )
|
|
332
331
|
static inline int LSAPI_SetRespStatus( int code )
|
333
332
|
{ return LSAPI_SetRespStatus_r( &g_req, code ); }
|
334
333
|
|
334
|
+
static inline int LSAPI_ErrResponse( int code, const char ** pRespHeaders, const char * pBody, int bodyLen )
|
335
|
+
{ return LSAPI_ErrResponse_r( &g_req, code, pRespHeaders, pBody, bodyLen ); }
|
336
|
+
|
337
|
+
static inline int LSAPI_End_Response(void)
|
338
|
+
{ return LSAPI_End_Response_r( &g_req ); }
|
339
|
+
|
335
340
|
int LSAPI_IsRunning(void);
|
336
341
|
|
337
342
|
int LSAPI_CreateListenSock( const char * pBind, int backlog );
|
@@ -344,6 +349,8 @@ void LSAPI_Set_Server_fd( int fd );
|
|
344
349
|
|
345
350
|
int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq );
|
346
351
|
|
352
|
+
void LSAPI_No_Check_ppid(void);
|
353
|
+
|
347
354
|
void LSAPI_Set_Max_Reqs( int reqs );
|
348
355
|
|
349
356
|
void LSAPI_Set_Max_Idle( int secs );
|
@@ -360,9 +367,46 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp );
|
|
360
367
|
|
361
368
|
void LSAPI_Set_Slow_Req_Msecs( int msecs );
|
362
369
|
|
363
|
-
int LSAPI_Get_Slow_Req_Msecs(
|
370
|
+
int LSAPI_Get_Slow_Req_Msecs(void);
|
371
|
+
|
372
|
+
int LSAPI_is_suEXEC_Daemon(void);
|
373
|
+
|
374
|
+
int LSAPI_Set_Restored_Parent_Pid(int pid);
|
375
|
+
|
376
|
+
typedef void (*LSAPI_On_Timer_pf)(int *forked_child_pid);
|
377
|
+
void LSAPI_Register_Pgrp_Timer_Callback(LSAPI_On_Timer_pf);
|
378
|
+
|
379
|
+
int LSAPI_Inc_Req_Processed(int cnt);
|
380
|
+
|
381
|
+
int LSAPI_Accept_Before_Fork(LSAPI_Request * pReq);
|
382
|
+
|
383
|
+
int LSAPI_Postfork_Child(LSAPI_Request * pReq);
|
384
|
+
|
385
|
+
int LSAPI_Postfork_Parent(LSAPI_Request * pReq);
|
386
|
+
|
387
|
+
#define LSAPI_LOG_LEVEL_BITS 0xff
|
388
|
+
#define LSAPI_LOG_FLAG_NONE 0
|
389
|
+
#define LSAPI_LOG_FLAG_DEBUG 1
|
390
|
+
#define LSAPI_LOG_FLAG_INFO 2
|
391
|
+
#define LSAPI_LOG_FLAG_NOTICE 3
|
392
|
+
#define LSAPI_LOG_FLAG_WARN 4
|
393
|
+
#define LSAPI_LOG_FLAG_ERROR 5
|
394
|
+
#define LSAPI_LOG_FLAG_CRIT 6
|
395
|
+
#define LSAPI_LOG_FLAG_FATAL 7
|
396
|
+
|
397
|
+
#define LSAPI_LOG_TIMESTAMP_BITS (0xff00)
|
398
|
+
#define LSAPI_LOG_TIMESTAMP_FULL (0x100)
|
399
|
+
#define LSAPI_LOG_TIMESTAMP_HMS (0x200)
|
400
|
+
#define LSAPI_LOG_TIMESTAMP_STDERR (0x400)
|
401
|
+
|
402
|
+
#define LSAPI_LOG_PID (0x10000)
|
403
|
+
|
404
|
+
void LSAPI_Log(int flag, const char * fmt, ...)
|
405
|
+
#if __GNUC__
|
406
|
+
__attribute__((format(printf, 2, 3)))
|
407
|
+
#endif
|
408
|
+
;
|
364
409
|
|
365
|
-
int LSAPI_is_suEXEC_Daemon();
|
366
410
|
|
367
411
|
#if defined (c_plusplus) || defined (__cplusplus)
|
368
412
|
}
|
data/ext/lsapi/lsruby.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
#include "ruby.h"
|
3
3
|
|
4
|
-
#
|
4
|
+
#if defined( RUBY_19 ) || defined( RUBY_2 )
|
5
5
|
#include <ruby/util.h>
|
6
6
|
#else
|
7
7
|
#include "util.h"
|
@@ -15,6 +15,8 @@
|
|
15
15
|
#include <sys/socket.h>
|
16
16
|
#include <sys/wait.h>
|
17
17
|
#include <unistd.h>
|
18
|
+
#include <sys/mman.h>
|
19
|
+
#include <fcntl.h>
|
18
20
|
|
19
21
|
/* RUBY_EXTERN VALUE ruby_errinfo; */
|
20
22
|
RUBY_EXTERN VALUE rb_stdin;
|
@@ -36,6 +38,7 @@ static VALUE env_copy;
|
|
36
38
|
|
37
39
|
static VALUE lsapi_env;
|
38
40
|
|
41
|
+
static int MAX_BODYBUF_LENGTH = (10 * 1024 * 1024);
|
39
42
|
|
40
43
|
/* static VALUE lsapi_objrefs; */
|
41
44
|
|
@@ -43,11 +46,9 @@ typedef struct lsapi_data
|
|
43
46
|
{
|
44
47
|
LSAPI_Request * req;
|
45
48
|
VALUE env;
|
46
|
-
|
47
|
-
|
49
|
+
ssize_t (* fn_write)( LSAPI_Request *, const char * , size_t );
|
48
50
|
}lsapi_data;
|
49
51
|
|
50
|
-
|
51
52
|
static VALUE cLSAPI;
|
52
53
|
|
53
54
|
static VALUE s_req = Qnil;
|
@@ -57,17 +58,28 @@ static VALUE s_req_stderr = Qnil;
|
|
57
58
|
static lsapi_data * s_stderr_data;
|
58
59
|
static pid_t s_pid = 0;
|
59
60
|
|
60
|
-
|
61
|
-
static void lsapi_ruby_setenv(const char *name, const char *value)
|
61
|
+
typedef struct lsapi_body
|
62
62
|
{
|
63
|
-
|
63
|
+
char *bodyBuf; //we put small one into memory, otherwise, into a memory mapping file, and we still use the bodyBuf to access this mapping
|
64
|
+
int bodyLen; //expected length got form content-length
|
65
|
+
int bodyCurrentLen; //current length by read() readBodyToReqBuf
|
66
|
+
int curPos;
|
67
|
+
}lsapi_body;
|
64
68
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
69
|
+
static lsapi_body s_body;
|
70
|
+
static char sTempFile[1024] = {0};
|
71
|
+
|
72
|
+
/*
|
73
|
+
* static void lsapi_ruby_setenv(const char *name, const char *value)
|
74
|
+
* {
|
75
|
+
* if (!name) return;
|
76
|
+
*
|
77
|
+
* if (value && *value)
|
78
|
+
* ruby_setenv(name, value);
|
79
|
+
* else
|
80
|
+
* ruby_unsetenv(name);
|
81
|
+
} * *
|
82
|
+
*/
|
71
83
|
|
72
84
|
|
73
85
|
static void lsapi_mark( lsapi_data * data )
|
@@ -75,87 +87,87 @@ static void lsapi_mark( lsapi_data * data )
|
|
75
87
|
rb_gc_mark( data->env );
|
76
88
|
}
|
77
89
|
/*
|
78
|
-
static void lsapi_free_data( lsapi_data * data )
|
79
|
-
{
|
80
|
-
free( data );
|
81
|
-
}
|
82
|
-
*/
|
90
|
+
* static void lsapi_free_data( lsapi_data * data )
|
91
|
+
* {
|
92
|
+
* free( data );
|
93
|
+
} * *
|
94
|
+
*/
|
83
95
|
static int add_env_rails( const char * pKey, int keyLen, const char * pValue, int valLen,
|
84
|
-
|
96
|
+
void * arg )
|
85
97
|
{
|
86
98
|
char * p;
|
87
99
|
int len;
|
88
100
|
/* Fixup some environment variables for rails */
|
89
101
|
switch( *pKey )
|
90
102
|
{
|
91
|
-
|
92
|
-
|
93
|
-
{
|
94
|
-
if ( !*pValue )
|
95
|
-
return 1;
|
96
|
-
}
|
97
|
-
break;
|
98
|
-
case 'R':
|
99
|
-
if (( *(pKey+8) == 'U' )&&( strcmp( pKey, "REQUEST_URI" ) == 0 ))
|
100
|
-
{
|
101
|
-
p = strchr( pValue, '?' );
|
102
|
-
if ( p )
|
103
|
+
case 'Q':
|
104
|
+
if ( strcmp( pKey, "QUERY_STRING" ) == 0 )
|
103
105
|
{
|
104
|
-
|
105
|
-
|
106
|
-
valLen = p - pValue;
|
107
|
-
*p++ = 0;
|
108
|
-
*/
|
106
|
+
if ( !*pValue )
|
107
|
+
return 1;
|
109
108
|
}
|
110
|
-
|
109
|
+
break;
|
110
|
+
case 'R':
|
111
|
+
if (( *(pKey+8) == 'U' )&&( strcmp( pKey, "REQUEST_URI" ) == 0 ))
|
111
112
|
{
|
112
|
-
p = (
|
113
|
-
|
113
|
+
p = strchr( pValue, '?' );
|
114
|
+
if ( p )
|
115
|
+
{
|
116
|
+
len = valLen - ( p - pValue ) - 1;
|
117
|
+
/*
|
118
|
+
* valLen = p - pValue;
|
119
|
+
*p++ = 0;
|
120
|
+
*/
|
121
|
+
}
|
122
|
+
else
|
123
|
+
{
|
124
|
+
p = (char *)pValue + valLen;
|
125
|
+
len = 0;
|
126
|
+
}
|
127
|
+
rb_hash_aset( lsapi_env,rb_tainted_str_new("PATH_INFO", 9),
|
128
|
+
rb_tainted_str_new(pValue, p - pValue));
|
129
|
+
rb_hash_aset( lsapi_env,rb_tainted_str_new("REQUEST_PATH", 12),
|
130
|
+
rb_tainted_str_new(pValue, p - pValue));
|
131
|
+
if ( *p == '?' )
|
132
|
+
++p;
|
133
|
+
rb_hash_aset( lsapi_env,rb_tainted_str_new("QUERY_STRING", 12),
|
134
|
+
rb_tainted_str_new(p, len));
|
114
135
|
}
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
pValue = "/";
|
129
|
-
valLen = 1;
|
130
|
-
}
|
131
|
-
break;
|
132
|
-
case 'P':
|
133
|
-
if ( strcmp( pKey, "PATH_INFO" ) == 0 )
|
134
|
-
return 1;
|
135
|
-
default:
|
136
|
-
break;
|
136
|
+
break;
|
137
|
+
case 'S':
|
138
|
+
if ( strcmp( pKey, "SCRIPT_NAME" ) == 0 )
|
139
|
+
{
|
140
|
+
pValue = "/";
|
141
|
+
valLen = 1;
|
142
|
+
}
|
143
|
+
break;
|
144
|
+
case 'P':
|
145
|
+
if ( strcmp( pKey, "PATH_INFO" ) == 0 )
|
146
|
+
return 1;
|
147
|
+
default:
|
148
|
+
break;
|
137
149
|
}
|
138
150
|
|
139
151
|
/* lsapi_ruby_setenv(pKey, pValue ); */
|
140
152
|
|
141
153
|
rb_hash_aset( lsapi_env,rb_tainted_str_new(pKey, keyLen),
|
142
|
-
|
154
|
+
rb_tainted_str_new(pValue, valLen));
|
143
155
|
return 1;
|
144
156
|
}
|
145
157
|
|
146
158
|
static int add_env_no_fix( const char * pKey, int keyLen, const char * pValue, int valLen,
|
147
|
-
|
159
|
+
void * arg )
|
148
160
|
{
|
149
161
|
rb_hash_aset( lsapi_env,rb_tainted_str_new(pKey, keyLen),
|
150
|
-
|
162
|
+
rb_tainted_str_new(pValue, valLen));
|
151
163
|
return 1;
|
152
164
|
}
|
153
165
|
|
154
166
|
typedef int (*fn_add_env)( const char * pKey, int keyLen, const char * pValue, int valLen,
|
155
|
-
|
156
|
-
|
167
|
+
void * arg );
|
168
|
+
|
157
169
|
fn_add_env s_fn_add_env = add_env_no_fix;
|
158
|
-
|
170
|
+
|
159
171
|
static void clear_env()
|
160
172
|
{
|
161
173
|
/* rb_funcall( lsapi_env, rb_intern( "clear" ), 0 ); */
|
@@ -165,15 +177,11 @@ static void clear_env()
|
|
165
177
|
static void setup_cgi_env( lsapi_data * data )
|
166
178
|
{
|
167
179
|
clear_env();
|
168
|
-
|
180
|
+
|
169
181
|
LSAPI_ForeachHeader_r( data->req, s_fn_add_env, data );
|
170
182
|
LSAPI_ForeachEnv_r( data->req, s_fn_add_env, data );
|
171
|
-
|
172
183
|
}
|
173
184
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
185
|
static VALUE lsapi_s_accept( VALUE self )
|
178
186
|
{
|
179
187
|
int pid;
|
@@ -181,33 +189,63 @@ static VALUE lsapi_s_accept( VALUE self )
|
|
181
189
|
return Qnil;
|
182
190
|
else
|
183
191
|
{
|
184
|
-
|
192
|
+
if (s_body.bodyBuf != NULL)
|
193
|
+
free (s_body.bodyBuf);
|
194
|
+
|
195
|
+
s_body.bodyBuf = NULL;
|
196
|
+
s_body.bodyLen = -1;
|
197
|
+
s_body.bodyCurrentLen = 0;
|
198
|
+
s_body.curPos = 0;
|
199
|
+
|
185
200
|
pid = getpid();
|
186
201
|
if ( pid != s_pid )
|
187
202
|
{
|
188
203
|
s_pid = pid;
|
189
204
|
rb_funcall( Qnil, rb_intern( "srand" ), 0 );
|
190
205
|
}
|
191
|
-
|
206
|
+
|
192
207
|
setup_cgi_env( s_req_data );
|
193
208
|
return s_req;
|
194
209
|
}
|
195
|
-
|
196
210
|
}
|
197
211
|
|
198
|
-
|
199
|
-
static
|
212
|
+
|
213
|
+
static VALUE lsapi_s_accept_new_conn(VALUE self)
|
214
|
+
{
|
215
|
+
if (LSAPI_Accept_Before_Fork(&g_req) == -1 )
|
216
|
+
return Qnil;
|
217
|
+
else
|
218
|
+
return s_req;
|
219
|
+
}
|
220
|
+
|
221
|
+
|
222
|
+
static VALUE lsapi_s_postfork_child(VALUE self)
|
200
223
|
{
|
201
|
-
|
202
|
-
|
203
|
-
if ( !p )
|
204
|
-
return -1;
|
205
|
-
*p = 0;
|
206
|
-
ret = chdir( pFile );
|
207
|
-
*p = '/';
|
208
|
-
return ret;
|
224
|
+
LSAPI_Postfork_Child(&g_req);
|
225
|
+
return s_req;
|
209
226
|
}
|
210
|
-
|
227
|
+
|
228
|
+
|
229
|
+
static VALUE lsapi_s_postfork_parent(VALUE self)
|
230
|
+
{
|
231
|
+
LSAPI_Postfork_Parent(&g_req);
|
232
|
+
return s_req;
|
233
|
+
}
|
234
|
+
|
235
|
+
|
236
|
+
/*
|
237
|
+
* static int chdir_file( const char * pFile )
|
238
|
+
* {
|
239
|
+
* char * p = strrchr( pFile, '/' );
|
240
|
+
* int ret;
|
241
|
+
* if ( !p )
|
242
|
+
* return -1;
|
243
|
+
*p = 0;
|
244
|
+
ret = chdir( pFile );
|
245
|
+
*p = '/';
|
246
|
+
return ret;
|
247
|
+
}
|
248
|
+
*/
|
211
249
|
|
212
250
|
static VALUE lsapi_eval_string_wrap(VALUE self, VALUE str)
|
213
251
|
{
|
@@ -217,25 +255,26 @@ static VALUE lsapi_eval_string_wrap(VALUE self, VALUE str)
|
|
217
255
|
}
|
218
256
|
else
|
219
257
|
{
|
220
|
-
|
258
|
+
SafeStringValue(str);
|
221
259
|
}
|
222
260
|
return rb_eval_string_wrap(StringValuePtr(str), NULL);
|
223
261
|
}
|
224
262
|
|
225
263
|
static VALUE lsapi_process( VALUE self )
|
226
264
|
{
|
227
|
-
lsapi_data *data;
|
265
|
+
/* lsapi_data *data;
|
228
266
|
const char * pScriptPath;
|
229
267
|
Data_Get_Struct(self,lsapi_data, data);
|
230
268
|
pScriptPath = LSAPI_GetScriptFileName_r( data->req );
|
231
|
-
/*
|
232
|
-
if ( chdir_file( pScriptPath ) == -1 )
|
233
|
-
{
|
234
|
-
lsapi_send_error( 404 );
|
235
|
-
}
|
236
|
-
rb_load_file( pScriptPath );
|
237
269
|
*/
|
238
|
-
|
270
|
+
/*
|
271
|
+
* if ( chdir_file( pScriptPath ) == -1 )
|
272
|
+
* {
|
273
|
+
* lsapi_send_error( 404 );
|
274
|
+
* }
|
275
|
+
* rb_load_file( pScriptPath );
|
276
|
+
*/
|
277
|
+
return Qnil;
|
239
278
|
}
|
240
279
|
|
241
280
|
|
@@ -256,9 +295,9 @@ static VALUE lsapi_write( VALUE self, VALUE str )
|
|
256
295
|
lsapi_data *data;
|
257
296
|
int len;
|
258
297
|
Data_Get_Struct(self,lsapi_data, data);
|
259
|
-
/* len = LSAPI_Write_r( data->req, RSTRING_PTR(str), RSTRING_LEN(str) ); */
|
298
|
+
/* len = LSAPI_Write_r( data->req, RSTRING_PTR(str), RSTRING_LEN(str) ); */
|
260
299
|
if (TYPE(str) != T_STRING)
|
261
|
-
|
300
|
+
str = rb_obj_as_string(str);
|
262
301
|
len = (*data->fn_write)( data->req, RSTRING_PTR(str), RSTRING_LEN(str) );
|
263
302
|
return INT2NUM( len );
|
264
303
|
}
|
@@ -267,13 +306,13 @@ static VALUE lsapi_print( int argc, VALUE *argv, VALUE out )
|
|
267
306
|
{
|
268
307
|
int i;
|
269
308
|
VALUE line;
|
270
|
-
|
309
|
+
|
271
310
|
/* if no argument given, print `$_' */
|
272
311
|
if (argc == 0)
|
273
312
|
{
|
274
|
-
|
275
|
-
|
276
|
-
|
313
|
+
argc = 1;
|
314
|
+
line = rb_lastline_get();
|
315
|
+
argv = &line;
|
277
316
|
}
|
278
317
|
for (i = 0; i<argc; i++)
|
279
318
|
{
|
@@ -283,19 +322,19 @@ static VALUE lsapi_print( int argc, VALUE *argv, VALUE out )
|
|
283
322
|
}
|
284
323
|
switch (TYPE(argv[i]))
|
285
324
|
{
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
325
|
+
case T_NIL:
|
326
|
+
lsapi_write(out, rb_str_new2("nil"));
|
327
|
+
break;
|
328
|
+
default:
|
329
|
+
lsapi_write(out, argv[i]);
|
330
|
+
break;
|
292
331
|
}
|
293
332
|
}
|
294
333
|
if (!NIL_P(rb_output_rs))
|
295
334
|
{
|
296
335
|
lsapi_write(out, rb_output_rs);
|
297
336
|
}
|
298
|
-
|
337
|
+
|
299
338
|
return Qnil;
|
300
339
|
}
|
301
340
|
|
@@ -307,13 +346,13 @@ static VALUE lsapi_printf(int argc, VALUE *argv, VALUE out)
|
|
307
346
|
|
308
347
|
static VALUE lsapi_puts _((int, VALUE*, VALUE));
|
309
348
|
|
310
|
-
#
|
349
|
+
#if defined( RUBY_19 ) || defined( RUBY_2 )
|
311
350
|
static VALUE lsapi_puts_ary(VALUE ary, VALUE out, int recur )
|
312
351
|
{
|
313
352
|
VALUE tmp;
|
314
353
|
long i;
|
315
|
-
|
316
|
-
if (recur)
|
354
|
+
|
355
|
+
if (recur)
|
317
356
|
{
|
318
357
|
tmp = rb_str_new2("[...]");
|
319
358
|
rb_io_puts(1, &tmp, out);
|
@@ -325,22 +364,22 @@ static VALUE lsapi_puts_ary(VALUE ary, VALUE out, int recur )
|
|
325
364
|
rb_io_puts(1, &tmp, out);
|
326
365
|
}
|
327
366
|
return Qnil;
|
328
|
-
|
367
|
+
|
329
368
|
}
|
330
369
|
#else
|
331
370
|
static VALUE lsapi_puts_ary(VALUE ary, VALUE out)
|
332
371
|
{
|
333
372
|
VALUE tmp;
|
334
373
|
int i;
|
335
|
-
|
374
|
+
|
336
375
|
for (i=0; i<RARRAY_LEN(ary); i++)
|
337
376
|
{
|
338
377
|
tmp = RARRAY_PTR(ary)[i];
|
339
|
-
|
378
|
+
if (rb_inspecting_p(tmp))
|
340
379
|
{
|
341
|
-
|
342
|
-
|
343
|
-
|
380
|
+
tmp = rb_str_new2("[...]");
|
381
|
+
}
|
382
|
+
lsapi_puts(1, &tmp, out);
|
344
383
|
}
|
345
384
|
return Qnil;
|
346
385
|
}
|
@@ -350,7 +389,7 @@ static VALUE lsapi_puts(int argc, VALUE *argv, VALUE out)
|
|
350
389
|
{
|
351
390
|
int i;
|
352
391
|
VALUE line;
|
353
|
-
|
392
|
+
|
354
393
|
/* if no argument given, print newline. */
|
355
394
|
if (argc == 0)
|
356
395
|
{
|
@@ -361,19 +400,19 @@ static VALUE lsapi_puts(int argc, VALUE *argv, VALUE out)
|
|
361
400
|
{
|
362
401
|
switch (TYPE(argv[i]))
|
363
402
|
{
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
#
|
369
|
-
|
403
|
+
case T_NIL:
|
404
|
+
line = rb_str_new2("nil");
|
405
|
+
break;
|
406
|
+
case T_ARRAY:
|
407
|
+
#if defined( RUBY_19 ) || defined( RUBY_2 )
|
408
|
+
rb_exec_recursive(lsapi_puts_ary, argv[i], out);
|
370
409
|
#else
|
371
|
-
|
410
|
+
rb_protect_inspect(lsapi_puts_ary, argv[i], out);
|
372
411
|
#endif
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
412
|
+
continue;
|
413
|
+
default:
|
414
|
+
line = argv[i];
|
415
|
+
break;
|
377
416
|
}
|
378
417
|
line = rb_obj_as_string(line);
|
379
418
|
lsapi_write(out, line);
|
@@ -382,7 +421,7 @@ static VALUE lsapi_puts(int argc, VALUE *argv, VALUE out)
|
|
382
421
|
lsapi_write(out, rb_default_rs);
|
383
422
|
}
|
384
423
|
}
|
385
|
-
|
424
|
+
|
386
425
|
return Qnil;
|
387
426
|
}
|
388
427
|
|
@@ -395,10 +434,10 @@ static VALUE lsapi_addstr(VALUE out, VALUE str)
|
|
395
434
|
|
396
435
|
static VALUE lsapi_flush( VALUE self )
|
397
436
|
{
|
398
|
-
/*
|
399
|
-
lsapi_data *data;
|
400
|
-
Data_Get_Struct(self,lsapi_data, data);
|
401
|
-
*/
|
437
|
+
/*
|
438
|
+
* lsapi_data *data;
|
439
|
+
* Data_Get_Struct(self,lsapi_data, data);
|
440
|
+
*/
|
402
441
|
LSAPI_Flush_r( &g_req );
|
403
442
|
return Qnil;
|
404
443
|
}
|
@@ -406,10 +445,10 @@ static VALUE lsapi_flush( VALUE self )
|
|
406
445
|
static VALUE lsapi_getc( VALUE self )
|
407
446
|
{
|
408
447
|
int ch;
|
409
|
-
/*
|
410
|
-
lsapi_data *data;
|
411
|
-
Data_Get_Struct(self,lsapi_data, data);
|
412
|
-
*/
|
448
|
+
/*
|
449
|
+
* lsapi_data *data;
|
450
|
+
* Data_Get_Struct(self,lsapi_data, data);
|
451
|
+
*/
|
413
452
|
if (rb_safe_level() >= 4 && !OBJ_TAINTED(self))
|
414
453
|
{
|
415
454
|
rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
|
@@ -420,89 +459,251 @@ static VALUE lsapi_getc( VALUE self )
|
|
420
459
|
return INT2NUM( ch );
|
421
460
|
}
|
422
461
|
|
462
|
+
static inline int isBodyWriteToFile()
|
463
|
+
{
|
464
|
+
return ((s_body.bodyLen >= MAX_BODYBUF_LENGTH)? (1): (0));
|
465
|
+
}
|
466
|
+
|
467
|
+
//create a temp file and open it, if failed, fd = -1
|
468
|
+
static inline int createTempFile()
|
469
|
+
{
|
470
|
+
int fd = -1;
|
471
|
+
char *sfn = strdup(sTempFile);
|
472
|
+
|
473
|
+
if ((fd = mkstemp(sfn)) == -1)
|
474
|
+
{
|
475
|
+
fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
|
476
|
+
}
|
477
|
+
else
|
478
|
+
unlink(sfn);
|
479
|
+
|
480
|
+
free(sfn);
|
481
|
+
return fd;
|
482
|
+
}
|
483
|
+
|
484
|
+
//return 1 if error occured!
|
485
|
+
//if already created, always OK (0)
|
486
|
+
static int createBodyBuf()
|
487
|
+
{
|
488
|
+
int fd = -1;
|
489
|
+
if (s_body.bodyLen == -1)
|
490
|
+
{
|
491
|
+
s_body.bodyLen = LSAPI_GetReqBodyLen_r(&g_req);
|
492
|
+
//Error if get a zeor length, should not happen
|
493
|
+
if (s_body.bodyLen < 0)
|
494
|
+
{
|
495
|
+
//Wrong bode length will be treated as 0
|
496
|
+
s_body.bodyLen = 0;
|
497
|
+
}
|
498
|
+
|
499
|
+
if (s_body.bodyLen > 0)
|
500
|
+
{
|
501
|
+
if (isBodyWriteToFile())
|
502
|
+
{
|
503
|
+
//create file mapping
|
504
|
+
fd = createTempFile();
|
505
|
+
if (fd == -1)
|
506
|
+
{
|
507
|
+
return 1;
|
508
|
+
}
|
509
|
+
if (ftruncate(fd, s_body.bodyLen) == 0)
|
510
|
+
{
|
511
|
+
perror("ftruncate() failed. \n");
|
512
|
+
close(fd);
|
513
|
+
return 1;
|
514
|
+
}
|
515
|
+
s_body.bodyBuf = mmap(NULL, s_body.bodyLen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
516
|
+
if (s_body.bodyBuf == MAP_FAILED)
|
517
|
+
{
|
518
|
+
perror("File mapping failed. \n");
|
519
|
+
close(fd);
|
520
|
+
return 1;
|
521
|
+
}
|
522
|
+
close(fd); //close since needn't it anymore
|
523
|
+
}
|
524
|
+
else
|
525
|
+
{
|
526
|
+
s_body.bodyBuf = (char *)calloc(s_body.bodyLen, sizeof(char));
|
527
|
+
if (s_body.bodyBuf == NULL)
|
528
|
+
{
|
529
|
+
perror("Memory calloc error");
|
530
|
+
return 1;
|
531
|
+
}
|
532
|
+
}
|
533
|
+
}
|
534
|
+
}
|
535
|
+
|
536
|
+
return 0;
|
537
|
+
}
|
538
|
+
|
539
|
+
static inline int isAllBodyRead()
|
540
|
+
{
|
541
|
+
return (s_body.bodyCurrentLen < s_body.bodyLen)? 0 : 1;
|
542
|
+
}
|
543
|
+
|
544
|
+
static inline int isEofBodyBuf()
|
545
|
+
{
|
546
|
+
return (s_body.curPos < s_body.bodyLen) ? 0 : 1;
|
547
|
+
}
|
548
|
+
//try to read length as times pagesize (such as 8KB * N)
|
549
|
+
static int readBodyBuf(const int needRead)
|
550
|
+
{
|
551
|
+
const int blockSize = 8192;
|
552
|
+
char *buff = s_body.bodyBuf + s_body.bodyCurrentLen;
|
553
|
+
int nRead;
|
554
|
+
int readMore = (needRead + blockSize -1) / blockSize * blockSize;
|
555
|
+
int remain = LSAPI_GetReqBodyRemain_r( &g_req );
|
556
|
+
//Only when not enough left, needReadChange will be changed!!!
|
557
|
+
if (remain < readMore)
|
558
|
+
readMore = remain;
|
559
|
+
|
560
|
+
if ( readMore <= 0 )
|
561
|
+
return 0;
|
562
|
+
|
563
|
+
nRead = LSAPI_ReadReqBody_r(&g_req, buff, readMore);
|
564
|
+
if ( nRead > 0 )
|
565
|
+
s_body.bodyCurrentLen += nRead;
|
566
|
+
|
567
|
+
return nRead;
|
568
|
+
}
|
569
|
+
|
423
570
|
static VALUE lsapi_gets( VALUE self )
|
424
571
|
{
|
425
572
|
VALUE str;
|
426
|
-
int
|
427
|
-
|
428
|
-
|
573
|
+
const int blkSize = 4096;
|
574
|
+
int n;
|
575
|
+
char *p = NULL;
|
576
|
+
|
429
577
|
if (rb_safe_level() >= 4 && !OBJ_TAINTED(self))
|
430
578
|
{
|
431
579
|
rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
|
432
580
|
}
|
433
|
-
|
581
|
+
|
582
|
+
if (createBodyBuf() == 1)
|
583
|
+
{
|
434
584
|
return Qnil;
|
435
|
-
|
585
|
+
}
|
586
|
+
|
587
|
+
//comment:
|
588
|
+
while((p = memmem(s_body.bodyBuf + s_body.curPos, s_body.bodyCurrentLen - s_body.curPos, "\n", 1)) == NULL)
|
589
|
+
{
|
590
|
+
if (isAllBodyRead() == 1)
|
591
|
+
break;
|
592
|
+
//read one page and check, then reply
|
593
|
+
readBodyBuf(blkSize);
|
594
|
+
}
|
595
|
+
|
596
|
+
p = memmem(s_body.bodyBuf + s_body.curPos, s_body.bodyCurrentLen - s_body.curPos, "\n", 1);
|
597
|
+
if (p != NULL)
|
598
|
+
n = p - s_body.bodyBuf - s_body.curPos + 1;
|
599
|
+
else
|
600
|
+
n = s_body.bodyCurrentLen - s_body.curPos;
|
601
|
+
|
602
|
+
str = rb_str_buf_new( n );
|
436
603
|
OBJ_TAINT(str);
|
437
|
-
|
604
|
+
|
605
|
+
if (n > 0)
|
438
606
|
{
|
439
|
-
|
440
|
-
|
441
|
-
rb_str_buf_cat( str, buff, len );
|
442
|
-
|
607
|
+
rb_str_buf_cat( str, s_body.bodyBuf + s_body.curPos, n );
|
608
|
+
s_body.curPos += n;
|
443
609
|
}
|
444
|
-
|
445
|
-
return Qnil;
|
610
|
+
|
446
611
|
return str;
|
447
612
|
}
|
448
613
|
|
449
|
-
|
450
614
|
static VALUE lsapi_read(int argc, VALUE *argv, VALUE self)
|
451
615
|
{
|
452
616
|
VALUE str;
|
453
617
|
int n;
|
454
|
-
int
|
455
|
-
|
456
|
-
|
618
|
+
int needRead;
|
619
|
+
int nRead;
|
620
|
+
|
457
621
|
if (rb_safe_level() >= 4 && !OBJ_TAINTED(self))
|
458
622
|
{
|
459
623
|
rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
|
460
624
|
}
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
if ( remain <= 0 )
|
625
|
+
|
626
|
+
if (createBodyBuf() == 1)
|
627
|
+
{
|
465
628
|
return Qnil;
|
466
|
-
|
629
|
+
}
|
630
|
+
|
631
|
+
//we need to consider these 4 cases:
|
632
|
+
//1, need all data since argc == 0, we may have all data 2, or not
|
633
|
+
//3, need a length of data (argv >= 1), we may have enough data already read, 4, or not
|
634
|
+
if (argc == 0)
|
635
|
+
n = s_body.bodyLen - s_body.curPos;
|
636
|
+
else
|
467
637
|
{
|
468
|
-
n = NUM2INT(argv[0]);
|
469
|
-
if (
|
470
|
-
|
638
|
+
n = NUM2INT(argv[0]); //request that length from currentpos
|
639
|
+
if (n < 0)
|
640
|
+
return Qnil;
|
641
|
+
if (n > s_body.bodyLen - s_body.curPos)
|
642
|
+
n = s_body.bodyLen - s_body.curPos;
|
471
643
|
}
|
472
|
-
|
644
|
+
needRead = s_body.curPos + n - s_body.bodyCurrentLen;
|
645
|
+
if (needRead < 0)
|
646
|
+
needRead = 0;
|
647
|
+
|
648
|
+
str = rb_str_buf_new( n );
|
473
649
|
OBJ_TAINT(str);
|
474
|
-
|
650
|
+
if (n == 0)
|
651
|
+
return str;
|
652
|
+
|
653
|
+
//copy already have part first
|
654
|
+
if (n - needRead != 0)
|
475
655
|
{
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
656
|
+
rb_str_buf_cat( str, s_body.bodyBuf + s_body.curPos, n - needRead);
|
657
|
+
s_body.curPos += (n - needRead);
|
658
|
+
}
|
659
|
+
|
660
|
+
if (needRead > 0)
|
661
|
+
{
|
662
|
+
//try to read needRead, but may be less (changed) when read the end of the data
|
663
|
+
nRead = readBodyBuf(needRead);
|
664
|
+
if (nRead > 0)
|
484
665
|
{
|
485
|
-
|
486
|
-
|
666
|
+
n = ((nRead < needRead) ? nRead : needRead);
|
667
|
+
rb_str_buf_cat( str, s_body.bodyBuf + s_body.curPos, n );
|
668
|
+
s_body.curPos += n;
|
487
669
|
}
|
488
670
|
}
|
489
|
-
|
490
|
-
return Qnil;
|
671
|
+
|
491
672
|
return str;
|
492
673
|
}
|
493
674
|
|
494
|
-
static VALUE
|
675
|
+
static VALUE lsapi_rewind(VALUE self)
|
676
|
+
{
|
677
|
+
s_body.curPos = 0;
|
678
|
+
return self;
|
679
|
+
}
|
680
|
+
|
681
|
+
static VALUE lsapi_each(int argc, VALUE *argv, VALUE self)
|
495
682
|
{
|
496
|
-
|
497
|
-
|
683
|
+
VALUE str;
|
684
|
+
lsapi_rewind(self);
|
685
|
+
|
686
|
+
while(isEofBodyBuf() != 1)
|
687
|
+
{
|
688
|
+
str = lsapi_gets(self);
|
689
|
+
rb_yield(str);
|
690
|
+
}
|
691
|
+
return self;
|
498
692
|
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
693
|
+
}
|
694
|
+
|
695
|
+
static VALUE lsapi_eof(VALUE self)
|
696
|
+
{
|
697
|
+
/*
|
698
|
+
* lsapi_data *data;
|
699
|
+
*
|
700
|
+
* if (rb_safe_level() >= 4 && !OBJ_TAINTED(self))
|
701
|
+
* {
|
702
|
+
* rb_raise(rb_eSecurityError, "Insecure: operation on untainted IO");
|
703
|
+
}
|
704
|
+
Data_Get_Struct(self, lsapi_data, data);
|
705
|
+
*/
|
706
|
+
return (LSAPI_GetReqBodyRemain_r( &g_req ) <= 0) ? Qtrue : Qfalse;
|
506
707
|
}
|
507
708
|
|
508
709
|
static VALUE lsapi_binmode(VALUE self)
|
@@ -527,7 +728,22 @@ static VALUE lsapi_setsync(VALUE self,VALUE sync)
|
|
527
728
|
|
528
729
|
static VALUE lsapi_close(VALUE self)
|
529
730
|
{
|
530
|
-
LSAPI_Flush_r( &g_req );
|
731
|
+
LSAPI_Flush_r( &g_req );
|
732
|
+
if (isBodyWriteToFile())
|
733
|
+
{
|
734
|
+
//msync(s_body.bodyBuf, s_body.bodyLen, MS_SYNC);
|
735
|
+
//sleep(5);
|
736
|
+
munmap(s_body.bodyBuf, s_body.bodyLen);
|
737
|
+
}
|
738
|
+
else
|
739
|
+
free(s_body.bodyBuf);
|
740
|
+
|
741
|
+
s_body.bodyBuf = NULL;
|
742
|
+
s_body.bodyLen = -1;
|
743
|
+
s_body.bodyCurrentLen = 0;
|
744
|
+
s_body.curPos = 0;
|
745
|
+
//Should the temp be deleted here?!
|
746
|
+
|
531
747
|
return Qnil;
|
532
748
|
}
|
533
749
|
|
@@ -540,41 +756,86 @@ static VALUE lsapi_reopen( int argc, VALUE *argv, VALUE self)
|
|
540
756
|
/* constant silence hack */
|
541
757
|
orig_verbose = (VALUE)ruby_verbose;
|
542
758
|
ruby_verbose = Qnil;
|
543
|
-
|
759
|
+
|
544
760
|
rb_define_global_const("STDERR", orig_stderr);
|
545
|
-
|
761
|
+
|
546
762
|
ruby_verbose = (VALUE)orig_verbose;
|
547
|
-
|
763
|
+
|
548
764
|
return rb_funcall2( orig_stderr, rb_intern( "reopen" ), argc, argv );
|
549
|
-
|
765
|
+
|
550
766
|
}
|
551
767
|
return self;
|
552
768
|
}
|
553
769
|
|
770
|
+
static void readMaxBodyBufLength()
|
771
|
+
{
|
772
|
+
int n;
|
773
|
+
const char *p = getenv( "LSAPI_MAX_BODYBUF_LENGTH" );
|
774
|
+
if ( p )
|
775
|
+
{
|
776
|
+
n = atoi( p );
|
777
|
+
if (n > 0)
|
778
|
+
{
|
779
|
+
if (strstr(p, "M") || strstr(p, "m"))
|
780
|
+
MAX_BODYBUF_LENGTH = n * 1024 * 1024;
|
781
|
+
else if (strstr(p, "K") || strstr(p, "k"))
|
782
|
+
MAX_BODYBUF_LENGTH = n * 1024;
|
783
|
+
else
|
784
|
+
MAX_BODYBUF_LENGTH = n;
|
785
|
+
}
|
786
|
+
}
|
787
|
+
}
|
554
788
|
|
789
|
+
static void readTempFileTemplate()
|
790
|
+
{
|
791
|
+
const char *p = getenv( "LSAPI_TEMPFILE" );
|
792
|
+
if (p == NULL || strlen(p) > 1024 - 7)
|
793
|
+
p = "/tmp/lsapi.XXXXXX";
|
794
|
+
|
795
|
+
strcpy(sTempFile, p);
|
796
|
+
if (strlen(p) <= 6 || strcmp(p + (strlen(p) - 6), "XXXXXX") != 0)
|
797
|
+
strcat(sTempFile, ".XXXXXX");
|
798
|
+
}
|
555
799
|
|
800
|
+
static void initBodyBuf()
|
801
|
+
{
|
802
|
+
s_body.bodyBuf = NULL;
|
803
|
+
s_body.bodyLen = -1;
|
804
|
+
s_body.bodyCurrentLen = 0;
|
805
|
+
s_body.curPos = 0;
|
806
|
+
}
|
556
807
|
void Init_lsapi()
|
557
808
|
{
|
558
|
-
VALUE remove_env;
|
559
809
|
VALUE orig_verbose;
|
560
810
|
char * p;
|
561
|
-
|
811
|
+
int prefork = 0;
|
562
812
|
LSAPI_Init();
|
563
|
-
|
813
|
+
initBodyBuf();
|
814
|
+
|
815
|
+
readMaxBodyBufLength();
|
816
|
+
readTempFileTemplate();
|
817
|
+
|
818
|
+
#ifdef rb_thread_select
|
564
819
|
LSAPI_Init_Env_Parameters( rb_thread_select );
|
565
|
-
|
820
|
+
#else
|
821
|
+
LSAPI_Init_Env_Parameters( select );
|
822
|
+
#endif
|
823
|
+
|
566
824
|
s_pid = getpid();
|
567
|
-
|
568
|
-
p = getenv( "
|
825
|
+
|
826
|
+
p = getenv( "RACK_ROOT" );
|
569
827
|
if ( p )
|
570
828
|
{
|
571
829
|
if ( chdir( p ) == -1 )
|
572
830
|
perror( "chdir()" );
|
573
831
|
}
|
574
|
-
if ( p || getenv( "
|
832
|
+
if ( p || getenv( "RACK_ENV" ) )
|
575
833
|
s_fn_add_env = add_env_rails;
|
576
|
-
|
577
|
-
|
834
|
+
|
835
|
+
p = getenv("LSAPI_CHILDREN");
|
836
|
+
if (p && atoi(p) > 1)
|
837
|
+
prefork = 1;
|
838
|
+
|
578
839
|
orig_stdin = rb_stdin;
|
579
840
|
orig_stdout = rb_stdout;
|
580
841
|
orig_stderr = rb_stderr;
|
@@ -586,19 +847,20 @@ void Init_lsapi()
|
|
586
847
|
|
587
848
|
/* tell the garbage collector it is a global variable, do not recycle it. */
|
588
849
|
rb_global_variable(&env_copy);
|
589
|
-
|
590
|
-
rb_hash_aset( env_copy,rb_tainted_str_new("GATEWAY_INTERFACE", 17),
|
591
|
-
rb_tainted_str_new("CGI/1.2", 7));
|
592
850
|
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
*/
|
597
|
-
|
851
|
+
rb_hash_aset( env_copy,rb_tainted_str_new("GATEWAY_Irewindable_input.rbNTERFACE", 17),
|
852
|
+
rb_tainted_str_new("CGI/1.2", 7));
|
853
|
+
|
598
854
|
rb_define_global_function("eval_string_wrap", lsapi_eval_string_wrap, 1);
|
599
|
-
|
855
|
+
|
600
856
|
cLSAPI = rb_define_class("LSAPI", rb_cObject);
|
601
857
|
rb_define_singleton_method(cLSAPI, "accept", lsapi_s_accept, 0);
|
858
|
+
if (prefork)
|
859
|
+
{
|
860
|
+
rb_define_singleton_method(cLSAPI, "accept_new_connection", lsapi_s_accept_new_conn, 0);
|
861
|
+
rb_define_singleton_method(cLSAPI, "postfork_child", lsapi_s_postfork_child, 0);
|
862
|
+
rb_define_singleton_method(cLSAPI, "postfork_parent", lsapi_s_postfork_parent, 0);
|
863
|
+
}
|
602
864
|
|
603
865
|
rb_define_method(cLSAPI, "process", lsapi_process, 0 );
|
604
866
|
/* rb_define_method(cLSAPI, "initialize", lsapi_initialize, 0); */
|
@@ -612,11 +874,14 @@ void Init_lsapi()
|
|
612
874
|
rb_define_method(cLSAPI, "getc", lsapi_getc, 0);
|
613
875
|
/* rb_define_method(cLSAPI, "ungetc", lsapi_ungetc, 1); */
|
614
876
|
rb_define_method(cLSAPI, "gets", lsapi_gets, 0);
|
615
|
-
|
877
|
+
|
616
878
|
//TEST: adding readline function to make irb happy?
|
617
879
|
/*rb_define_method(cLSAPI, "readline", lsapi_gets, 0); */
|
618
|
-
|
880
|
+
|
619
881
|
rb_define_method(cLSAPI, "read", lsapi_read, -1);
|
882
|
+
rb_define_method(cLSAPI, "rewind", lsapi_rewind, 0);
|
883
|
+
rb_define_method(cLSAPI, "each", lsapi_each, 0);
|
884
|
+
|
620
885
|
rb_define_method(cLSAPI, "eof", lsapi_eof, 0);
|
621
886
|
rb_define_method(cLSAPI, "eof?", lsapi_eof, 0);
|
622
887
|
rb_define_method(cLSAPI, "close", lsapi_close, 0);
|
@@ -628,34 +893,34 @@ void Init_lsapi()
|
|
628
893
|
rb_define_method(cLSAPI, "sync=", lsapi_setsync, 1);
|
629
894
|
rb_define_method(cLSAPI, "reopen", lsapi_reopen, -1 );
|
630
895
|
|
631
|
-
|
896
|
+
|
632
897
|
s_req = Data_Make_Struct( cLSAPI, lsapi_data, lsapi_mark, free, s_req_data );
|
633
898
|
s_req_data->req = &g_req;
|
634
899
|
s_req_data->fn_write = LSAPI_Write_r;
|
635
900
|
rb_stdin = rb_stdout = s_req;
|
636
|
-
|
901
|
+
|
637
902
|
#if RUBY_VERSION_CODE < 180
|
638
903
|
rb_defout = s_req;
|
639
904
|
#endif
|
640
905
|
rb_global_variable(&s_req );
|
641
|
-
|
906
|
+
|
642
907
|
s_req_stderr = Data_Make_Struct( cLSAPI, lsapi_data, lsapi_mark, free, s_stderr_data );
|
643
908
|
s_stderr_data->req = &g_req;
|
644
909
|
s_stderr_data->fn_write = LSAPI_Write_Stderr_r;
|
645
910
|
rb_stderr = s_req_stderr;
|
646
911
|
rb_global_variable(&s_req_stderr );
|
647
|
-
|
912
|
+
|
648
913
|
/* constant silence hack */
|
649
914
|
orig_verbose = (VALUE)ruby_verbose;
|
650
915
|
ruby_verbose = Qnil;
|
651
|
-
|
916
|
+
|
652
917
|
lsapi_env = rb_hash_new();
|
653
918
|
clear_env();
|
654
919
|
/* redefine ENV using a hash table, should be faster than char **environment */
|
655
920
|
rb_define_global_const("ENV", lsapi_env);
|
656
921
|
|
657
922
|
rb_define_global_const("STDERR", rb_stderr);
|
658
|
-
|
923
|
+
|
659
924
|
ruby_verbose = (VALUE)orig_verbose;
|
660
925
|
|
661
926
|
return;
|