diff options
Diffstat (limited to 'src/fastcgi.cpp')
-rw-r--r-- | src/fastcgi.cpp | 123 |
1 files changed, 103 insertions, 20 deletions
diff --git a/src/fastcgi.cpp b/src/fastcgi.cpp index aba3b71..9a602de 100644 --- a/src/fastcgi.cpp +++ b/src/fastcgi.cpp | |||
@@ -50,13 +50,17 @@ bool Bu::FastCgi::isEmbedded() | |||
50 | 50 | ||
51 | void Bu::FastCgi::read( Bu::Socket &s, Bu::FastCgi::Record &r ) | 51 | void Bu::FastCgi::read( Bu::Socket &s, Bu::FastCgi::Record &r ) |
52 | { | 52 | { |
53 | s.read( &r, sizeof(Record) ); | 53 | int iRead = s.read( &r, sizeof(Record) ); |
54 | if( iRead != sizeof(Record) ) | ||
55 | throw Bu::SocketException("Hey, the size %d is wrong for Record. (%s)", | ||
56 | iRead, strerror( errno ) ); | ||
54 | r.uRequestId = ntohs( r.uRequestId ); | 57 | r.uRequestId = ntohs( r.uRequestId ); |
55 | r.uContentLength = ntohs( r.uContentLength ); | 58 | r.uContentLength = ntohs( r.uContentLength ); |
56 | } | 59 | } |
57 | 60 | ||
58 | void Bu::FastCgi::write( Bu::Socket &s, Bu::FastCgi::Record r ) | 61 | void Bu::FastCgi::write( Bu::Socket &s, Bu::FastCgi::Record r ) |
59 | { | 62 | { |
63 | sio << "Out -> " << r << sio.nl; | ||
60 | r.uRequestId = htons( r.uRequestId ); | 64 | r.uRequestId = htons( r.uRequestId ); |
61 | r.uContentLength = htons( r.uContentLength ); | 65 | r.uContentLength = htons( r.uContentLength ); |
62 | s.write( &r, sizeof(Record) ); | 66 | s.write( &r, sizeof(Record) ); |
@@ -111,8 +115,30 @@ void Bu::FastCgi::readPair( Bu::Socket &s, StrHash &hParams, uint16_t &uRead ) | |||
111 | } | 115 | } |
112 | } | 116 | } |
113 | 117 | ||
118 | bool Bu::FastCgi::hasChannel( int iChan ) | ||
119 | { | ||
120 | if( aChannel.getSize() < iChan ) | ||
121 | return false; | ||
122 | if( aChannel[iChan-1] == NULL ) | ||
123 | return false; | ||
124 | return true; | ||
125 | } | ||
126 | |||
127 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::FastCgi::Record &r ) | ||
128 | { | ||
129 | f << "[Ver=" << (uint32_t)r.uVersion << | ||
130 | ", Type=" << (uint32_t)r.uType << | ||
131 | ", Req=" << (uint32_t)r.uRequestId << | ||
132 | ", clen=" << (uint32_t)r.uContentLength << | ||
133 | ", plen=" << (uint32_t)r.uPaddingLength << | ||
134 | ", resv=" << (uint32_t)r.uReserved << | ||
135 | "]"; | ||
136 | return f; | ||
137 | } | ||
138 | |||
114 | void Bu::FastCgi::run() | 139 | void Bu::FastCgi::run() |
115 | { | 140 | { |
141 | sio << "sizeof(Bu::FastCgi::Record) = " << sizeof(Record) << sio.nl; | ||
116 | bRunning = true; | 142 | bRunning = true; |
117 | while( bRunning ) | 143 | while( bRunning ) |
118 | { | 144 | { |
@@ -122,21 +148,49 @@ void Bu::FastCgi::run() | |||
122 | 148 | ||
123 | Bu::Socket s( iSock ); | 149 | Bu::Socket s( iSock ); |
124 | s.setBlocking( true ); | 150 | s.setBlocking( true ); |
151 | sio << "Got connection, blocking? " << s.isBlocking() << sio.nl; | ||
125 | try | 152 | try |
126 | { | 153 | { |
127 | for(;;) | 154 | for(;;) |
128 | { | 155 | { |
129 | Record r; | 156 | Record r; |
130 | read( s, r ); | 157 | memset( &r, 0, sizeof(r) ); |
131 | while( aChannel.getSize() < r.uRequestId ) | 158 | // try |
132 | aChannel.append( NULL ); | 159 | // { |
160 | read( s, r ); | ||
161 | // } | ||
162 | // catch( Bu::ExceptionBase &e ) | ||
163 | // { | ||
164 | // sio << "Error: " << e.what() << ", " << s.isOpen() << | ||
165 | // sio.nl; | ||
166 | // continue; | ||
167 | // } | ||
133 | Channel *pChan = NULL; | 168 | Channel *pChan = NULL; |
134 | if( r.uRequestId > 0 ) | 169 | if( r.uRequestId > 0 ) |
135 | pChan = aChannel[r.uRequestId-1]; | 170 | { |
171 | if( !hasChannel( r.uRequestId ) && | ||
172 | r.uType != typeBeginRequest ) | ||
173 | { | ||
174 | sio << "Error, stream data without stream." << sio.nl; | ||
175 | sio << r << sio.nl; | ||
176 | if( r.uContentLength > 0 ) | ||
177 | { | ||
178 | char *buf = new char[r.uContentLength]; | ||
179 | sio << " (read " << s.read( buf, r.uContentLength ) | ||
180 | << "/" << r.uContentLength << "):" << sio.nl; | ||
181 | sio.write( buf, r.uContentLength ); | ||
182 | sio << sio.nl << sio.nl; | ||
183 | } | ||
184 | } | ||
185 | while( aChannel.getSize() < r.uRequestId ) | ||
186 | aChannel.append( NULL ); | ||
187 | if( r.uRequestId > 0 ) | ||
188 | pChan = aChannel[r.uRequestId-1]; | ||
189 | } | ||
136 | 190 | ||
137 | sio << "Record (id=" << r.uRequestId << ", len=" << | 191 | sio << "Record (id=" << r.uRequestId << ", len=" << |
138 | r.uContentLength << ", pad=" << | 192 | r.uContentLength << ", pad=" << |
139 | (int)r.uPaddingLength << "): "; | 193 | (unsigned int)r.uPaddingLength << "): "; |
140 | fflush( stdout ); | 194 | fflush( stdout ); |
141 | 195 | ||
142 | switch( (RequestType)r.uType ) | 196 | switch( (RequestType)r.uType ) |
@@ -180,9 +234,16 @@ void Bu::FastCgi::run() | |||
180 | else | 234 | else |
181 | { | 235 | { |
182 | char *buf = new char[r.uContentLength]; | 236 | char *buf = new char[r.uContentLength]; |
183 | sio << " (read " << s.read( buf, r.uContentLength ) | 237 | int iTotal = 0; |
184 | << ")"; | 238 | do |
185 | pChan->sStdIn.append( buf, r.uContentLength ); | 239 | { |
240 | size_t iRead = s.read( | ||
241 | buf, r.uContentLength-iTotal ); | ||
242 | iTotal += iRead; | ||
243 | sio << " (read " << iRead << " " << iTotal | ||
244 | << "/" << r.uContentLength << ")"; | ||
245 | pChan->sStdIn.append( buf, iRead ); | ||
246 | } while( iTotal < r.uContentLength ); | ||
186 | delete[] buf; | 247 | delete[] buf; |
187 | } | 248 | } |
188 | break; | 249 | break; |
@@ -219,6 +280,7 @@ void Bu::FastCgi::run() | |||
219 | { | 280 | { |
220 | if( pChan->uFlags == chflgAllDone ) | 281 | if( pChan->uFlags == chflgAllDone ) |
221 | { | 282 | { |
283 | sio << "All done, generating output." << sio.nl; | ||
222 | Bu::MemBuf mStdOut, mStdErr; | 284 | Bu::MemBuf mStdOut, mStdErr; |
223 | int iRet = request( | 285 | int iRet = request( |
224 | pChan->hParams, pChan->sStdIn, | 286 | pChan->hParams, pChan->sStdIn, |
@@ -229,27 +291,47 @@ void Bu::FastCgi::run() | |||
229 | Bu::FString &sStdErr = mStdErr.getString(); | 291 | Bu::FString &sStdErr = mStdErr.getString(); |
230 | 292 | ||
231 | Record rOut; | 293 | Record rOut; |
294 | memset( &rOut, 0, sizeof(rOut) ); | ||
232 | rOut.uVersion = 1; | 295 | rOut.uVersion = 1; |
233 | rOut.uRequestId = r.uRequestId; | 296 | rOut.uRequestId = r.uRequestId; |
234 | rOut.uPaddingLength = 0; | 297 | rOut.uPaddingLength = 0; |
298 | rOut.uType = typeStdOut; | ||
235 | if( sStdOut.getSize() > 0 ) | 299 | if( sStdOut.getSize() > 0 ) |
236 | { | 300 | { |
237 | rOut.uType = typeStdOut; | 301 | for( int iPos = 0; iPos < sStdOut.getSize(); |
238 | rOut.uContentLength = sStdOut.getSize(); | 302 | iPos += 65528 ) |
239 | write( s, rOut ); | 303 | { |
240 | s.write( sStdOut ); | 304 | int iSize = sStdOut.getSize()-iPos; |
305 | if( iSize > 65528 ) | ||
306 | iSize = 65528; | ||
307 | rOut.uContentLength = iSize; | ||
308 | write( s, rOut ); | ||
309 | int iAmnt = s.write( | ||
310 | sStdOut.getStr()+iPos, iSize ); | ||
311 | sio << "Wrote " << iAmnt << | ||
312 | " of " << iSize << sio.nl; | ||
313 | } | ||
241 | } | 314 | } |
242 | rOut.uType = typeStdOut; | ||
243 | rOut.uContentLength = 0; | 315 | rOut.uContentLength = 0; |
244 | write( s, rOut ); | 316 | write( s, rOut ); |
317 | |||
318 | rOut.uType = typeStdErr; | ||
245 | if( sStdErr.getSize() > 0 ) | 319 | if( sStdErr.getSize() > 0 ) |
246 | { | 320 | { |
247 | rOut.uType = typeStdErr; | 321 | for( int iPos = 0; iPos < sStdErr.getSize(); |
248 | rOut.uContentLength = sStdErr.getSize(); | 322 | iPos += 65528 ) |
249 | write( s, rOut ); | 323 | { |
250 | s.write( sStdOut ); | 324 | int iSize = sStdErr.getSize()-iPos; |
325 | if( iSize > 65528 ) | ||
326 | iSize = 65528; | ||
327 | rOut.uContentLength = iSize; | ||
328 | write( s, rOut ); | ||
329 | int iAmnt = s.write( | ||
330 | sStdErr.getStr()+iPos, iSize ); | ||
331 | sio << "Wrote " << iAmnt << | ||
332 | " of " << iSize << sio.nl; | ||
333 | } | ||
251 | } | 334 | } |
252 | rOut.uType = typeStdErr; | ||
253 | rOut.uContentLength = 0; | 335 | rOut.uContentLength = 0; |
254 | write( s, rOut ); | 336 | write( s, rOut ); |
255 | 337 | ||
@@ -270,7 +352,8 @@ void Bu::FastCgi::run() | |||
270 | } | 352 | } |
271 | catch( Bu::SocketException &e ) | 353 | catch( Bu::SocketException &e ) |
272 | { | 354 | { |
273 | //sio << "Bu::SocketException: " << e.what() << sio.nl; | 355 | sio << "Bu::SocketException: " << e.what() << sio.nl << |
356 | "\tSocket open: " << s.isOpen() << sio.nl; | ||
274 | } | 357 | } |
275 | } | 358 | } |
276 | } | 359 | } |