ruby-lsapi 1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +84 -0
- data/examples/lsapi_with_cgi.rb +14 -0
- data/examples/testlsapi.rb +11 -0
- data/ext/lsapi/extconf.rb +3 -0
- data/ext/lsapi/lsapidef.h +181 -0
- data/ext/lsapi/lsapilib.c +1181 -0
- data/ext/lsapi/lsapilib.h +296 -0
- data/ext/lsapi/lsruby.c +579 -0
- data/rails/dispatch.lsapi +12 -0
- data/scripts/lsruby_runner.rb +71 -0
- data/setup.rb +1585 -0
- metadata +60 -0
data/README
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
lsapi - LSAPI extension for Ruby
|
3
|
+
================================
|
4
|
+
|
5
|
+
Version 0.1.0
|
6
|
+
|
7
|
+
INSTALL
|
8
|
+
-------
|
9
|
+
|
10
|
+
$ ruby setup.rb config
|
11
|
+
$ ruby setup.rb setup
|
12
|
+
# ruby setup.rb install
|
13
|
+
|
14
|
+
USAGE
|
15
|
+
-----
|
16
|
+
|
17
|
+
General CGI scripts
|
18
|
+
```````````````````
|
19
|
+
The most efficient way to use LSAPI interface is to modify your CGI script,
|
20
|
+
you need to add the following to your CGI script
|
21
|
+
|
22
|
+
require 'lsapi'
|
23
|
+
|
24
|
+
while LSAPI.accept != nil
|
25
|
+
|
26
|
+
<your CGI script>
|
27
|
+
...
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
There is no need to change the way how CGI environment variables being
|
32
|
+
accessed in your script.
|
33
|
+
|
34
|
+
There are examples under examples/ folder.
|
35
|
+
|
36
|
+
|
37
|
+
Rails dispatcher
|
38
|
+
````````````````
|
39
|
+
A LSAPI dispatcher is available under rails/ folder, just copy it over to
|
40
|
+
the public/ folder of your Rails application, then change the rewrite rule
|
41
|
+
in public/.htaccess from
|
42
|
+
|
43
|
+
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
|
44
|
+
to
|
45
|
+
RewriteRule ^(.*)$ dispatch.lsapi [QSA,L]
|
46
|
+
|
47
|
+
It is very expensive to start a fresh Rails application process, while on
|
48
|
+
the other hand, server hardware resources can be used more efficiently with
|
49
|
+
dynamic spawning. In order to solve this conflict, instead of spawning a
|
50
|
+
fresh Rails process, LSAPI dispatcher can dynamically fork children processes
|
51
|
+
off an initialized Rails process.
|
52
|
+
|
53
|
+
When you configure dispatch.lsapi as a LSAPI application, you should add
|
54
|
+
an extra environment variable
|
55
|
+
|
56
|
+
LSAPI_CHILDREN=n
|
57
|
+
|
58
|
+
n should match the "Max Conns" configuration entry of the LSAPI application.
|
59
|
+
|
60
|
+
|
61
|
+
Ruby Script Runner
|
62
|
+
``````````````````
|
63
|
+
If you don't want to change your Ruby CGI code, you can use our Ruby script
|
64
|
+
runner under scripts/ folder. You need to configure lsruby_runner.rb as a
|
65
|
+
LSAPI application, then add a script handler for "rb" suffix.
|
66
|
+
|
67
|
+
|
68
|
+
License
|
69
|
+
-------
|
70
|
+
|
71
|
+
LSAPI library code is under BSD license
|
72
|
+
|
73
|
+
LSAPI ruby extension code is under Ruby license
|
74
|
+
|
75
|
+
* ((<URL:http://www.ruby-lang.org/ja/LICENSE.txt>)) (Japanese)
|
76
|
+
* ((<URL:http://www.ruby-lang.org/en/LICENSE.txt>)) (English)
|
77
|
+
|
78
|
+
|
79
|
+
Copyright
|
80
|
+
---------
|
81
|
+
|
82
|
+
Copyright (C) 2006 Lite Speed Technologes Inc.
|
83
|
+
|
84
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
|
3
|
+
require 'lsapi'
|
4
|
+
|
5
|
+
$count = 0;
|
6
|
+
|
7
|
+
while LSAPI.accept != nil
|
8
|
+
print "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\nHello World! \##{$count}<br>\r\n"
|
9
|
+
ENV.each_pair {|key, value| print "#{key} is #{value}<br>\r\n" }
|
10
|
+
$count = $count + 1
|
11
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (c) 2005, Lite Speed Technologies Inc.
|
3
|
+
All rights reserved.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions are
|
7
|
+
met:
|
8
|
+
|
9
|
+
* Redistributions of source code must retain the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer.
|
11
|
+
* Redistributions in binary form must reproduce the above
|
12
|
+
copyright notice, this list of conditions and the following
|
13
|
+
disclaimer in the documentation and/or other materials provided
|
14
|
+
with the distribution.
|
15
|
+
* Neither the name of the Lite Speed Technologies Inc nor the
|
16
|
+
names of its contributors may be used to endorse or promote
|
17
|
+
products derived from this software without specific prior
|
18
|
+
written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
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.
|
31
|
+
*/
|
32
|
+
|
33
|
+
/***************************************************************************
|
34
|
+
$Id: lsapidef.h,v 1.14 2005/09/29 23:51:06 gwang Exp $
|
35
|
+
-------------------
|
36
|
+
begin : Thu Feb 10 2005
|
37
|
+
author : George Wang
|
38
|
+
email : gwang@litespeedtech.com
|
39
|
+
***************************************************************************/
|
40
|
+
|
41
|
+
#ifndef _LSAPIDEF_H_
|
42
|
+
#define _LSAPIDEF_H_
|
43
|
+
|
44
|
+
#include <inttypes.h>
|
45
|
+
|
46
|
+
#if defined (c_plusplus) || defined (__cplusplus)
|
47
|
+
extern "C" {
|
48
|
+
#endif
|
49
|
+
|
50
|
+
enum
|
51
|
+
{
|
52
|
+
H_ACCEPT = 0,
|
53
|
+
H_ACC_CHARSET,
|
54
|
+
H_ACC_ENCODING,
|
55
|
+
H_ACC_LANG,
|
56
|
+
H_AUTHORIZATION,
|
57
|
+
H_CONNECTION,
|
58
|
+
H_CONTENT_TYPE,
|
59
|
+
H_CONTENT_LENGTH,
|
60
|
+
H_COOKIE,
|
61
|
+
H_COOKIE2,
|
62
|
+
H_HOST,
|
63
|
+
H_PRAGMA,
|
64
|
+
H_REFERER,
|
65
|
+
H_USERAGENT,
|
66
|
+
H_CACHE_CTRL,
|
67
|
+
H_IF_MODIFIED_SINCE,
|
68
|
+
H_IF_MATCH,
|
69
|
+
H_IF_NO_MATCH,
|
70
|
+
H_IF_RANGE,
|
71
|
+
H_IF_UNMOD_SINCE,
|
72
|
+
H_KEEP_ALIVE,
|
73
|
+
H_RANGE,
|
74
|
+
H_X_FORWARDED_FOR,
|
75
|
+
H_VIA,
|
76
|
+
H_TRANSFER_ENCODING
|
77
|
+
|
78
|
+
};
|
79
|
+
#define LSAPI_SOCK_FILENO 0
|
80
|
+
|
81
|
+
#define LSAPI_VERSION_B0 'L'
|
82
|
+
#define LSAPI_VERSION_B1 'S'
|
83
|
+
|
84
|
+
//Values for m_flag in lsapi_packet_header
|
85
|
+
#define LSAPI_ENDIAN_LITTLE 0
|
86
|
+
#define LSAPI_ENDIAN_BIG 1
|
87
|
+
#define LSAPI_ENDIAN_BIT 1
|
88
|
+
|
89
|
+
#if defined(__i386__)||defined( __x86_64 )||defined( __x86_64__ )
|
90
|
+
#define LSAPI_ENDIAN LSAPI_ENDIAN_LITTLE
|
91
|
+
#else
|
92
|
+
#define LSAPI_ENDIAN LSAPI_ENDIAN_BIG
|
93
|
+
#endif
|
94
|
+
|
95
|
+
//Values for m_type in lsapi_packet_header
|
96
|
+
#define LSAPI_BEGIN_REQUEST 1
|
97
|
+
#define LSAPI_ABORT_REQUEST 2
|
98
|
+
#define LSAPI_RESP_HEADER 3
|
99
|
+
#define LSAPI_RESP_STREAM 4
|
100
|
+
#define LSAPI_RESP_END 5
|
101
|
+
#define LSAPI_STDERR_STREAM 6
|
102
|
+
#define LSAPI_REQ_RECEIVED 7
|
103
|
+
|
104
|
+
|
105
|
+
#define LSAPI_MAX_HEADER_LEN 65535
|
106
|
+
#define LSAPI_MAX_DATA_PACKET_LEN 16384
|
107
|
+
|
108
|
+
#define LSAPI_RESP_HTTP_HEADER_MAX 4096
|
109
|
+
#define LSAPI_PACKET_HEADER_LEN 8
|
110
|
+
|
111
|
+
|
112
|
+
struct lsapi_packet_header
|
113
|
+
{
|
114
|
+
char m_versionB0; //LSAPI protocol version
|
115
|
+
char m_versionB1;
|
116
|
+
char m_type;
|
117
|
+
char m_flag;
|
118
|
+
union
|
119
|
+
{
|
120
|
+
int32_t m_iLen; //include this header
|
121
|
+
char m_bytes[4];
|
122
|
+
}m_packetLen;
|
123
|
+
};
|
124
|
+
|
125
|
+
// LSAPI request header packet
|
126
|
+
//
|
127
|
+
// 1. struct lsapi_req_header
|
128
|
+
// 2. struct lsapi_http_header_index
|
129
|
+
// 3. lsapi_header_offset * unknownHeaders
|
130
|
+
// 4. org http request header
|
131
|
+
// 5. request body if available
|
132
|
+
|
133
|
+
struct lsapi_req_header
|
134
|
+
{
|
135
|
+
struct lsapi_packet_header m_pktHeader;
|
136
|
+
|
137
|
+
int32_t m_httpHeaderLen;
|
138
|
+
int32_t m_reqBodyLen;
|
139
|
+
int32_t m_scriptFileOff; //path to the script file.
|
140
|
+
int32_t m_scriptNameOff; //decrypted URI, without pathinfo,
|
141
|
+
int32_t m_queryStringOff; //Query string inside env
|
142
|
+
int32_t m_requestMethodOff;
|
143
|
+
int32_t m_cntUnknownHeaders;
|
144
|
+
int32_t m_cntEnv;
|
145
|
+
int32_t m_cntSpecialEnv;
|
146
|
+
} ;
|
147
|
+
|
148
|
+
|
149
|
+
struct lsapi_http_header_index
|
150
|
+
{
|
151
|
+
int16_t m_headerLen[H_TRANSFER_ENCODING+1];
|
152
|
+
int32_t m_headerOff[H_TRANSFER_ENCODING+1];
|
153
|
+
} ;
|
154
|
+
|
155
|
+
struct lsapi_header_offset
|
156
|
+
{
|
157
|
+
int32_t nameOff;
|
158
|
+
int32_t nameLen;
|
159
|
+
int32_t valueOff;
|
160
|
+
int32_t valueLen;
|
161
|
+
} ;
|
162
|
+
|
163
|
+
struct lsapi_resp_info
|
164
|
+
{
|
165
|
+
int32_t m_cntHeaders;
|
166
|
+
int32_t m_status;
|
167
|
+
};
|
168
|
+
|
169
|
+
struct lsapi_resp_header
|
170
|
+
{
|
171
|
+
struct lsapi_packet_header m_pktHeader;
|
172
|
+
struct lsapi_resp_info m_respInfo;
|
173
|
+
};
|
174
|
+
|
175
|
+
#if defined (c_plusplus) || defined (__cplusplus)
|
176
|
+
}
|
177
|
+
#endif
|
178
|
+
|
179
|
+
|
180
|
+
#endif
|
181
|
+
|
@@ -0,0 +1,1181 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (c) 2005, Lite Speed Technologies Inc.
|
3
|
+
All rights reserved.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions are
|
7
|
+
met:
|
8
|
+
|
9
|
+
* Redistributions of source code must retain the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer.
|
11
|
+
* Redistributions in binary form must reproduce the above
|
12
|
+
copyright notice, this list of conditions and the following
|
13
|
+
disclaimer in the documentation and/or other materials provided
|
14
|
+
with the distribution.
|
15
|
+
* Neither the name of the Lite Speed Technologies Inc nor the
|
16
|
+
names of its contributors may be used to endorse or promote
|
17
|
+
products derived from this software without specific prior
|
18
|
+
written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
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.
|
31
|
+
*/
|
32
|
+
|
33
|
+
/***************************************************************************
|
34
|
+
lsapilib.c - description
|
35
|
+
-------------------
|
36
|
+
begin : Mon Feb 21 2005
|
37
|
+
copyright : (C) 2005 by George Wang
|
38
|
+
email : gwang@litespeedtech.com
|
39
|
+
***************************************************************************/
|
40
|
+
|
41
|
+
|
42
|
+
#include <lsapilib.h>
|
43
|
+
|
44
|
+
#include <ctype.h>
|
45
|
+
#include <errno.h>
|
46
|
+
#include <fcntl.h>
|
47
|
+
|
48
|
+
//#include <arpa/inet.h>
|
49
|
+
#include <sys/types.h>
|
50
|
+
#include <netinet/in.h>
|
51
|
+
#include <netinet/tcp.h>
|
52
|
+
#include <signal.h>
|
53
|
+
#include <stdlib.h>
|
54
|
+
#include <stdio.h>
|
55
|
+
#include <string.h>
|
56
|
+
#include <sys/socket.h>
|
57
|
+
#include <sys/uio.h>
|
58
|
+
#include <unistd.h>
|
59
|
+
|
60
|
+
#define LSAPI_ST_REQ_HEADER 1
|
61
|
+
#define LSAPI_ST_REQ_BODY 2
|
62
|
+
#define LSAPI_ST_RESP_HEADER 4
|
63
|
+
#define LSAPI_ST_RESP_BODY 8
|
64
|
+
|
65
|
+
#define LSAPI_RESP_BUF_SIZE 8192
|
66
|
+
#define LSAPI_INIT_RESP_HEADER_LEN 4096
|
67
|
+
|
68
|
+
|
69
|
+
static int g_inited = 0;
|
70
|
+
static int g_running = 1;
|
71
|
+
LSAPI_Request g_req;
|
72
|
+
|
73
|
+
void Flush_RespBuf_r( LSAPI_Request * pReq );
|
74
|
+
|
75
|
+
static const char *CGI_HEADERS[H_TRANSFER_ENCODING+1] =
|
76
|
+
{
|
77
|
+
"HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET",
|
78
|
+
"HTTP_ACCEPT_ENCODING",
|
79
|
+
"HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHORIZATION",
|
80
|
+
"HTTP_CONNECTION", "CONTENT_TYPE",
|
81
|
+
"CONTENT_LENGTH", "HTTP_COOKIE", "HTTP_COOKIE2",
|
82
|
+
"HTTP_HOST", "HTTP_PRAGMA",
|
83
|
+
"HTTP_REFERER", "HTTP_USER_AGENT",
|
84
|
+
"HTTP_CACHE_CTRL",
|
85
|
+
"HTTP_IF_MODIFIED_SINCE", "HTTP_IF_MATCH",
|
86
|
+
"HTTP_IF_NONE_MATCH",
|
87
|
+
"HTTP_IF_RANGE",
|
88
|
+
"HTTP_IF_UNMODIFIED_SINCE",
|
89
|
+
"HTTP_KEEPALIVE",
|
90
|
+
"HTTP_RANGE",
|
91
|
+
"HTTP_X_FORWARDED_FOR",
|
92
|
+
"HTTP_VIA",
|
93
|
+
"HTTP_TRANSFER_ENCODING"
|
94
|
+
};
|
95
|
+
|
96
|
+
static int CGI_HEADER_LEN[H_TRANSFER_ENCODING+1] =
|
97
|
+
{ 11, 19, 20, 20, 18, 15, 12, 14, 11, 12, 9, 11, 12, 15, 15,
|
98
|
+
22, 13, 18, 13, 24, 14, 10, 20, 8, 22 };
|
99
|
+
|
100
|
+
static void lsapi_sigpipe( int sig )
|
101
|
+
{
|
102
|
+
}
|
103
|
+
static void lsapi_siguser1( int sig )
|
104
|
+
{
|
105
|
+
g_running = 0;
|
106
|
+
}
|
107
|
+
|
108
|
+
#ifndef sighandler_t
|
109
|
+
typedef void (*sighandler_t)(int);
|
110
|
+
#endif
|
111
|
+
|
112
|
+
static void lsapi_signal(int signo, sighandler_t handler)
|
113
|
+
{
|
114
|
+
struct sigaction sa;
|
115
|
+
|
116
|
+
sigaction(signo, NULL, &sa);
|
117
|
+
|
118
|
+
if (sa.sa_handler == SIG_DFL)
|
119
|
+
{
|
120
|
+
sigemptyset(&sa.sa_mask);
|
121
|
+
sa.sa_flags = 0;
|
122
|
+
sa.sa_handler = handler;
|
123
|
+
sigaction(signo, &sa, NULL);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
static inline void lsapi_buildPacketHeader( struct lsapi_packet_header * pHeader,
|
129
|
+
char type, int len )
|
130
|
+
{
|
131
|
+
pHeader->m_versionB0 = LSAPI_VERSION_B0; //LSAPI protocol version
|
132
|
+
pHeader->m_versionB1 = LSAPI_VERSION_B1;
|
133
|
+
pHeader->m_type = type;
|
134
|
+
pHeader->m_flag = LSAPI_ENDIAN;
|
135
|
+
pHeader->m_packetLen.m_iLen = len;
|
136
|
+
}
|
137
|
+
|
138
|
+
static int lsapi_close( int fd )
|
139
|
+
{
|
140
|
+
int ret;
|
141
|
+
while( 1 )
|
142
|
+
{
|
143
|
+
ret = close( fd );
|
144
|
+
if (( ret == -1 )&&( errno == EINTR )&&(g_running))
|
145
|
+
continue;
|
146
|
+
return ret;
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
static inline int lsapi_read( int fd, void * pBuf, int len )
|
151
|
+
{
|
152
|
+
int ret;
|
153
|
+
while( 1 )
|
154
|
+
{
|
155
|
+
ret = read( fd, (char *)pBuf, len );
|
156
|
+
if (( ret == -1 )&&( errno == EINTR )&&(g_running))
|
157
|
+
continue;
|
158
|
+
return ret;
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
//static int lsapi_write( int fd, const void * pBuf, int len )
|
163
|
+
//{
|
164
|
+
// int ret;
|
165
|
+
// const char * pCur;
|
166
|
+
// const char * pEnd;
|
167
|
+
// if ( len == 0 )
|
168
|
+
// return 0;
|
169
|
+
// pCur = (const char *)pBuf;
|
170
|
+
// pEnd = pCur + len;
|
171
|
+
// while( g_running && (pCur < pEnd) )
|
172
|
+
// {
|
173
|
+
// ret = write( fd, pCur, pEnd - pCur );
|
174
|
+
// if ( ret >= 0)
|
175
|
+
// pCur += ret;
|
176
|
+
// else if (( ret == -1 )&&( errno != EINTR ))
|
177
|
+
// return ret;
|
178
|
+
// }
|
179
|
+
// return pCur - (const char *)pBuf;
|
180
|
+
//}
|
181
|
+
|
182
|
+
static int lsapi_writev( int fd, struct iovec ** pVec, int count, int totalLen )
|
183
|
+
{
|
184
|
+
int ret;
|
185
|
+
int left = totalLen;
|
186
|
+
int n = count;
|
187
|
+
while(( left > 0 )&&g_running )
|
188
|
+
{
|
189
|
+
ret = writev( fd, *pVec, n );
|
190
|
+
if ( ret > 0 )
|
191
|
+
{
|
192
|
+
left -= ret;
|
193
|
+
if (( left <= 0)||( !g_running ))
|
194
|
+
return totalLen - left;
|
195
|
+
while( ret > 0 )
|
196
|
+
{
|
197
|
+
if ( (*pVec)->iov_len <= ret )
|
198
|
+
{
|
199
|
+
ret -= (*pVec)->iov_len;
|
200
|
+
++(*pVec);
|
201
|
+
}
|
202
|
+
else
|
203
|
+
{
|
204
|
+
(*pVec)->iov_base = (char *)(*pVec)->iov_base + ret;
|
205
|
+
(*pVec)->iov_len -= ret;
|
206
|
+
break;
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
210
|
+
else if (( ret == -1 )&&( errno != EINTR ))
|
211
|
+
return ret;
|
212
|
+
}
|
213
|
+
return totalLen - left;
|
214
|
+
}
|
215
|
+
|
216
|
+
//static int getTotalLen( struct iovec * pVec, int count )
|
217
|
+
//{
|
218
|
+
// struct iovec * pEnd = pVec + count;
|
219
|
+
// int total = 0;
|
220
|
+
// while( pVec < pEnd )
|
221
|
+
// {
|
222
|
+
// total += pVec->iov_len;
|
223
|
+
// ++pVec;
|
224
|
+
// }
|
225
|
+
// return total;
|
226
|
+
//}
|
227
|
+
|
228
|
+
|
229
|
+
static inline int allocateBuf( LSAPI_Request * pReq, int size )
|
230
|
+
{
|
231
|
+
char * pBuf = (char *)realloc( pReq->m_pReqBuf, size );
|
232
|
+
if ( pBuf )
|
233
|
+
{
|
234
|
+
pReq->m_pReqBuf = pBuf;
|
235
|
+
pReq->m_reqBufSize = size;
|
236
|
+
pReq->m_pHeader = (struct lsapi_req_header *)pReq->m_pReqBuf;
|
237
|
+
return 0;
|
238
|
+
}
|
239
|
+
return -1;
|
240
|
+
}
|
241
|
+
|
242
|
+
|
243
|
+
static int allocateIovec( LSAPI_Request * pReq, int n )
|
244
|
+
{
|
245
|
+
struct iovec * p = (struct iovec *)realloc(
|
246
|
+
pReq->m_pIovec, sizeof(struct iovec) * n );
|
247
|
+
if ( !p )
|
248
|
+
return -1;
|
249
|
+
pReq->m_pIovecToWrite = p + ( pReq->m_pIovecToWrite - pReq->m_pIovec );
|
250
|
+
pReq->m_pIovecCur = p + ( pReq->m_pIovecCur - pReq->m_pIovec );
|
251
|
+
pReq->m_pIovec = p;
|
252
|
+
pReq->m_pIovecEnd = p + n;
|
253
|
+
return 0;
|
254
|
+
}
|
255
|
+
|
256
|
+
static int allocateRespHeaderBuf( LSAPI_Request * pReq, int size )
|
257
|
+
{
|
258
|
+
char * p = (char *)realloc( pReq->m_pRespHeaderBuf, size );
|
259
|
+
if ( !p )
|
260
|
+
return -1;
|
261
|
+
pReq->m_pRespHeaderBufPos = p + ( pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf );
|
262
|
+
pReq->m_pRespHeaderBuf = p;
|
263
|
+
pReq->m_pRespHeaderBufEnd = p + size;
|
264
|
+
return 0;
|
265
|
+
}
|
266
|
+
|
267
|
+
|
268
|
+
static inline int verifyHeader( struct lsapi_packet_header * pHeader, char pktType )
|
269
|
+
{
|
270
|
+
if (( LSAPI_VERSION_B0 != pHeader->m_versionB0 )||
|
271
|
+
( LSAPI_VERSION_B1 != pHeader->m_versionB1 )||
|
272
|
+
( pktType != pHeader->m_type ))
|
273
|
+
return -1;
|
274
|
+
if ( LSAPI_ENDIAN != (pHeader->m_flag & LSAPI_ENDIAN_BIT ))
|
275
|
+
{
|
276
|
+
register char b;
|
277
|
+
b = pHeader->m_packetLen.m_bytes[0];
|
278
|
+
pHeader->m_packetLen.m_bytes[0] = pHeader->m_packetLen.m_bytes[3];
|
279
|
+
pHeader->m_packetLen.m_bytes[3] = b;
|
280
|
+
b = pHeader->m_packetLen.m_bytes[1];
|
281
|
+
pHeader->m_packetLen.m_bytes[1] = pHeader->m_packetLen.m_bytes[2];
|
282
|
+
pHeader->m_packetLen.m_bytes[2] = b;
|
283
|
+
}
|
284
|
+
return pHeader->m_packetLen.m_iLen;
|
285
|
+
}
|
286
|
+
|
287
|
+
static int allocateEnvList( struct LSAPI_key_value_pair ** pEnvList,
|
288
|
+
int *curSize, int newSize )
|
289
|
+
{
|
290
|
+
struct LSAPI_key_value_pair * pBuf;
|
291
|
+
if ( *curSize >= newSize )
|
292
|
+
return 0;
|
293
|
+
if ( newSize > 8192 )
|
294
|
+
return -1;
|
295
|
+
pBuf = (struct LSAPI_key_value_pair *)realloc( *pEnvList, newSize *
|
296
|
+
sizeof(struct LSAPI_key_value_pair) );
|
297
|
+
if ( pBuf )
|
298
|
+
{
|
299
|
+
*pEnvList = pBuf;
|
300
|
+
*curSize = newSize;
|
301
|
+
return 0;
|
302
|
+
}
|
303
|
+
else
|
304
|
+
return -1;
|
305
|
+
|
306
|
+
}
|
307
|
+
|
308
|
+
static inline int isPipe( int fd )
|
309
|
+
{
|
310
|
+
char achPeer[128];
|
311
|
+
socklen_t len = 128;
|
312
|
+
if (( getpeername( fd, (struct sockaddr *)achPeer, &len ) != 0 )&&
|
313
|
+
( errno == ENOTCONN ))
|
314
|
+
return 0;
|
315
|
+
else
|
316
|
+
return 1;
|
317
|
+
}
|
318
|
+
|
319
|
+
static int parseEnv( struct LSAPI_key_value_pair * pEnvList, int count,
|
320
|
+
char **pBegin, char * pEnd )
|
321
|
+
{
|
322
|
+
struct LSAPI_key_value_pair * pEnvEnd;
|
323
|
+
int keyLen = 0, valLen = 0;
|
324
|
+
if ( count > 8192 )
|
325
|
+
return -1;
|
326
|
+
pEnvEnd = pEnvList + count;
|
327
|
+
while( pEnvList != pEnvEnd )
|
328
|
+
{
|
329
|
+
if ( pEnd - *pBegin < 4 )
|
330
|
+
return -1;
|
331
|
+
keyLen = *((unsigned char *)((*pBegin)++));
|
332
|
+
keyLen = (keyLen << 8) + *((unsigned char *)((*pBegin)++));
|
333
|
+
valLen = *((unsigned char *)((*pBegin)++));
|
334
|
+
valLen = (valLen << 8) + *((unsigned char *)((*pBegin)++));
|
335
|
+
if ( *pBegin + keyLen + valLen > pEnd )
|
336
|
+
return -1;
|
337
|
+
if (( !keyLen )||( !valLen ))
|
338
|
+
return -1;
|
339
|
+
|
340
|
+
pEnvList->pKey = *pBegin;
|
341
|
+
*pBegin += keyLen;
|
342
|
+
pEnvList->pValue = *pBegin;
|
343
|
+
*pBegin += valLen;
|
344
|
+
|
345
|
+
pEnvList->keyLen = keyLen - 1;
|
346
|
+
pEnvList->valLen = valLen - 1;
|
347
|
+
++pEnvList;
|
348
|
+
}
|
349
|
+
if ( memcmp( *pBegin, "\0\0\0\0", 4 ) != 0 )
|
350
|
+
return -1;
|
351
|
+
*pBegin += 4;
|
352
|
+
return 0;
|
353
|
+
}
|
354
|
+
|
355
|
+
static inline void swapIntEndian( int * pInteger )
|
356
|
+
{
|
357
|
+
char * p = (char *)pInteger;
|
358
|
+
register char b;
|
359
|
+
b = p[0];
|
360
|
+
p[0] = p[3];
|
361
|
+
p[3] = b;
|
362
|
+
b = p[1];
|
363
|
+
p[1] = p[2];
|
364
|
+
p[2] = b;
|
365
|
+
|
366
|
+
}
|
367
|
+
|
368
|
+
static inline void fixEndian( LSAPI_Request * pReq )
|
369
|
+
{
|
370
|
+
struct lsapi_req_header *p= pReq->m_pHeader;
|
371
|
+
swapIntEndian( &p->m_httpHeaderLen );
|
372
|
+
swapIntEndian( &p->m_reqBodyLen );
|
373
|
+
swapIntEndian( &p->m_scriptFileOff );
|
374
|
+
swapIntEndian( &p->m_scriptNameOff );
|
375
|
+
swapIntEndian( &p->m_queryStringOff );
|
376
|
+
swapIntEndian( &p->m_requestMethodOff );
|
377
|
+
swapIntEndian( &p->m_cntUnknownHeaders );
|
378
|
+
swapIntEndian( &p->m_cntEnv );
|
379
|
+
swapIntEndian( &p->m_cntSpecialEnv );
|
380
|
+
}
|
381
|
+
|
382
|
+
static void fixHeaderIndexEndian( LSAPI_Request * pReq )
|
383
|
+
{
|
384
|
+
int i;
|
385
|
+
for( i = 0; i < H_TRANSFER_ENCODING; ++i )
|
386
|
+
{
|
387
|
+
if ( pReq->m_pHeaderIndex->m_headerOff[i] )
|
388
|
+
{
|
389
|
+
register char b;
|
390
|
+
char * p = (char *)(&pReq->m_pHeaderIndex->m_headerLen[i]);
|
391
|
+
b = p[0];
|
392
|
+
p[0] = p[1];
|
393
|
+
p[1] = b;
|
394
|
+
swapIntEndian( &pReq->m_pHeaderIndex->m_headerOff[i] );
|
395
|
+
}
|
396
|
+
}
|
397
|
+
if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 )
|
398
|
+
{
|
399
|
+
struct lsapi_header_offset * pCur, *pEnd;
|
400
|
+
pCur = pReq->m_pUnknownHeader;
|
401
|
+
pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders;
|
402
|
+
while( pCur < pEnd )
|
403
|
+
{
|
404
|
+
swapIntEndian( &pCur->nameOff );
|
405
|
+
swapIntEndian( &pCur->nameLen );
|
406
|
+
swapIntEndian( &pCur->valueOff );
|
407
|
+
swapIntEndian( &pCur->valueLen );
|
408
|
+
++pCur;
|
409
|
+
}
|
410
|
+
}
|
411
|
+
}
|
412
|
+
|
413
|
+
static int parseRequest( LSAPI_Request * pReq, int totalLen )
|
414
|
+
{
|
415
|
+
int shouldFixEndian;
|
416
|
+
char * pBegin = pReq->m_pReqBuf + sizeof( struct lsapi_req_header );
|
417
|
+
char * pEnd = pReq->m_pReqBuf + totalLen;
|
418
|
+
shouldFixEndian = ( LSAPI_ENDIAN != (
|
419
|
+
pReq->m_pHeader->m_pktHeader.m_flag & LSAPI_ENDIAN_BIT ) );
|
420
|
+
if ( shouldFixEndian )
|
421
|
+
{
|
422
|
+
fixEndian( pReq );
|
423
|
+
}
|
424
|
+
if ( (pReq->m_specialEnvListSize < pReq->m_pHeader->m_cntSpecialEnv )&&
|
425
|
+
allocateEnvList( &pReq->m_pSpecialEnvList,
|
426
|
+
&pReq->m_specialEnvListSize,
|
427
|
+
pReq->m_pHeader->m_cntSpecialEnv ) == -1 )
|
428
|
+
return -1;
|
429
|
+
if ( (pReq->m_envListSize < pReq->m_pHeader->m_cntEnv )&&
|
430
|
+
allocateEnvList( &pReq->m_pEnvList, &pReq->m_envListSize,
|
431
|
+
pReq->m_pHeader->m_cntEnv ) == -1 )
|
432
|
+
return -1;
|
433
|
+
|
434
|
+
if ( parseEnv( pReq->m_pSpecialEnvList,
|
435
|
+
pReq->m_pHeader->m_cntSpecialEnv,
|
436
|
+
&pBegin, pEnd ) == -1 )
|
437
|
+
return -1;
|
438
|
+
if ( parseEnv( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv,
|
439
|
+
&pBegin, pEnd ) == -1 )
|
440
|
+
return -1;
|
441
|
+
|
442
|
+
pReq->m_pScriptFile = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptFileOff;
|
443
|
+
pReq->m_pScriptName = pReq->m_pReqBuf + pReq->m_pHeader->m_scriptNameOff;
|
444
|
+
pReq->m_pQueryString = pReq->m_pReqBuf + pReq->m_pHeader->m_queryStringOff;
|
445
|
+
pReq->m_pRequestMethod = pReq->m_pReqBuf + pReq->m_pHeader->m_requestMethodOff;
|
446
|
+
|
447
|
+
pBegin = pReq->m_pReqBuf + (( pBegin - pReq->m_pReqBuf + 7 ) & (~0x7));
|
448
|
+
pReq->m_pHeaderIndex = ( struct lsapi_http_header_index * )pBegin;
|
449
|
+
pBegin += sizeof( struct lsapi_http_header_index );
|
450
|
+
|
451
|
+
pReq->m_pUnknownHeader = (struct lsapi_header_offset *)pBegin;
|
452
|
+
pBegin += sizeof( struct lsapi_header_offset) *
|
453
|
+
pReq->m_pHeader->m_cntUnknownHeaders;
|
454
|
+
|
455
|
+
pReq->m_pHttpHeader = pBegin;
|
456
|
+
pBegin += pReq->m_pHeader->m_httpHeaderLen;
|
457
|
+
if ( pBegin != pEnd )
|
458
|
+
return -1;
|
459
|
+
|
460
|
+
if ( shouldFixEndian )
|
461
|
+
{
|
462
|
+
fixHeaderIndexEndian( pReq );
|
463
|
+
}
|
464
|
+
|
465
|
+
return 0;
|
466
|
+
}
|
467
|
+
|
468
|
+
static struct lsapi_packet_header ack = {'L', 'S',
|
469
|
+
LSAPI_REQ_RECEIVED, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
|
470
|
+
static inline int notify_req_received( LSAPI_Request * pReq )
|
471
|
+
{
|
472
|
+
if ( write( pReq->m_fd, &ack, LSAPI_PACKET_HEADER_LEN )
|
473
|
+
< LSAPI_PACKET_HEADER_LEN )
|
474
|
+
return -1;
|
475
|
+
return 0;
|
476
|
+
}
|
477
|
+
|
478
|
+
|
479
|
+
static int readReq( LSAPI_Request * pReq )
|
480
|
+
{
|
481
|
+
int len;
|
482
|
+
int packetLen;
|
483
|
+
if ( !pReq )
|
484
|
+
return -1;
|
485
|
+
if ( pReq->m_reqBufSize < 8192 )
|
486
|
+
{
|
487
|
+
if ( allocateBuf( pReq, 8192 ) == -1 )
|
488
|
+
return -1;
|
489
|
+
}
|
490
|
+
|
491
|
+
while ( pReq->m_bufRead < LSAPI_PACKET_HEADER_LEN )
|
492
|
+
{
|
493
|
+
len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf, pReq->m_reqBufSize );
|
494
|
+
if ( len <= 0 )
|
495
|
+
return -1;
|
496
|
+
pReq->m_bufRead += len;
|
497
|
+
}
|
498
|
+
pReq->m_reqState = LSAPI_ST_REQ_HEADER;
|
499
|
+
|
500
|
+
packetLen = verifyHeader( &pReq->m_pHeader->m_pktHeader, LSAPI_BEGIN_REQUEST );
|
501
|
+
if ( packetLen < 0 )
|
502
|
+
return -1;
|
503
|
+
if ( packetLen > LSAPI_MAX_HEADER_LEN )
|
504
|
+
return -1;
|
505
|
+
|
506
|
+
if ( packetLen > pReq->m_reqBufSize )
|
507
|
+
{
|
508
|
+
if ( allocateBuf( pReq, packetLen ) == -1 )
|
509
|
+
return -1;
|
510
|
+
}
|
511
|
+
while( packetLen > pReq->m_bufRead )
|
512
|
+
{
|
513
|
+
len = lsapi_read( pReq->m_fd, pReq->m_pReqBuf + pReq->m_bufRead, packetLen - pReq->m_bufRead );
|
514
|
+
if ( len <= 0 )
|
515
|
+
return -1;
|
516
|
+
pReq->m_bufRead += len;
|
517
|
+
}
|
518
|
+
if ( parseRequest( pReq, packetLen ) < 0 )
|
519
|
+
return -1;
|
520
|
+
pReq->m_bufProcessed = packetLen;
|
521
|
+
pReq->m_reqState = LSAPI_ST_REQ_BODY | LSAPI_ST_RESP_HEADER;
|
522
|
+
|
523
|
+
return notify_req_received( pReq );
|
524
|
+
}
|
525
|
+
|
526
|
+
|
527
|
+
|
528
|
+
int LSAPI_Init(void)
|
529
|
+
{
|
530
|
+
if ( !g_inited )
|
531
|
+
{
|
532
|
+
lsapi_signal(SIGPIPE, lsapi_sigpipe);
|
533
|
+
lsapi_signal(SIGUSR1, lsapi_siguser1);
|
534
|
+
|
535
|
+
if ( LSAPI_InitRequest( &g_req, LSAPI_SOCK_FILENO ) == -1 )
|
536
|
+
return -1;
|
537
|
+
g_inited = 1;
|
538
|
+
}
|
539
|
+
return 0;
|
540
|
+
}
|
541
|
+
|
542
|
+
void LSAPI_stop(void)
|
543
|
+
{
|
544
|
+
g_running = 0;
|
545
|
+
}
|
546
|
+
|
547
|
+
int LSAPI_InitRequest( LSAPI_Request * pReq, int fd )
|
548
|
+
{
|
549
|
+
if ( !pReq )
|
550
|
+
return -1;
|
551
|
+
memset( pReq, 0, sizeof( LSAPI_Request ) );
|
552
|
+
if ( allocateIovec( pReq, 16 ) == -1 )
|
553
|
+
return -1;
|
554
|
+
pReq->m_pRespBuf = pReq->m_pRespBufPos = (char *)malloc( LSAPI_RESP_BUF_SIZE );
|
555
|
+
if ( !pReq->m_pRespBuf )
|
556
|
+
return -1;
|
557
|
+
pReq->m_pRespBufEnd = pReq->m_pRespBuf + LSAPI_RESP_BUF_SIZE;
|
558
|
+
pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec + 1;
|
559
|
+
pReq->m_respPktHeaderEnd = &pReq->m_respPktHeader[5];
|
560
|
+
if ( allocateRespHeaderBuf( pReq, LSAPI_INIT_RESP_HEADER_LEN ) == -1 )
|
561
|
+
return -1;
|
562
|
+
|
563
|
+
if ( isPipe( fd ) )
|
564
|
+
{
|
565
|
+
pReq->m_fdListen = -1;
|
566
|
+
pReq->m_fd = fd;
|
567
|
+
}
|
568
|
+
else
|
569
|
+
{
|
570
|
+
pReq->m_fdListen = fd;
|
571
|
+
pReq->m_fd = -1;
|
572
|
+
}
|
573
|
+
return 0;
|
574
|
+
}
|
575
|
+
|
576
|
+
int LSAPI_Is_Listen( void )
|
577
|
+
{
|
578
|
+
return LSAPI_Is_Listen_r( &g_req );
|
579
|
+
}
|
580
|
+
|
581
|
+
int LSAPI_Is_Listen_r( LSAPI_Request * pReq)
|
582
|
+
{
|
583
|
+
return pReq->m_fdListen != -1;
|
584
|
+
}
|
585
|
+
|
586
|
+
|
587
|
+
|
588
|
+
int LSAPI_Accept_r( LSAPI_Request * pReq )
|
589
|
+
{
|
590
|
+
char achPeer[128];
|
591
|
+
socklen_t len;
|
592
|
+
int nodelay = 1;
|
593
|
+
|
594
|
+
if ( !pReq )
|
595
|
+
return -1;
|
596
|
+
if ( LSAPI_Finish_r( pReq ) == -1 )
|
597
|
+
return -1;
|
598
|
+
while( g_running )
|
599
|
+
{
|
600
|
+
if ( pReq->m_fd == -1 )
|
601
|
+
{
|
602
|
+
if ( pReq->m_fdListen != -1)
|
603
|
+
{
|
604
|
+
len = sizeof( achPeer );
|
605
|
+
pReq->m_fd = accept( pReq->m_fdListen,
|
606
|
+
(struct sockaddr *)&achPeer, &len );
|
607
|
+
if ( pReq->m_fd == -1 )
|
608
|
+
{
|
609
|
+
if (( errno == EINTR )||( errno == EAGAIN))
|
610
|
+
continue;
|
611
|
+
else
|
612
|
+
return -1;
|
613
|
+
}
|
614
|
+
else if (((struct sockaddr *)&achPeer)->sa_family == AF_INET )
|
615
|
+
{
|
616
|
+
setsockopt(pReq->m_fd, IPPROTO_TCP, TCP_NODELAY,
|
617
|
+
(char *)&nodelay, sizeof(nodelay));
|
618
|
+
}
|
619
|
+
}
|
620
|
+
else
|
621
|
+
return -1;
|
622
|
+
}
|
623
|
+
if ( !readReq( pReq ) )
|
624
|
+
break;
|
625
|
+
lsapi_close( pReq->m_fd );
|
626
|
+
pReq->m_fd = -1;
|
627
|
+
LSAPI_Reset_r( pReq );
|
628
|
+
}
|
629
|
+
return 0;
|
630
|
+
}
|
631
|
+
|
632
|
+
static struct lsapi_packet_header finish = {'L', 'S',
|
633
|
+
LSAPI_RESP_END, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
|
634
|
+
|
635
|
+
int LSAPI_Finish_r( LSAPI_Request * pReq )
|
636
|
+
{
|
637
|
+
//finish req body
|
638
|
+
if ( !pReq )
|
639
|
+
return -1;
|
640
|
+
if (pReq->m_reqState)
|
641
|
+
{
|
642
|
+
if ( pReq->m_fd != -1 )
|
643
|
+
{
|
644
|
+
if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
|
645
|
+
{
|
646
|
+
LSAPI_FinalizeRespHeaders_r( pReq );
|
647
|
+
}
|
648
|
+
if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
|
649
|
+
{
|
650
|
+
Flush_RespBuf_r( pReq );
|
651
|
+
}
|
652
|
+
|
653
|
+
pReq->m_pIovecCur->iov_base = (void *)&finish;
|
654
|
+
pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN;
|
655
|
+
pReq->m_totalLen += LSAPI_PACKET_HEADER_LEN;
|
656
|
+
++pReq->m_pIovecCur;
|
657
|
+
LSAPI_Flush_r( pReq );
|
658
|
+
}
|
659
|
+
LSAPI_Reset_r( pReq );
|
660
|
+
}
|
661
|
+
return 0;
|
662
|
+
}
|
663
|
+
|
664
|
+
|
665
|
+
void LSAPI_Reset_r( LSAPI_Request * pReq )
|
666
|
+
{
|
667
|
+
pReq->m_pRespBufPos = pReq->m_pRespBuf;
|
668
|
+
pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec + 1;
|
669
|
+
pReq->m_pRespHeaderBufPos = pReq->m_pRespHeaderBuf;
|
670
|
+
|
671
|
+
memset( &pReq->m_pHeaderIndex, 0,
|
672
|
+
(char *)(pReq->m_respHeaderLen) - (char *)&pReq->m_pHeaderIndex );
|
673
|
+
}
|
674
|
+
|
675
|
+
|
676
|
+
int LSAPI_Release_r( LSAPI_Request * pReq )
|
677
|
+
{
|
678
|
+
if ( pReq->m_pReqBuf )
|
679
|
+
free( pReq->m_pReqBuf );
|
680
|
+
if ( pReq->m_pSpecialEnvList )
|
681
|
+
free( pReq->m_pSpecialEnvList );
|
682
|
+
if ( pReq->m_pEnvList )
|
683
|
+
free( pReq->m_pEnvList );
|
684
|
+
if ( pReq->m_pRespHeaderBuf )
|
685
|
+
free( pReq->m_pRespHeaderBuf );
|
686
|
+
return 0;
|
687
|
+
}
|
688
|
+
|
689
|
+
|
690
|
+
char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex )
|
691
|
+
{
|
692
|
+
int off;
|
693
|
+
if ( !pReq || ((unsigned int)headerIndex > H_TRANSFER_ENCODING) )
|
694
|
+
return NULL;
|
695
|
+
off = pReq->m_pHeaderIndex->m_headerOff[ headerIndex ];
|
696
|
+
if ( !off )
|
697
|
+
return NULL;
|
698
|
+
if ( *(pReq->m_pHttpHeader + off +
|
699
|
+
pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) )
|
700
|
+
*( pReq->m_pHttpHeader + off +
|
701
|
+
pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0;
|
702
|
+
return pReq->m_pHttpHeader + off;
|
703
|
+
}
|
704
|
+
|
705
|
+
|
706
|
+
int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int bufLen )
|
707
|
+
{
|
708
|
+
int len;
|
709
|
+
int total;
|
710
|
+
//char *pOldBuf = pBuf;
|
711
|
+
if (!pReq || ( !pBuf )||(bufLen < 0 ))
|
712
|
+
return -1;
|
713
|
+
|
714
|
+
total = pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead;
|
715
|
+
|
716
|
+
if ( total <= 0 )
|
717
|
+
return 0;
|
718
|
+
if ( total < bufLen )
|
719
|
+
bufLen = total;
|
720
|
+
|
721
|
+
total = 0;
|
722
|
+
len = pReq->m_bufRead - pReq->m_bufProcessed;
|
723
|
+
if ( len > 0 )
|
724
|
+
{
|
725
|
+
if ( len > bufLen )
|
726
|
+
len = bufLen;
|
727
|
+
memmove( pBuf, pReq->m_pReqBuf + pReq->m_bufProcessed, len );
|
728
|
+
pReq->m_bufProcessed += len;
|
729
|
+
total += len;
|
730
|
+
pBuf += len;
|
731
|
+
bufLen -= len;
|
732
|
+
}
|
733
|
+
while( bufLen > 0 )
|
734
|
+
{
|
735
|
+
len = lsapi_read( pReq->m_fd, pBuf, bufLen );
|
736
|
+
if ( len > 0 )
|
737
|
+
{
|
738
|
+
total += len;
|
739
|
+
pBuf += len;
|
740
|
+
bufLen -= len;
|
741
|
+
}
|
742
|
+
else if ( len < 0 )
|
743
|
+
return -1;
|
744
|
+
}
|
745
|
+
pReq->m_reqBodyRead += total;
|
746
|
+
return total;
|
747
|
+
|
748
|
+
}
|
749
|
+
|
750
|
+
|
751
|
+
//int LSAPI_Write( const char * pBuf, int len )
|
752
|
+
//{
|
753
|
+
// return LSAPI_Write_r( &g_req, pBuf, len );
|
754
|
+
//}
|
755
|
+
|
756
|
+
int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len )
|
757
|
+
{
|
758
|
+
struct lsapi_packet_header * pHeader;
|
759
|
+
const char * pEnd;
|
760
|
+
const char * p;
|
761
|
+
int bufLen;
|
762
|
+
int toWrite;
|
763
|
+
int packetLen;
|
764
|
+
|
765
|
+
if ( !pReq || !pBuf )
|
766
|
+
return -1;
|
767
|
+
if ( len < pReq->m_pRespBufEnd - pReq->m_pRespBufPos )
|
768
|
+
{
|
769
|
+
memmove( pReq->m_pRespBufPos, pBuf, len );
|
770
|
+
pReq->m_pRespBufPos += len;
|
771
|
+
return len;
|
772
|
+
}
|
773
|
+
|
774
|
+
if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
|
775
|
+
{
|
776
|
+
LSAPI_FinalizeRespHeaders_r( pReq );
|
777
|
+
}
|
778
|
+
pReq->m_reqState |= LSAPI_ST_RESP_BODY;
|
779
|
+
|
780
|
+
pHeader = pReq->m_respPktHeader;
|
781
|
+
p = pBuf;
|
782
|
+
pEnd = pBuf + len;
|
783
|
+
bufLen = pReq->m_pRespBufPos - pReq->m_pRespBuf;
|
784
|
+
|
785
|
+
while( ( toWrite = pEnd - p ) > 0 )
|
786
|
+
{
|
787
|
+
packetLen = toWrite + bufLen;
|
788
|
+
if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen)
|
789
|
+
{
|
790
|
+
packetLen = LSAPI_MAX_DATA_PACKET_LEN;
|
791
|
+
toWrite = packetLen - bufLen;
|
792
|
+
}
|
793
|
+
|
794
|
+
lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM,
|
795
|
+
packetLen + LSAPI_PACKET_HEADER_LEN );
|
796
|
+
pReq->m_totalLen += packetLen + LSAPI_PACKET_HEADER_LEN;
|
797
|
+
|
798
|
+
pReq->m_pIovecCur->iov_base = (void *)pHeader;
|
799
|
+
pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN;
|
800
|
+
++pReq->m_pIovecCur;
|
801
|
+
++pHeader;
|
802
|
+
if ( bufLen > 0 )
|
803
|
+
{
|
804
|
+
pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf;
|
805
|
+
pReq->m_pIovecCur->iov_len = bufLen;
|
806
|
+
pReq->m_pRespBufPos = pReq->m_pRespBuf;
|
807
|
+
++pReq->m_pIovecCur;
|
808
|
+
bufLen = 0;
|
809
|
+
}
|
810
|
+
|
811
|
+
pReq->m_pIovecCur->iov_base = (void *)p;
|
812
|
+
pReq->m_pIovecCur->iov_len = toWrite;
|
813
|
+
++pReq->m_pIovecCur;
|
814
|
+
p += toWrite;
|
815
|
+
|
816
|
+
if ( pHeader >= pReq->m_respPktHeaderEnd - 1)
|
817
|
+
{
|
818
|
+
if ( LSAPI_Flush_r( pReq ) == -1 )
|
819
|
+
return -1;
|
820
|
+
pHeader = pReq->m_respPktHeader;
|
821
|
+
}
|
822
|
+
}
|
823
|
+
if ( pHeader != pReq->m_respPktHeader )
|
824
|
+
if ( LSAPI_Flush_r( pReq ) == -1 )
|
825
|
+
return -1;
|
826
|
+
return p - pBuf;
|
827
|
+
}
|
828
|
+
|
829
|
+
void Flush_RespBuf_r( LSAPI_Request * pReq )
|
830
|
+
{
|
831
|
+
struct lsapi_packet_header * pHeader = pReq->m_respPktHeader;
|
832
|
+
int bufLen = pReq->m_pRespBufPos - pReq->m_pRespBuf;
|
833
|
+
pReq->m_reqState |= LSAPI_ST_RESP_BODY;
|
834
|
+
lsapi_buildPacketHeader( pHeader, LSAPI_RESP_STREAM,
|
835
|
+
bufLen + LSAPI_PACKET_HEADER_LEN );
|
836
|
+
pReq->m_totalLen += bufLen + LSAPI_PACKET_HEADER_LEN;
|
837
|
+
|
838
|
+
pReq->m_pIovecCur->iov_base = (void *)pHeader;
|
839
|
+
pReq->m_pIovecCur->iov_len = LSAPI_PACKET_HEADER_LEN;
|
840
|
+
++pReq->m_pIovecCur;
|
841
|
+
++pHeader;
|
842
|
+
if ( bufLen > 0 )
|
843
|
+
{
|
844
|
+
pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespBuf;
|
845
|
+
pReq->m_pIovecCur->iov_len = bufLen;
|
846
|
+
pReq->m_pRespBufPos = pReq->m_pRespBuf;
|
847
|
+
++pReq->m_pIovecCur;
|
848
|
+
bufLen = 0;
|
849
|
+
}
|
850
|
+
}
|
851
|
+
|
852
|
+
|
853
|
+
|
854
|
+
|
855
|
+
int LSAPI_Flush_r( LSAPI_Request * pReq )
|
856
|
+
{
|
857
|
+
int ret = 0;
|
858
|
+
int n;
|
859
|
+
if ( !pReq )
|
860
|
+
return -1;
|
861
|
+
n = pReq->m_pIovecCur - pReq->m_pIovecToWrite;
|
862
|
+
if (( 0 == n )&&( pReq->m_pRespBufPos == pReq->m_pRespBuf ))
|
863
|
+
return 0;
|
864
|
+
if ( pReq->m_reqState & LSAPI_ST_RESP_HEADER )
|
865
|
+
{
|
866
|
+
LSAPI_FinalizeRespHeaders_r( pReq );
|
867
|
+
}
|
868
|
+
if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
|
869
|
+
{
|
870
|
+
Flush_RespBuf_r( pReq );
|
871
|
+
}
|
872
|
+
|
873
|
+
n = pReq->m_pIovecCur - pReq->m_pIovecToWrite;
|
874
|
+
if ( n > 0 )
|
875
|
+
{
|
876
|
+
|
877
|
+
ret = lsapi_writev( pReq->m_fd, &pReq->m_pIovecToWrite,
|
878
|
+
n, pReq->m_totalLen );
|
879
|
+
if ( ret < pReq->m_totalLen )
|
880
|
+
{
|
881
|
+
lsapi_close( pReq->m_fd );
|
882
|
+
pReq->m_fd = -1;
|
883
|
+
ret = -1;
|
884
|
+
}
|
885
|
+
pReq->m_totalLen = 0;
|
886
|
+
pReq->m_pIovecCur = pReq->m_pIovecToWrite = pReq->m_pIovec;
|
887
|
+
}
|
888
|
+
return ret;
|
889
|
+
}
|
890
|
+
|
891
|
+
|
892
|
+
int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len )
|
893
|
+
{
|
894
|
+
struct lsapi_packet_header header;
|
895
|
+
const char * pEnd;
|
896
|
+
const char * p;
|
897
|
+
int packetLen;
|
898
|
+
int totalLen;
|
899
|
+
int ret;
|
900
|
+
struct iovec iov[2];
|
901
|
+
struct iovec *pIov;
|
902
|
+
|
903
|
+
if ( pReq->m_pRespBufPos != pReq->m_pRespBuf )
|
904
|
+
{
|
905
|
+
LSAPI_Flush_r( pReq );
|
906
|
+
}
|
907
|
+
|
908
|
+
p = pBuf;
|
909
|
+
pEnd = pBuf + len;
|
910
|
+
|
911
|
+
while( ( packetLen = pEnd - p ) > 0 )
|
912
|
+
{
|
913
|
+
if ( LSAPI_MAX_DATA_PACKET_LEN < packetLen)
|
914
|
+
{
|
915
|
+
packetLen = LSAPI_MAX_DATA_PACKET_LEN;
|
916
|
+
}
|
917
|
+
|
918
|
+
lsapi_buildPacketHeader( &header, LSAPI_STDERR_STREAM,
|
919
|
+
packetLen + LSAPI_PACKET_HEADER_LEN );
|
920
|
+
totalLen = packetLen + LSAPI_PACKET_HEADER_LEN;
|
921
|
+
|
922
|
+
iov[0].iov_base = (void *)&header;
|
923
|
+
iov[0].iov_len = LSAPI_PACKET_HEADER_LEN;
|
924
|
+
|
925
|
+
iov[1].iov_base = (void *)p;
|
926
|
+
iov[1].iov_len = packetLen;
|
927
|
+
p += packetLen;
|
928
|
+
pIov = iov;
|
929
|
+
ret = lsapi_writev( pReq->m_fd, &pIov,
|
930
|
+
2, totalLen );
|
931
|
+
if ( ret < totalLen )
|
932
|
+
{
|
933
|
+
lsapi_close( pReq->m_fd );
|
934
|
+
pReq->m_fd = -1;
|
935
|
+
ret = -1;
|
936
|
+
}
|
937
|
+
}
|
938
|
+
return p - pBuf;
|
939
|
+
}
|
940
|
+
|
941
|
+
static char * GetHeaderVar( LSAPI_Request * pReq, const char * name )
|
942
|
+
{
|
943
|
+
int i;
|
944
|
+
for( i = 0; i < H_TRANSFER_ENCODING; ++i )
|
945
|
+
{
|
946
|
+
if ( pReq->m_pHeaderIndex->m_headerOff[i] )
|
947
|
+
{
|
948
|
+
if ( strcmp( name, CGI_HEADERS[i] ) == 0 )
|
949
|
+
return pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i];
|
950
|
+
}
|
951
|
+
}
|
952
|
+
if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 )
|
953
|
+
{
|
954
|
+
const char *p;
|
955
|
+
char *pKey;
|
956
|
+
char *pKeyEnd ;
|
957
|
+
int keyLen;
|
958
|
+
struct lsapi_header_offset * pCur, *pEnd;
|
959
|
+
pCur = pReq->m_pUnknownHeader;
|
960
|
+
pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders;
|
961
|
+
while( pCur < pEnd )
|
962
|
+
{
|
963
|
+
pKey = pReq->m_pHttpHeader + pCur->nameOff;
|
964
|
+
keyLen = pCur->nameLen;
|
965
|
+
pKeyEnd = pKey + keyLen;
|
966
|
+
p = &name[5];
|
967
|
+
|
968
|
+
while(( pKey < pKeyEnd )&&( *p ))
|
969
|
+
{
|
970
|
+
char ch = toupper( *pKey );
|
971
|
+
if ((ch != *p )||(( *p == '_' )&&( ch != '-')))
|
972
|
+
break;
|
973
|
+
++p; ++pKey;
|
974
|
+
}
|
975
|
+
if (( pKey == pKeyEnd )&& (!*p ))
|
976
|
+
return pReq->m_pHttpHeader + pCur->valueOff;
|
977
|
+
++pCur;
|
978
|
+
}
|
979
|
+
}
|
980
|
+
return NULL;
|
981
|
+
}
|
982
|
+
|
983
|
+
|
984
|
+
char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name )
|
985
|
+
{
|
986
|
+
struct LSAPI_key_value_pair * pBegin = pReq->m_pEnvList;
|
987
|
+
struct LSAPI_key_value_pair * pEnd = pBegin + pReq->m_pHeader->m_cntEnv;
|
988
|
+
if ( !pReq || !name )
|
989
|
+
return NULL;
|
990
|
+
if ( strncmp( name, "HTTP_", 5 ) == 0 )
|
991
|
+
{
|
992
|
+
return GetHeaderVar( pReq, name );
|
993
|
+
}
|
994
|
+
while( pBegin < pEnd )
|
995
|
+
{
|
996
|
+
if ( strcmp( name, pBegin->pKey ) == 0 )
|
997
|
+
return pBegin->pValue;
|
998
|
+
++pBegin;
|
999
|
+
}
|
1000
|
+
return NULL;
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
|
1004
|
+
int LSAPI_ForeachHeader_r( LSAPI_Request * pReq,
|
1005
|
+
LSAPI_CB_EnvHandler fn, void * arg )
|
1006
|
+
{
|
1007
|
+
int i;
|
1008
|
+
int len = 0;
|
1009
|
+
char * pValue;
|
1010
|
+
int ret;
|
1011
|
+
int count = 0;
|
1012
|
+
if ( !pReq || !fn )
|
1013
|
+
return -1;
|
1014
|
+
for( i = 0; i < H_TRANSFER_ENCODING; ++i )
|
1015
|
+
{
|
1016
|
+
if ( pReq->m_pHeaderIndex->m_headerOff[i] )
|
1017
|
+
{
|
1018
|
+
len = pReq->m_pHeaderIndex->m_headerLen[i];
|
1019
|
+
pValue = pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i];
|
1020
|
+
*(pValue + len ) = 0;
|
1021
|
+
ret = (*fn)( CGI_HEADERS[i], CGI_HEADER_LEN[i],
|
1022
|
+
pValue, len, arg );
|
1023
|
+
++count;
|
1024
|
+
if ( ret <= 0 )
|
1025
|
+
return ret;
|
1026
|
+
}
|
1027
|
+
}
|
1028
|
+
if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 )
|
1029
|
+
{
|
1030
|
+
char achHeaderName[256];
|
1031
|
+
char *p;
|
1032
|
+
char *pKey;
|
1033
|
+
char *pKeyEnd ;
|
1034
|
+
int keyLen;
|
1035
|
+
struct lsapi_header_offset * pCur, *pEnd;
|
1036
|
+
pCur = pReq->m_pUnknownHeader;
|
1037
|
+
pEnd = pCur + pReq->m_pHeader->m_cntUnknownHeaders;
|
1038
|
+
while( pCur < pEnd )
|
1039
|
+
{
|
1040
|
+
pKey = pReq->m_pHttpHeader + pCur->nameOff;
|
1041
|
+
keyLen = pCur->nameLen;
|
1042
|
+
pKeyEnd = pKey + keyLen;
|
1043
|
+
memcpy( achHeaderName, "HTTP_", 5 );
|
1044
|
+
p = &achHeaderName[5];
|
1045
|
+
if ( keyLen > 250 )
|
1046
|
+
keyLen = 250;
|
1047
|
+
|
1048
|
+
while( pKey < pKeyEnd )
|
1049
|
+
{
|
1050
|
+
char ch = *pKey++;
|
1051
|
+
if ( ch == '-' )
|
1052
|
+
*p++ = '_';
|
1053
|
+
else
|
1054
|
+
*p++ = toupper( ch );
|
1055
|
+
}
|
1056
|
+
*p = 0;
|
1057
|
+
keyLen += 5;
|
1058
|
+
|
1059
|
+
pValue = pReq->m_pHttpHeader + pCur->valueOff;
|
1060
|
+
*(pValue + pCur->valueLen ) = 0;
|
1061
|
+
ret = (*fn)( achHeaderName, pCur->valueLen,
|
1062
|
+
pValue, len, arg );
|
1063
|
+
if ( ret <= 0 )
|
1064
|
+
return ret;
|
1065
|
+
++pCur;
|
1066
|
+
}
|
1067
|
+
}
|
1068
|
+
return count + pReq->m_pHeader->m_cntUnknownHeaders;
|
1069
|
+
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
static int EnvForeach( struct LSAPI_key_value_pair * pEnv,
|
1073
|
+
int n, LSAPI_CB_EnvHandler fn, void * arg )
|
1074
|
+
{
|
1075
|
+
struct LSAPI_key_value_pair * pEnd = pEnv + n;
|
1076
|
+
int ret;
|
1077
|
+
if ( !pEnv || !fn )
|
1078
|
+
return -1;
|
1079
|
+
while( pEnv < pEnd )
|
1080
|
+
{
|
1081
|
+
ret = (*fn)( pEnv->pKey, pEnv->keyLen,
|
1082
|
+
pEnv->pValue, pEnv->valLen, arg );
|
1083
|
+
if ( ret <= 0 )
|
1084
|
+
return ret;
|
1085
|
+
++pEnv;
|
1086
|
+
}
|
1087
|
+
return n;
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
|
1091
|
+
|
1092
|
+
int LSAPI_ForeachEnv_r( LSAPI_Request * pReq,
|
1093
|
+
LSAPI_CB_EnvHandler fn, void * arg )
|
1094
|
+
{
|
1095
|
+
if ( !pReq || !fn )
|
1096
|
+
return -1;
|
1097
|
+
if ( pReq->m_pHeader->m_cntEnv > 0 )
|
1098
|
+
{
|
1099
|
+
return EnvForeach( pReq->m_pEnvList, pReq->m_pHeader->m_cntEnv,
|
1100
|
+
fn, arg );
|
1101
|
+
}
|
1102
|
+
return 0;
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
|
1106
|
+
|
1107
|
+
int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq,
|
1108
|
+
LSAPI_CB_EnvHandler fn, void * arg )
|
1109
|
+
{
|
1110
|
+
if ( !pReq || !fn )
|
1111
|
+
return -1;
|
1112
|
+
if ( pReq->m_pHeader->m_cntSpecialEnv > 0 )
|
1113
|
+
{
|
1114
|
+
return EnvForeach( pReq->m_pSpecialEnvList,
|
1115
|
+
pReq->m_pHeader->m_cntSpecialEnv,
|
1116
|
+
fn, arg );
|
1117
|
+
}
|
1118
|
+
return 0;
|
1119
|
+
|
1120
|
+
}
|
1121
|
+
|
1122
|
+
|
1123
|
+
|
1124
|
+
int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq )
|
1125
|
+
{
|
1126
|
+
if ( !pReq || !pReq->m_pIovec )
|
1127
|
+
return -1;
|
1128
|
+
if ( !( pReq->m_reqState & LSAPI_ST_RESP_HEADER ) )
|
1129
|
+
return 0;
|
1130
|
+
pReq->m_reqState &= ~LSAPI_ST_RESP_HEADER;
|
1131
|
+
if ( pReq->m_pRespHeaderBufPos > pReq->m_pRespHeaderBuf )
|
1132
|
+
{
|
1133
|
+
pReq->m_pIovecCur->iov_base = (void *)pReq->m_pRespHeaderBuf;
|
1134
|
+
pReq->m_pIovecCur->iov_len = pReq->m_pRespHeaderBufPos - pReq->m_pRespHeaderBuf;
|
1135
|
+
pReq->m_totalLen += pReq->m_pIovecCur->iov_len;
|
1136
|
+
++pReq->m_pIovecCur;
|
1137
|
+
}
|
1138
|
+
|
1139
|
+
pReq->m_pIovec->iov_len = sizeof( struct lsapi_resp_header)
|
1140
|
+
+ pReq->m_respHeader.m_respInfo.m_cntHeaders * sizeof( short );
|
1141
|
+
pReq->m_totalLen += pReq->m_pIovec->iov_len;
|
1142
|
+
|
1143
|
+
lsapi_buildPacketHeader( &pReq->m_respHeader.m_pktHeader,
|
1144
|
+
LSAPI_RESP_HEADER, pReq->m_totalLen );
|
1145
|
+
pReq->m_pIovec->iov_base = (void *)&pReq->m_respHeader;
|
1146
|
+
pReq->m_pIovecToWrite = pReq->m_pIovec;
|
1147
|
+
return 0;
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
|
1151
|
+
|
1152
|
+
|
1153
|
+
int LSAPI_AppendRespHeader_r( LSAPI_Request * pReq, char * pBuf, int len )
|
1154
|
+
{
|
1155
|
+
if ( !pReq || !pBuf || len <= 0 || len > LSAPI_RESP_HTTP_HEADER_MAX )
|
1156
|
+
return -1;
|
1157
|
+
if ( pReq->m_reqState & LSAPI_ST_RESP_BODY )
|
1158
|
+
return -1;
|
1159
|
+
if ( pReq->m_respHeader.m_respInfo.m_cntHeaders >= LSAPI_MAX_RESP_HEADERS )
|
1160
|
+
return -1;
|
1161
|
+
if ( pReq->m_pRespHeaderBufPos + len + 1 > pReq->m_pRespHeaderBufEnd )
|
1162
|
+
{
|
1163
|
+
int newlen = pReq->m_pRespHeaderBufPos + len + 4096 - pReq->m_pRespHeaderBuf;
|
1164
|
+
newlen -= newlen % 4096;
|
1165
|
+
if ( allocateRespHeaderBuf( pReq, newlen ) == -1 )
|
1166
|
+
return -1;
|
1167
|
+
}
|
1168
|
+
memmove( pReq->m_pRespHeaderBufPos, pBuf, len );
|
1169
|
+
pReq->m_pRespHeaderBufPos += len;
|
1170
|
+
*pReq->m_pRespHeaderBufPos++ = 0;
|
1171
|
+
++len; //add one byte padding for \0
|
1172
|
+
pReq->m_respHeaderLen[pReq->m_respHeader.m_respInfo.m_cntHeaders] = len;
|
1173
|
+
++pReq->m_respHeader.m_respInfo.m_cntHeaders;
|
1174
|
+
return 0;
|
1175
|
+
}
|
1176
|
+
|
1177
|
+
|
1178
|
+
|
1179
|
+
|
1180
|
+
|
1181
|
+
|