X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNetwork%2Fjpg-httpd.cxx;h=55e5e79c02c44619fddf7c50dfcebda0f9abfe50;hb=e16f772e54216b0088ca9cb3f3b0fb062be8bfdb;hp=63afbffbdcd841cd3fa9cef01d51a65456355b1e;hpb=e75f6a8f0100f847cbe1bb8fc83a0c466dbe44f5;p=flightgear.git diff --git a/src/Network/jpg-httpd.cxx b/src/Network/jpg-httpd.cxx index 63afbffbd..55e5e79c0 100644 --- a/src/Network/jpg-httpd.cxx +++ b/src/Network/jpg-httpd.cxx @@ -3,7 +3,7 @@ // // Written by Curtis Olson, started June 2001. // -// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org +// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt // // Jpeg Image Support added August 2001 // by Norman Vine - nhv@cape.com @@ -20,7 +20,7 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -31,26 +31,31 @@ #include -#include // atoi() atof() +#include // atoi() atof() -#include STL_STRING -#include STL_STRSTREAM +#include #include #include #include -#include +#include #include
#include
+#include
#include "jpg-httpd.hxx" -SG_USING_STD(string); -#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS) -SG_USING_STD(cout); -SG_USING_STD(istrstream); -#endif +#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() { @@ -70,7 +75,7 @@ bool FGJpegHttpd::open() { bool FGJpegHttpd::process() { - netChannel::poll(); + simgear::NetChannel::poll(); return true; } @@ -82,44 +87,125 @@ bool FGJpegHttpd::close() { return true; } - // Handle http GET requests -void HttpdImageChannel::foundTerminator (void) { +void HttpdImageChannel :: foundTerminator( void ) { + + closeWhenDone(); - closeWhenDone (); + 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; - string response; - 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();