alter the logic of ReadData. New behaviour is documented. This solves unneccessary disconnects for me.
parent
c8e41319e6
commit
95d7a3ff94
|
@ -18,6 +18,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "zm_remote_camera_http.h"
|
#include "zm_remote_camera_http.h"
|
||||||
|
#include "zm_rtsp_auth.h"
|
||||||
|
|
||||||
#include "zm_mem_utils.h"
|
#include "zm_mem_utils.h"
|
||||||
|
|
||||||
|
@ -147,6 +148,12 @@ int RemoteCameraHttp::SendRequest()
|
||||||
return( 0 );
|
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 )
|
int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected )
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
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 );
|
int n_found = select( sd+1, &rfds, NULL, NULL, &temp_timeout );
|
||||||
if( n_found == 0 )
|
if( n_found == 0 )
|
||||||
{
|
{
|
||||||
Warning( "Select timed out" );
|
Debug( 4, "Select timed out timeout was %d secs %d usecs", temp_timeout.tv_sec, temp_timeout.tv_usec );
|
||||||
Disconnect();
|
// Why are we disconnecting? It's just a timeout, meaning that data wasn't available.
|
||||||
|
//Disconnect();
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
else if ( n_found < 0)
|
else if ( n_found < 0)
|
||||||
|
@ -184,9 +192,11 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected )
|
||||||
|
|
||||||
if ( total_bytes_to_read == 0 )
|
if ( total_bytes_to_read == 0 )
|
||||||
{
|
{
|
||||||
Debug( 3, "Socket closed" );
|
// If socket is closed locally, then select will fail, but if it is closed remotely
|
||||||
Disconnect();
|
// then we have an exception on our socket.. but no data.
|
||||||
return( 0 );
|
Debug( 3, "Socket closed remotely" );
|
||||||
|
//Disconnect(); // Disconnect is done outside of ReadData now.
|
||||||
|
return( -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Debug( 3, "Expecting %d bytes", total_bytes_to_read );
|
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)
|
else if ( bytes_read == 0)
|
||||||
{
|
{
|
||||||
Debug( 3, "Socket closed" );
|
Debug( 2, "Socket closed" );
|
||||||
Disconnect();
|
//Disconnect(); // Disconnect is done outside of ReadData now.
|
||||||
return( 0 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
else if ( bytes_read < bytes_to_read )
|
else if ( bytes_read < bytes_to_read )
|
||||||
{
|
{
|
||||||
|
@ -228,6 +238,7 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected )
|
||||||
|
|
||||||
int RemoteCameraHttp::GetResponse()
|
int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
|
int buffer_len;
|
||||||
#if HAVE_LIBPCRE
|
#if HAVE_LIBPCRE
|
||||||
if ( method == REGEXP )
|
if ( method == REGEXP )
|
||||||
{
|
{
|
||||||
|
@ -257,17 +268,12 @@ int RemoteCameraHttp::GetResponse()
|
||||||
static RegExpr *content_length_expr = 0;
|
static RegExpr *content_length_expr = 0;
|
||||||
static RegExpr *content_type_expr = 0;
|
static RegExpr *content_type_expr = 0;
|
||||||
|
|
||||||
int buffer_len = ReadData( buffer );
|
while ( ! ( 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 );
|
|
||||||
}
|
}
|
||||||
|
if ( buffer_len < 0 ) {
|
||||||
|
Error( "Unable to read header data" );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
if ( !header_expr )
|
if ( !header_expr )
|
||||||
header_expr = new RegExpr( "^(.+?\r?\n\r?\n)", PCRE_DOTALL );
|
header_expr = new RegExpr( "^(.+?\r?\n\r?\n)", PCRE_DOTALL );
|
||||||
if ( header_expr->Match( (char*)buffer, buffer.size() ) == 2 )
|
if ( header_expr->Match( (char*)buffer, buffer.size() ) == 2 )
|
||||||
|
@ -435,16 +441,12 @@ int RemoteCameraHttp::GetResponse()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug( 3, "Unable to extract subheader from stream, retrying" );
|
Debug( 3, "Unable to extract subheader from stream, retrying" );
|
||||||
int buffer_len = ReadData( buffer );
|
while ( ! ( buffer_len = ReadData( buffer ) ) ) {
|
||||||
if ( buffer_len == 0 )
|
|
||||||
{
|
|
||||||
Error( "Connection dropped by remote end" );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
else if ( buffer_len < 0 )
|
|
||||||
{
|
|
||||||
return( -1 );
|
|
||||||
}
|
}
|
||||||
|
if ( buffer_len < 0 ) {
|
||||||
|
Error( "Unable to extract subheader data" );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -479,14 +481,8 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
while ( (long)buffer.size() < content_length )
|
while ( (long)buffer.size() < content_length )
|
||||||
{
|
{
|
||||||
int buffer_len = ReadData( buffer );
|
Debug(3, "Need more data buffer %d < content length %d", buffer.size(), content_length );
|
||||||
if ( buffer_len == 0 )
|
if ( ReadData( buffer ) < 0 ) {
|
||||||
{
|
|
||||||
Error( "Connection dropped by remote end" );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
else if ( buffer_len < 0 )
|
|
||||||
{
|
|
||||||
Error( "Unable to read content" );
|
Error( "Unable to read content" );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -497,54 +493,26 @@ int RemoteCameraHttp::GetResponse()
|
||||||
{
|
{
|
||||||
while ( !content_length )
|
while ( !content_length )
|
||||||
{
|
{
|
||||||
int buffer_len = ReadData( buffer );
|
while ( ! ( 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 );
|
|
||||||
}
|
}
|
||||||
|
if ( buffer_len < 0 ) {
|
||||||
|
Error( "Unable to read content" );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
static RegExpr *content_expr = 0;
|
static RegExpr *content_expr = 0;
|
||||||
if ( buffer_len )
|
if ( mode == MULTI_IMAGE )
|
||||||
{
|
{
|
||||||
if ( mode == MULTI_IMAGE )
|
if ( !content_expr )
|
||||||
{
|
{
|
||||||
if ( !content_expr )
|
char content_pattern[256] = "";
|
||||||
{
|
snprintf( content_pattern, sizeof(content_pattern), "^(.+?)(?:\r?\n)*(?:--)?%s\r?\n", content_boundary );
|
||||||
char content_pattern[256] = "";
|
content_expr = new RegExpr( content_pattern, PCRE_DOTALL );
|
||||||
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 )
|
||||||
}
|
{
|
||||||
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 );
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -650,17 +618,12 @@ int RemoteCameraHttp::GetResponse()
|
||||||
}
|
}
|
||||||
case HEADERCONT :
|
case HEADERCONT :
|
||||||
{
|
{
|
||||||
int buffer_len = ReadData( buffer );
|
while ( ! ( 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 );
|
|
||||||
}
|
}
|
||||||
|
if ( buffer_len < 0 ) {
|
||||||
|
Error( "Unable to read header" );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
char *crlf = 0;
|
char *crlf = 0;
|
||||||
char *header_ptr = (char *)buffer;
|
char *header_ptr = (char *)buffer;
|
||||||
|
@ -1004,17 +967,12 @@ int RemoteCameraHttp::GetResponse()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug( 3, "Unable to extract subheader from stream, retrying" );
|
Debug( 3, "Unable to extract subheader from stream, retrying" );
|
||||||
int buffer_len = ReadData( buffer );
|
while ( ! ( 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 );
|
|
||||||
}
|
}
|
||||||
|
if ( buffer_len < 0 ) {
|
||||||
|
Error( "Unable to read subheader" );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
state = SUBHEADERCONT;
|
state = SUBHEADERCONT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1060,14 +1018,7 @@ int RemoteCameraHttp::GetResponse()
|
||||||
while ( (long)buffer.size() < content_length )
|
while ( (long)buffer.size() < content_length )
|
||||||
{
|
{
|
||||||
//int buffer_len = ReadData( buffer, content_length-buffer.size() );
|
//int buffer_len = ReadData( buffer, content_length-buffer.size() );
|
||||||
int buffer_len = ReadData( buffer );
|
if ( ReadData( buffer ) < 0 ) {
|
||||||
if ( buffer_len == 0 )
|
|
||||||
{
|
|
||||||
Error( "Connection dropped by remote end" );
|
|
||||||
return( 0 );
|
|
||||||
}
|
|
||||||
else if ( buffer_len < 0 )
|
|
||||||
{
|
|
||||||
Error( "Unable to read content" );
|
Error( "Unable to read content" );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
@ -1079,16 +1030,8 @@ int RemoteCameraHttp::GetResponse()
|
||||||
int content_pos = 0;
|
int content_pos = 0;
|
||||||
while ( !content_length )
|
while ( !content_length )
|
||||||
{
|
{
|
||||||
int buffer_len = ReadData( buffer );
|
buffer_len = ReadData( buffer );
|
||||||
if ( buffer_len == 0 )
|
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" );
|
Error( "Unable to read content" );
|
||||||
return( -1 );
|
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 );
|
return( content_length );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1191,7 +1134,7 @@ int RemoteCameraHttp::Capture( Image &image )
|
||||||
}
|
}
|
||||||
if ( content_length < 0 )
|
if ( content_length < 0 )
|
||||||
{
|
{
|
||||||
Error( "Unable to get response" );
|
Error( "Unable to get response, disconnecting" );
|
||||||
Disconnect();
|
Disconnect();
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue