ruby-lsapi 4.2 → 5.2
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 +5 -5
- data/ext/lsapi/lsapidef.h +14 -13
- data/ext/lsapi/lsapilib.c +1155 -327
- data/ext/lsapi/lsapilib.h +73 -28
- data/ext/lsapi/lsruby.c +475 -211
- data/lsapi.gemspec +16 -0
- metadata +8 -7
data/ext/lsapi/lsapilib.h
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright (c) 2002-
|
|
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,7 +27,7 @@ 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
33
|
|
|
@@ -38,9 +38,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
38
38
|
extern "C" {
|
|
39
39
|
#endif
|
|
40
40
|
|
|
41
|
-
#include
|
|
42
|
-
#include <lsapidef.h>
|
|
41
|
+
#include "lsapidef.h"
|
|
43
42
|
|
|
43
|
+
#include <stddef.h>
|
|
44
44
|
#include <sys/time.h>
|
|
45
45
|
#include <sys/types.h>
|
|
46
46
|
|
|
@@ -52,8 +52,8 @@ struct LSAPI_key_value_pair
|
|
|
52
52
|
int valLen;
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
#define LSAPI_MAX_RESP_HEADERS
|
|
55
|
+
struct lsapi_child_status;
|
|
56
|
+
#define LSAPI_MAX_RESP_HEADERS 1000
|
|
57
57
|
|
|
58
58
|
typedef struct lsapi_request
|
|
59
59
|
{
|
|
@@ -65,7 +65,7 @@ typedef struct lsapi_request
|
|
|
65
65
|
|
|
66
66
|
char * m_pReqBuf;
|
|
67
67
|
int m_reqBufSize;
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
char * m_pRespBuf;
|
|
70
70
|
char * m_pRespBufEnd;
|
|
71
71
|
char * m_pRespBufPos;
|
|
@@ -73,12 +73,13 @@ typedef struct lsapi_request
|
|
|
73
73
|
char * m_pRespHeaderBuf;
|
|
74
74
|
char * m_pRespHeaderBufEnd;
|
|
75
75
|
char * m_pRespHeaderBufPos;
|
|
76
|
+
struct lsapi_child_status * child_status;
|
|
76
77
|
|
|
77
78
|
|
|
78
79
|
struct iovec * m_pIovec;
|
|
79
80
|
struct iovec * m_pIovecEnd;
|
|
80
81
|
struct iovec * m_pIovecCur;
|
|
81
|
-
struct iovec * m_pIovecToWrite;
|
|
82
|
+
struct iovec * m_pIovecToWrite;
|
|
82
83
|
|
|
83
84
|
struct lsapi_packet_header * m_respPktHeaderEnd;
|
|
84
85
|
|
|
@@ -90,7 +91,7 @@ typedef struct lsapi_request
|
|
|
90
91
|
|
|
91
92
|
struct lsapi_http_header_index * m_pHeaderIndex;
|
|
92
93
|
struct lsapi_header_offset * m_pUnknownHeader;
|
|
93
|
-
|
|
94
|
+
|
|
94
95
|
char * m_pScriptFile;
|
|
95
96
|
char * m_pScriptName;
|
|
96
97
|
char * m_pQueryString;
|
|
@@ -102,9 +103,9 @@ typedef struct lsapi_request
|
|
|
102
103
|
off_t m_reqBodyRead;
|
|
103
104
|
int m_bufProcessed;
|
|
104
105
|
int m_bufRead;
|
|
105
|
-
|
|
106
|
+
|
|
106
107
|
struct lsapi_packet_header m_respPktHeader[5];
|
|
107
|
-
|
|
108
|
+
|
|
108
109
|
struct lsapi_resp_header m_respHeader;
|
|
109
110
|
short m_respHeaderLen[LSAPI_MAX_RESP_HEADERS];
|
|
110
111
|
void * m_pAppData;
|
|
@@ -150,7 +151,6 @@ int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq,
|
|
|
150
151
|
LSAPI_CB_EnvHandler fn, void * arg );
|
|
151
152
|
|
|
152
153
|
char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name );
|
|
153
|
-
|
|
154
154
|
|
|
155
155
|
ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t len );
|
|
156
156
|
|
|
@@ -171,7 +171,7 @@ int LSAPI_Flush_r( LSAPI_Request * pReq );
|
|
|
171
171
|
|
|
172
172
|
int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, const char * pBuf, int len );
|
|
173
173
|
|
|
174
|
-
int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
|
|
174
|
+
int LSAPI_AppendRespHeader2_r( LSAPI_Request * pReq, const char * pHeaderName,
|
|
175
175
|
const char * pHeaderValue );
|
|
176
176
|
|
|
177
177
|
int LSAPI_ErrResponse_r( LSAPI_Request * pReq, int code, const char ** pRespHeaders,
|
|
@@ -248,6 +248,9 @@ static inline off_t LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq )
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
|
|
251
|
+
int LSAPI_End_Response_r(LSAPI_Request * pReq);
|
|
252
|
+
|
|
253
|
+
|
|
251
254
|
|
|
252
255
|
int LSAPI_Is_Listen(void);
|
|
253
256
|
|
|
@@ -276,28 +279,28 @@ static inline int LSAPI_ForeachSpecialEnv( LSAPI_CB_EnvHandler fn, void * arg )
|
|
|
276
279
|
static inline char * LSAPI_GetEnv( const char * name )
|
|
277
280
|
{ return LSAPI_GetEnv_r( &g_req, name ); }
|
|
278
281
|
|
|
279
|
-
static inline char * LSAPI_GetQueryString()
|
|
282
|
+
static inline char * LSAPI_GetQueryString(void)
|
|
280
283
|
{ return LSAPI_GetQueryString_r( &g_req ); }
|
|
281
284
|
|
|
282
|
-
static inline char * LSAPI_GetScriptFileName()
|
|
285
|
+
static inline char * LSAPI_GetScriptFileName(void)
|
|
283
286
|
{ return LSAPI_GetScriptFileName_r( &g_req ); }
|
|
284
287
|
|
|
285
|
-
static inline char * LSAPI_GetScriptName()
|
|
288
|
+
static inline char * LSAPI_GetScriptName(void)
|
|
286
289
|
{ return LSAPI_GetScriptName_r( &g_req ); }
|
|
287
290
|
|
|
288
|
-
static inline char * LSAPI_GetRequestMethod()
|
|
291
|
+
static inline char * LSAPI_GetRequestMethod(void)
|
|
289
292
|
{ return LSAPI_GetRequestMethod_r( &g_req ); }
|
|
290
293
|
|
|
291
|
-
static inline off_t LSAPI_GetReqBodyLen()
|
|
294
|
+
static inline off_t LSAPI_GetReqBodyLen(void)
|
|
292
295
|
{ return LSAPI_GetReqBodyLen_r( &g_req ); }
|
|
293
296
|
|
|
294
|
-
static inline off_t LSAPI_GetReqBodyRemain()
|
|
297
|
+
static inline off_t LSAPI_GetReqBodyRemain(void)
|
|
295
298
|
{ return LSAPI_GetReqBodyRemain_r( &g_req ); }
|
|
296
299
|
|
|
297
300
|
static inline ssize_t LSAPI_ReadReqBody( char * pBuf, size_t len )
|
|
298
301
|
{ return LSAPI_ReadReqBody_r( &g_req, pBuf, len ); }
|
|
299
302
|
|
|
300
|
-
static inline int LSAPI_ReqBodyGetChar()
|
|
303
|
+
static inline int LSAPI_ReqBodyGetChar(void)
|
|
301
304
|
{ return LSAPI_ReqBodyGetChar_r( &g_req ); }
|
|
302
305
|
|
|
303
306
|
static inline int LSAPI_ReqBodyGetLine( char * pBuf, int len, int *getLF )
|
|
@@ -313,13 +316,13 @@ static inline ssize_t LSAPI_Write( const char * pBuf, ssize_t len )
|
|
|
313
316
|
|
|
314
317
|
static inline ssize_t LSAPI_sendfile( int fdIn, off_t* off, size_t size )
|
|
315
318
|
{
|
|
316
|
-
return LSAPI_sendfile_r(&g_req, fdIn, off, size );
|
|
319
|
+
return LSAPI_sendfile_r(&g_req, fdIn, off, size );
|
|
317
320
|
}
|
|
318
321
|
|
|
319
322
|
static inline ssize_t LSAPI_Write_Stderr( const char * pBuf, ssize_t len )
|
|
320
323
|
{ return LSAPI_Write_Stderr_r( &g_req, pBuf, len ); }
|
|
321
324
|
|
|
322
|
-
static inline int LSAPI_Flush()
|
|
325
|
+
static inline int LSAPI_Flush(void)
|
|
323
326
|
{ return LSAPI_Flush_r( &g_req ); }
|
|
324
327
|
|
|
325
328
|
static inline int LSAPI_AppendRespHeader( char * pBuf, int len )
|
|
@@ -331,6 +334,9 @@ static inline int LSAPI_SetRespStatus( int code )
|
|
|
331
334
|
static inline int LSAPI_ErrResponse( int code, const char ** pRespHeaders, const char * pBody, int bodyLen )
|
|
332
335
|
{ return LSAPI_ErrResponse_r( &g_req, code, pRespHeaders, pBody, bodyLen ); }
|
|
333
336
|
|
|
337
|
+
static inline int LSAPI_End_Response(void)
|
|
338
|
+
{ return LSAPI_End_Response_r( &g_req ); }
|
|
339
|
+
|
|
334
340
|
int LSAPI_IsRunning(void);
|
|
335
341
|
|
|
336
342
|
int LSAPI_CreateListenSock( const char * pBind, int backlog );
|
|
@@ -343,6 +349,8 @@ void LSAPI_Set_Server_fd( int fd );
|
|
|
343
349
|
|
|
344
350
|
int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq );
|
|
345
351
|
|
|
352
|
+
void LSAPI_No_Check_ppid(void);
|
|
353
|
+
|
|
346
354
|
void LSAPI_Set_Max_Reqs( int reqs );
|
|
347
355
|
|
|
348
356
|
void LSAPI_Set_Max_Idle( int secs );
|
|
@@ -359,9 +367,46 @@ int LSAPI_Init_Env_Parameters( fn_select_t fp );
|
|
|
359
367
|
|
|
360
368
|
void LSAPI_Set_Slow_Req_Msecs( int msecs );
|
|
361
369
|
|
|
362
|
-
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
|
+
;
|
|
363
409
|
|
|
364
|
-
int LSAPI_is_suEXEC_Daemon();
|
|
365
410
|
|
|
366
411
|
#if defined (c_plusplus) || defined (__cplusplus)
|
|
367
412
|
}
|
data/ext/lsapi/lsruby.c
CHANGED
|
@@ -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
|
|
|
@@ -44,10 +47,8 @@ typedef struct lsapi_data
|
|
|
44
47
|
LSAPI_Request * req;
|
|
45
48
|
VALUE env;
|
|
46
49
|
ssize_t (* fn_write)( LSAPI_Request *, const char * , size_t );
|
|
47
|
-
|
|
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
|
{
|
|
@@ -224,18 +262,19 @@ static VALUE lsapi_eval_string_wrap(VALUE self, VALUE str)
|
|
|
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
|
|
|
@@ -312,8 +351,8 @@ 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
|
-
|
|
403
|
+
case T_NIL:
|
|
404
|
+
line = rb_str_new2("nil");
|
|
405
|
+
break;
|
|
406
|
+
case T_ARRAY:
|
|
368
407
|
#if defined( RUBY_19 ) || defined( RUBY_2 )
|
|
369
|
-
|
|
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,88 +459,250 @@ 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
|
-
|
|
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
|
+
*/
|
|
505
706
|
return (LSAPI_GetReqBodyRemain_r( &g_req ) <= 0) ? Qtrue : Qfalse;
|
|
506
707
|
}
|
|
507
708
|
|
|
@@ -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,42 +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();
|
|
813
|
+
initBodyBuf();
|
|
814
|
+
|
|
815
|
+
readMaxBodyBufLength();
|
|
816
|
+
readTempFileTemplate();
|
|
817
|
+
|
|
818
|
+
p = getenv("LSAPI_CHILDREN");
|
|
819
|
+
if (p && atoi(p) > 1)
|
|
820
|
+
prefork = 1;
|
|
563
821
|
|
|
564
|
-
|
|
822
|
+
#ifdef rb_thread_select
|
|
823
|
+
LSAPI_Init_Env_Parameters( rb_thread_select );
|
|
824
|
+
#else
|
|
565
825
|
LSAPI_Init_Env_Parameters( select );
|
|
566
|
-
|
|
826
|
+
#endif
|
|
827
|
+
|
|
567
828
|
s_pid = getpid();
|
|
568
|
-
|
|
569
|
-
p = getenv( "
|
|
829
|
+
|
|
830
|
+
p = getenv( "RACK_ROOT" );
|
|
570
831
|
if ( p )
|
|
571
832
|
{
|
|
572
833
|
if ( chdir( p ) == -1 )
|
|
573
834
|
perror( "chdir()" );
|
|
574
835
|
}
|
|
575
|
-
if ( p || getenv( "
|
|
836
|
+
if ( p || getenv( "RACK_ENV" ) )
|
|
576
837
|
s_fn_add_env = add_env_rails;
|
|
577
|
-
|
|
578
|
-
|
|
838
|
+
|
|
579
839
|
orig_stdin = rb_stdin;
|
|
580
840
|
orig_stdout = rb_stdout;
|
|
581
841
|
orig_stderr = rb_stderr;
|
|
@@ -587,19 +847,20 @@ void Init_lsapi()
|
|
|
587
847
|
|
|
588
848
|
/* tell the garbage collector it is a global variable, do not recycle it. */
|
|
589
849
|
rb_global_variable(&env_copy);
|
|
590
|
-
|
|
591
|
-
rb_hash_aset( env_copy,rb_tainted_str_new("GATEWAY_INTERFACE", 17),
|
|
592
|
-
rb_tainted_str_new("CGI/1.2", 7));
|
|
593
850
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
*/
|
|
598
|
-
|
|
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
|
+
|
|
599
854
|
rb_define_global_function("eval_string_wrap", lsapi_eval_string_wrap, 1);
|
|
600
|
-
|
|
855
|
+
|
|
601
856
|
cLSAPI = rb_define_class("LSAPI", rb_cObject);
|
|
602
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
|
+
}
|
|
603
864
|
|
|
604
865
|
rb_define_method(cLSAPI, "process", lsapi_process, 0 );
|
|
605
866
|
/* rb_define_method(cLSAPI, "initialize", lsapi_initialize, 0); */
|
|
@@ -613,11 +874,14 @@ void Init_lsapi()
|
|
|
613
874
|
rb_define_method(cLSAPI, "getc", lsapi_getc, 0);
|
|
614
875
|
/* rb_define_method(cLSAPI, "ungetc", lsapi_ungetc, 1); */
|
|
615
876
|
rb_define_method(cLSAPI, "gets", lsapi_gets, 0);
|
|
616
|
-
|
|
877
|
+
|
|
617
878
|
//TEST: adding readline function to make irb happy?
|
|
618
879
|
/*rb_define_method(cLSAPI, "readline", lsapi_gets, 0); */
|
|
619
|
-
|
|
880
|
+
|
|
620
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
|
+
|
|
621
885
|
rb_define_method(cLSAPI, "eof", lsapi_eof, 0);
|
|
622
886
|
rb_define_method(cLSAPI, "eof?", lsapi_eof, 0);
|
|
623
887
|
rb_define_method(cLSAPI, "close", lsapi_close, 0);
|
|
@@ -629,34 +893,34 @@ void Init_lsapi()
|
|
|
629
893
|
rb_define_method(cLSAPI, "sync=", lsapi_setsync, 1);
|
|
630
894
|
rb_define_method(cLSAPI, "reopen", lsapi_reopen, -1 );
|
|
631
895
|
|
|
632
|
-
|
|
896
|
+
|
|
633
897
|
s_req = Data_Make_Struct( cLSAPI, lsapi_data, lsapi_mark, free, s_req_data );
|
|
634
898
|
s_req_data->req = &g_req;
|
|
635
899
|
s_req_data->fn_write = LSAPI_Write_r;
|
|
636
900
|
rb_stdin = rb_stdout = s_req;
|
|
637
|
-
|
|
901
|
+
|
|
638
902
|
#if RUBY_VERSION_CODE < 180
|
|
639
903
|
rb_defout = s_req;
|
|
640
904
|
#endif
|
|
641
905
|
rb_global_variable(&s_req );
|
|
642
|
-
|
|
906
|
+
|
|
643
907
|
s_req_stderr = Data_Make_Struct( cLSAPI, lsapi_data, lsapi_mark, free, s_stderr_data );
|
|
644
908
|
s_stderr_data->req = &g_req;
|
|
645
909
|
s_stderr_data->fn_write = LSAPI_Write_Stderr_r;
|
|
646
910
|
rb_stderr = s_req_stderr;
|
|
647
911
|
rb_global_variable(&s_req_stderr );
|
|
648
|
-
|
|
912
|
+
|
|
649
913
|
/* constant silence hack */
|
|
650
914
|
orig_verbose = (VALUE)ruby_verbose;
|
|
651
915
|
ruby_verbose = Qnil;
|
|
652
|
-
|
|
916
|
+
|
|
653
917
|
lsapi_env = rb_hash_new();
|
|
654
918
|
clear_env();
|
|
655
919
|
/* redefine ENV using a hash table, should be faster than char **environment */
|
|
656
920
|
rb_define_global_const("ENV", lsapi_env);
|
|
657
921
|
|
|
658
922
|
rb_define_global_const("STDERR", rb_stderr);
|
|
659
|
-
|
|
923
|
+
|
|
660
924
|
ruby_verbose = (VALUE)orig_verbose;
|
|
661
925
|
|
|
662
926
|
return;
|