X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNetwork%2Fjpg-httpd.cxx;h=abf2911e3893210411f82a2c9d21c0e192d90923;hb=ff408dc540b0944061b0b88bdad93b5de17dbab9;hp=73d49fa7c4da8b580085a381ea29bb2c515c9b2b;hpb=c9813d1b5d79b4aad13c263690a0223086af25ac;p=flightgear.git diff --git a/src/Network/jpg-httpd.cxx b/src/Network/jpg-httpd.cxx index 73d49fa7c..abf2911e3 100644 --- a/src/Network/jpg-httpd.cxx +++ b/src/Network/jpg-httpd.cxx @@ -33,7 +33,7 @@ #include // atoi() atof() -#include STL_STRING +#include #include #include @@ -42,10 +42,20 @@ #include
#include
+#include
#include "jpg-httpd.hxx" -SG_USING_STD(string); +#define __MAX_HTTP_BLOCK_SIZE 4096 +#define __MAX_STRING_SIZE 2048 +#define __TIMEOUT_COUNT 5 +#define __HTTP_GET_STRING "GET " + +#include +#include +extern osg::ref_ptr sceneView; + +using std::string; bool FGJpegHttpd::open() { @@ -77,44 +87,125 @@ bool FGJpegHttpd::close() { return true; } - // Handle http GET requests -void HttpdImageChannel::foundTerminator (void) { +void HttpdImageChannel :: foundTerminator( void ) { - closeWhenDone (); + closeWhenDone(); - string response; + char szTemp[256]; + char szResponse[__MAX_STRING_SIZE]; + char *pRequest = buffer.getData(); + int nStep = 0; + int nBytesSent = 0; + int nTimeoutCount = 0; + int nBufferCount = 0; + int nImageLen; + int nBlockSize; - const string s = buffer.getData(); - if ( s.find( "GET " ) == 0 ) { + + if ( strstr( pRequest, __HTTP_GET_STRING ) != NULL ) { - printf("echo: %s\n", s.c_str()); - - int ImageLen = JpgFactory->render(); - - if( ImageLen ) { - response = "HTTP/1.1 200 OK"; - response += getTerminator(); - response += "Content-Type: image/jpeg"; - response += getTerminator(); - push( response.c_str() ); - - char ctmp[256]; - printf( "info->numbytes = %d\n", ImageLen ); - sprintf( ctmp, "Content-Length: %d", ImageLen ); - push( ctmp ); - - response = getTerminator(); - response += "Connection: close"; - response += getTerminator(); - response += getTerminator(); - push( response.c_str() ); - - /* can't use strlen on binary data */ - bufferSend ( (char *)JpgFactory->data(), ImageLen ) ; + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< HTTP Request : " << pRequest ); + + double left, right, bottom, top, zNear, zFar; + osgViewer::Viewer* viewer = globals->get_renderer()->getViewer(); + viewer->getCamera()->getProjectionMatrixAsFrustum(left, right, + bottom, top, + zNear, zFar); + JpgFactory->setFrustum( left, right, bottom, top, zNear, zFar ); + + nImageLen = JpgFactory -> render(); + nBlockSize = ( nImageLen < __MAX_HTTP_BLOCK_SIZE ? nImageLen : __MAX_HTTP_BLOCK_SIZE ); + + if( nImageLen ) { + strcpy( szResponse, "HTTP/1.1 200 OK" ); + strcat( szResponse, getTerminator() ); + strcat( szResponse, "Content-Type: image/jpeg" ); + strcat( szResponse, getTerminator() ); + + SG_LOG( SG_IO, SG_DEBUG, "info->numbytes = " << nImageLen ); + sprintf( szTemp, "Content-Length: %d", nImageLen ); + strcat( szResponse, szTemp ); + + strcat( szResponse, getTerminator() ); + strcat( szResponse, "Connection: close" ); + strcat( szResponse, getTerminator() ); + strcat( szResponse, getTerminator() ); + + if( getHandle() == -1 ) { + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Invalid socket handle. Ignoring request.\n" ); + buffer.remove(); + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< End of image Transmission.\n" ); + return; + } + + if( send( ( char * ) szResponse, strlen( szResponse ) ) <= 0 ) { + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Error to send HTTP response. Ignoring request.\n" ); + buffer.remove(); + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< End of image Transmission.\n" ); + return; + } + + /* + * Send block with size defined by __MAX_HTTP_BLOCK_SIZE + */ + while( nStep <= nImageLen ) { + nBufferCount++; + + if( getHandle() == -1 ) { + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Invalid socket handle. Ignoring request.\n" ); + break; + } + + nBytesSent = send( ( char * ) JpgFactory -> data() + nStep, nBlockSize ); + + if( nBytesSent <= 0 ) { + if( nTimeoutCount == __TIMEOUT_COUNT ) { + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Timeout reached. Exiting before end of image transmission.\n" ); + nTimeoutCount = 0; + break; + } + + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< Zero bytes sent.\n" ); + +#ifdef _WIN32 + Sleep(1000); +#else + sleep(1); +#endif + nTimeoutCount++; + continue; + } + + SG_LOG( SG_IO, SG_DEBUG, ">>>>>>>>> (" << nBufferCount << ") BLOCK STEP " << nStep << " - IMAGELEN " << nImageLen << " - BLOCKSIZE " << nBlockSize << " - SENT " << nBytesSent ); + + /* + * Calculate remaining image. + */ + if( ( nStep + nBlockSize ) >= nImageLen ) { + nBlockSize = ( nImageLen - nStep ); + nStep += nBlockSize; + } + + nStep += nBytesSent; + nTimeoutCount = 0; +#ifdef _WIN32 + Sleep(1); +#else + usleep( 1000 ); +#endif + } + + SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< End of image Transmission.\n" ); + } else { - printf("!!! NO IMAGE !!!\n\tinfo->numbytes = %d\n", ImageLen ); + SG_LOG( SG_IO, SG_DEBUG, "!!! NO IMAGE !!! info -> numbytes = " << nImageLen ); } + + /* + * Release JPEG buffer. + */ + JpgFactory -> destroy(); } buffer.remove();