summaryrefslogtreecommitdiff
path: root/src/fastcgi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/fastcgi.cpp')
-rw-r--r--src/fastcgi.cpp123
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
51void Bu::FastCgi::read( Bu::Socket &s, Bu::FastCgi::Record &r ) 51void 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
58void Bu::FastCgi::write( Bu::Socket &s, Bu::FastCgi::Record r ) 61void 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
118bool 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
127Bu::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
114void Bu::FastCgi::run() 139void 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}