Follow HTTP Redirect

Anything you want added or changed in future versions of ZoneMinder? Post here and there's a chance it will get in! Search to make sure it hasn't already been requested.
Post Reply
jayko
Posts: 1
Joined: Tue Dec 28, 2010 12:51 pm

Follow HTTP Redirect

Post by jayko »

When I specify a link that requires a redirect return is:

12/28/10 06:02:06.063556 zmc_m1[20346].INF-zmc.cpp/188 [Starting Capture]
12/28/10 06:02:06.273556 zmc_m1[20347].ERR-zm_rtsp.cpp/266 [Unexpected response code 302, text is 'Found']
12/28/10 06:02:17.783556 zmc_m1[20346].FAT-zm_remote_camera_rtsp.cpp/118 [No RTSP sources]
mastertheknife
Posts: 678
Joined: Wed Dec 16, 2009 4:32 pm
Location: Israel

Post by mastertheknife »

Just something quick to get you running.
I wrote this quickly without even testing it or trying to compile it, hopefully it works for you.

Code: Select all

--- a/src/zm_rtsp.cpp
+++ b/src/zm_rtsp.cpp
@@ -201,6 +201,11 @@ int RtspThread::run()
 {
     std::string message;
     std::string response;
+    bool torestart = false;
+    const char* locationheader;
+    char newhost[32];
+    char newpath[64];
+    char newport[8];
 
     response.reserve( ZM_NETWORK_BUFSIZ );
 
@@ -216,6 +221,7 @@ int RtspThread::run()
 
     if ( mMethod == RTP_RTSP_HTTP )
     {
+      do {
         if ( !mRtspSocket2.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) )
             Fatal( "Unable to connect auxiliary RTSP/HTTP socket" );
         //Select select( 0.25 );
@@ -260,9 +266,29 @@ int RtspThread::run()
                     Hexdump( ZM_DBG_ERR, response.data(), min(response.size(),16) );
             }
             return( -1 );
-        }
-        if ( respCode != 200 )
-        {
+       }
+
+        /* Redirect */
+        if ( respCode == 301 || respCode == 302) {
+         locationheader = strstr(response.c_str(),"Location:");
+         if(locationheader == NULL) {
+           Error( "Unable to find new address in the redirect");
+           return ( -1 );
+         }
+         /* Check if a port is specified in the redirect */
+         if(strchr(locationheader,':') != NULL) {
+           sscanf(locationheader,"Location: http://%s:%s/%s",newhost,newport,newpath);
+           mPort = newport;
+         } else {  
+           sscanf(locationheader,"Location: http://%s/%s",newhost,newpath);
+           mPort = "80";
+         }
+         
+         mHost = newhost;
+         mPath = newpath;
+        
+         torestart = true; /* Restart the loop to connect to the new host and path */
+       } else if (respCode != 200) {
             Error( "Unexpected response code %d, text is '%s'", respCode, respText );
             return( -1 );
         }
@@ -280,6 +306,8 @@ int RtspThread::run()
             Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) );
             return( -1 );
         }
+        
+        while(torestart == true); /* Restart the loop if a redirect is found */
     }
 
     std::string localHost = "";

mastertheknife.
Post Reply