From 95d7a3ff946de18ed4cd1b8633720c8f3cd5b38f Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 4 Jun 2015 11:33:03 -0400 Subject: [PATCH] alter the logic of ReadData. New behaviour is documented. This solves unneccessary disconnects for me. --- src/zm_remote_camera_http.cpp | 185 ++++++++++++---------------------- 1 file changed, 64 insertions(+), 121 deletions(-) diff --git a/src/zm_remote_camera_http.cpp b/src/zm_remote_camera_http.cpp index c6de64aed..119db03ca 100644 --- a/src/zm_remote_camera_http.cpp +++ b/src/zm_remote_camera_http.cpp @@ -18,6 +18,7 @@ // #include "zm_remote_camera_http.h" +#include "zm_rtsp_auth.h" #include "zm_mem_utils.h" @@ -147,6 +148,12 @@ int RemoteCameraHttp::SendRequest() return( 0 ); } +/* Return codes are as follows: + * -1 means there was an error + * 0 means no bytes were returned but there wasn't actually an error. + * > 0 is the # of bytes read. + */ + int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected ) { fd_set rfds; @@ -158,8 +165,9 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected ) int n_found = select( sd+1, &rfds, NULL, NULL, &temp_timeout ); if( n_found == 0 ) { - Warning( "Select timed out" ); - Disconnect(); + Debug( 4, "Select timed out timeout was %d secs %d usecs", temp_timeout.tv_sec, temp_timeout.tv_usec ); + // Why are we disconnecting? It's just a timeout, meaning that data wasn't available. + //Disconnect(); return( 0 ); } else if ( n_found < 0) @@ -184,9 +192,11 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected ) if ( total_bytes_to_read == 0 ) { - Debug( 3, "Socket closed" ); - Disconnect(); - return( 0 ); + // If socket is closed locally, then select will fail, but if it is closed remotely + // then we have an exception on our socket.. but no data. + Debug( 3, "Socket closed remotely" ); + //Disconnect(); // Disconnect is done outside of ReadData now. + return( -1 ); } } Debug( 3, "Expecting %d bytes", total_bytes_to_read ); @@ -205,9 +215,9 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected ) } else if ( bytes_read == 0) { - Debug( 3, "Socket closed" ); - Disconnect(); - return( 0 ); + Debug( 2, "Socket closed" ); + //Disconnect(); // Disconnect is done outside of ReadData now. + return( -1 ); } else if ( bytes_read < bytes_to_read ) { @@ -228,6 +238,7 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected ) int RemoteCameraHttp::GetResponse() { + int buffer_len; #if HAVE_LIBPCRE if ( method == REGEXP ) { @@ -257,17 +268,12 @@ int RemoteCameraHttp::GetResponse() static RegExpr *content_length_expr = 0; static RegExpr *content_type_expr = 0; - int buffer_len = ReadData( buffer ); - if ( buffer_len == 0 ) - { - Error( "Connection dropped by remote end" ); - return( 0 ); - } - else if ( buffer_len < 0 ) - { - Error( "Unable to read header data" ); - return( -1 ); + while ( ! ( buffer_len = ReadData( buffer ) ) ) { } + if ( buffer_len < 0 ) { + Error( "Unable to read header data" ); + return( -1 ); + } if ( !header_expr ) header_expr = new RegExpr( "^(.+?\r?\n\r?\n)", PCRE_DOTALL ); if ( header_expr->Match( (char*)buffer, buffer.size() ) == 2 ) @@ -435,16 +441,12 @@ int RemoteCameraHttp::GetResponse() else { Debug( 3, "Unable to extract subheader from stream, retrying" ); - int buffer_len = ReadData( buffer ); - if ( buffer_len == 0 ) - { - Error( "Connection dropped by remote end" ); - return( 0 ); - } - else if ( buffer_len < 0 ) - { - return( -1 ); + while ( ! ( buffer_len = ReadData( buffer ) ) ) { } + if ( buffer_len < 0 ) { + Error( "Unable to extract subheader data" ); + return( -1 ); + } } break; } @@ -479,14 +481,8 @@ int RemoteCameraHttp::GetResponse() { while ( (long)buffer.size() < content_length ) { - int buffer_len = ReadData( buffer ); - if ( buffer_len == 0 ) - { - Error( "Connection dropped by remote end" ); - return( 0 ); - } - else if ( buffer_len < 0 ) - { +Debug(3, "Need more data buffer %d < content length %d", buffer.size(), content_length ); + if ( ReadData( buffer ) < 0 ) { Error( "Unable to read content" ); return( -1 ); } @@ -497,54 +493,26 @@ int RemoteCameraHttp::GetResponse() { while ( !content_length ) { - int buffer_len = ReadData( buffer ); - if ( buffer_len == 0 ) - { - if ( mode == MULTI_IMAGE ) - { - Error( "Connection dropped by remote end" ); - return( 0 ); - } - } - else if ( buffer_len < 0 ) - { - Error( "Unable to read content" ); - return( -1 ); + while ( ! ( buffer_len = ReadData( buffer ) ) ) { } + if ( buffer_len < 0 ) { + Error( "Unable to read content" ); + return( -1 ); + } static RegExpr *content_expr = 0; - if ( buffer_len ) - { - if ( mode == MULTI_IMAGE ) - { - if ( !content_expr ) - { - char content_pattern[256] = ""; - snprintf( content_pattern, sizeof(content_pattern), "^(.+?)(?:\r?\n)*(?:--)?%s\r?\n", content_boundary ); - content_expr = new RegExpr( content_pattern, PCRE_DOTALL ); - } - if ( content_expr->Match( buffer, buffer.size() ) == 2 ) - { - content_length = content_expr->MatchLength( 1 ); - Debug( 3, "Got end of image by pattern, content-length = %d", content_length ); - } - } - } - else - { - content_length = buffer.size(); - Debug( 3, "Got end of image by closure, content-length = %d", content_length ); - if ( mode == SINGLE_IMAGE ) - { - if ( !content_expr ) - { - content_expr = new RegExpr( "^(.+?)(?:\r?\n){1,2}?$", PCRE_DOTALL ); - } - if ( content_expr->Match( buffer, buffer.size() ) == 2 ) - { - content_length = content_expr->MatchLength( 1 ); - Debug( 3, "Trimmed end of image, new content-length = %d", content_length ); - } - } + if ( mode == MULTI_IMAGE ) + { + if ( !content_expr ) + { + char content_pattern[256] = ""; + snprintf( content_pattern, sizeof(content_pattern), "^(.+?)(?:\r?\n)*(?:--)?%s\r?\n", content_boundary ); + content_expr = new RegExpr( content_pattern, PCRE_DOTALL ); + } + if ( content_expr->Match( buffer, buffer.size() ) == 2 ) + { + content_length = content_expr->MatchLength( 1 ); + Debug( 3, "Got end of image by pattern, content-length = %d", content_length ); + } } } } @@ -650,17 +618,12 @@ int RemoteCameraHttp::GetResponse() } case HEADERCONT : { - int buffer_len = ReadData( buffer ); - if ( buffer_len == 0 ) - { - Error( "Connection dropped by remote end" ); - return( 0 ); - } - else if ( buffer_len < 0 ) - { - Error( "Unable to read header" ); - return( -1 ); + while ( ! ( buffer_len = ReadData( buffer ) ) ) { } + if ( buffer_len < 0 ) { + Error( "Unable to read header" ); + return( -1 ); + } char *crlf = 0; char *header_ptr = (char *)buffer; @@ -1004,17 +967,12 @@ int RemoteCameraHttp::GetResponse() else { Debug( 3, "Unable to extract subheader from stream, retrying" ); - int buffer_len = ReadData( buffer ); - if ( buffer_len == 0 ) - { - Error( "Connection dropped by remote end" ); - return( 0 ); - } - else if ( buffer_len < 0 ) - { - Error( "Unable to read subheader" ); - return( -1 ); + while ( ! ( buffer_len = ReadData( buffer ) ) ) { } + if ( buffer_len < 0 ) { + Error( "Unable to read subheader" ); + return( -1 ); + } state = SUBHEADERCONT; } break; @@ -1060,14 +1018,7 @@ int RemoteCameraHttp::GetResponse() while ( (long)buffer.size() < content_length ) { //int buffer_len = ReadData( buffer, content_length-buffer.size() ); - int buffer_len = ReadData( buffer ); - if ( buffer_len == 0 ) - { - Error( "Connection dropped by remote end" ); - return( 0 ); - } - else if ( buffer_len < 0 ) - { + if ( ReadData( buffer ) < 0 ) { Error( "Unable to read content" ); return( -1 ); } @@ -1079,16 +1030,8 @@ int RemoteCameraHttp::GetResponse() int content_pos = 0; while ( !content_length ) { - int buffer_len = ReadData( buffer ); - if ( buffer_len == 0 ) - { - if ( mode == MULTI_IMAGE ) - { - Error( "Connection dropped by remote end" ); - return( 0 ); - } - } - else if ( buffer_len < 0 ) + buffer_len = ReadData( buffer ); + if ( buffer_len < 0 ) { Error( "Unable to read content" ); return( -1 ); @@ -1147,7 +1090,7 @@ int RemoteCameraHttp::GetResponse() } } - Debug( 3, "Returning %d (%d) bytes of captured content", content_length, buffer.size() ); + Debug( 3, "Returning %d bytes, buffer size: (%d) bytes of captured content", content_length, buffer.size() ); return( content_length ); } } @@ -1191,7 +1134,7 @@ int RemoteCameraHttp::Capture( Image &image ) } if ( content_length < 0 ) { - Error( "Unable to get response" ); + Error( "Unable to get response, disconnecting" ); Disconnect(); return( -1 ); }