/** @brief IDLE state handler.
  *
  * @param[in] pHttpResolver - Reference to HTTPResolver
  * @return
  * HTTPDL_WAITING - Successfully posted GET request to the HTTP stack
  * HTTPDL_ERROR_ABORT - Error
  */
HTTPDownloadStatus HTTPResolver::IdleStateHandler::Execute
(
 HTTPResolver* pHttpResolver
)
{
  QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW,
                "HTTPResolver::IdleStateHandler::Execute()" );
  HTTPDownloadStatus status = HTTPCommon::HTTPDL_ERROR_ABORT;
  HTTPResolver* pSelf = static_cast<HTTPResolver *> (pHttpResolver);

  //Validity check
  if (pSelf)
  {
    HTTPSessionInfo& sessionInfo = pSelf->m_sessionInfo;
    URL url = sessionInfo.GetURL();
    char* pLaunchURL = pSelf->m_pLaunchURL;
    HTTPMethodType methodType = HTTP_GET;

    //Prepare launch URL
    if (HTTPCommon::ParseURL(url, HTTP_DEFAULT_PORT, pLaunchURL) && pLaunchURL)
    {
      pSelf->m_pLaunchURL = pLaunchURL;
      HTTPStackInterface& HTTPStack = pSelf->m_pHTTPStack;

      if(HTTPStack.CreateRequest(pSelf->m_nRequestID) == HTTP_SUCCESS )
      {
        //Add HTTP headers
        char hostName[HTTP_MAX_HOSTNAME_LEN] = {0};
        if (url.GetHost(hostName, sizeof(hostName)) == URL::URL_OK)
        {
            (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "Host", (int)std_strlen("Host"),
                                    hostName, (int)std_strlen(hostName));
        }

        char range[HTTP_MAX_RANGE_LEN] = {0};
        if (pSelf->m_nMaxRequestSize >= 0)
        {
          (void)std_strlprintf(range, sizeof(range), "bytes=%d-%d", 0, (int)pSelf->m_nMaxRequestSize);
        }
        else
        {
        (void)std_strlprintf(range, sizeof(range), "bytes=%d-", 0);
        }

          (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "Range", (int)std_strlen("Range"),
                                  range, (int)std_strlen(range));

        const char* pUserAgent = sessionInfo.GetUserAgent();
        if (pUserAgent)
        {
            (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "User-Agent",
                                    (int)std_strlen("User-Agent"),
                                    pUserAgent, (int)std_strlen(pUserAgent));
        }

        //Add any OEM headers
        HTTPCommon::AddIPStreamProtocolHeaders(sessionInfo, HTTPStack, methodType, pSelf->m_nRequestID);

        //Send HTTP GET request
        QTV_MSG_SPRINTF_PRIO_2( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH,
                                "HTTPResolver::IdleStateHandler: Posting GET %s for %s", range, pLaunchURL );
          HTTPReturnCode result = HTTPStack.SendRequest(pSelf->m_nRequestID, methodType,
                                                      pLaunchURL,
                                                      (int)std_strlen(pLaunchURL));
        if (result == HTTP_SUCCESS)
        {
          //HTTP GET request successfully composed and posted to the HTTP stack,
          //move to WAIT_FOR_DATA
          status = HTTPCommon::HTTPDL_WAITING;
          pSelf->SetStateHandler(&pSelf->m_WaitForDataStateHandler);
          QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_MEDIUM,
                        "HTTPResolver::IdleStateHandler: HTTP GET request successfully "
                        "composed and posted to HTTP stack - moving to WAIT_FOR_DATA" );
        }
        else
        {
          QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
                         "HTTPResolver::IdleStateHandler: Posting HTTP GET failed %d",
                         result );
        }
      }
      else
      {
        QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
                      "Error Creating Request");
      }
    }// if (HTTPCommon::ParseURL())
  }// if (pSelf)

  return status;
}
Esempio n. 2
0
bool HttpRetriever::TaskValid(  long bsize    )
{
	KSocket *csock = this->mCtrlSock ;
	KSocket *dsock = this->mTranSock ;
	
	URL * furl = this->mUrl ;
	
	long * size = & bsize ;
	
	bool dret ;
	char rbuff[1024] = {0};
	char *pos = rbuff ;
	char *s = 0 ;
	char range[50] = {0};
	
		HttpHeader header;

		//fprintf(stderr , " GET %s \n" ,furl->GetPath());
		header.AddHeader( "GET", furl->GetFullPath() );
		header.AddHeader( "Host", furl->GetHost());
		header.AddHeader( "Connection", "Close");

		//header.Dump() ;
		
		sprintf(range,"bytes=%ld-", *size);
		header.AddHeader( "Range",range);
		std::string hs = header.HeaderString() ;
		csock->Write(hs.c_str(), hs.length());		

		fprintf(stderr , "%s" , hs.c_str());
		
		int rlen = 0 ;		
		do
		{
			
			rlen = csock->Peek(rbuff + rlen  , sizeof(rbuff) );
			fprintf(stderr, "Peeking %s \n" , rbuff );
			if( rlen <= 0 ) break ;
			if( ( s = strstr(rbuff ,"\r\n\r\n") ) != 0 )
			{
				*size = s - rbuff + 4 ;
				break ;
			}
			
		}while(true);
		
		header.ClearHeaders();
		header.Parse(rbuff);

		//header.Dump() ;
		std::string status = header.GetHeader( "Status" ) ;
		
		if ( status.compare("400") < 0 && status.compare("300") >= 0  ) 
		{
			//if follow into the redirector url
			//rewrite url
			//now this function lack test, i think i cant work correct
			fprintf(stderr , "400 Redirect Signal found\n");
			return false ;
		}
		else if ( status.compare("300") < 0 && status.compare("200") >= 0  ) 
		{
			//normal response
		}
		else //if( status.compare("200") < 0 || status.compare("400") >= 0 ) 
		{
			fprintf(stderr,"Header status (%s)  \n",header.GetHeader( "Status" ).c_str() );

			*size = 0 ;
			return false ;
		}		

		//read head now , really data 
		memset(rbuff,0,sizeof(rbuff));
		csock->Read(rbuff , *size ) ;
		//fprintf(stderr,"Header (%ld)  is %s \n", *size ,rbuff);

				
		*size = atol(header.GetHeader( "Content-Length" ).c_str());
	this->mContentLength = * size ;
		
	dsock->SetSocket(csock) ;
		
	dret = true ;
	
	return dret ; 
	return false ;
}
/** @brief IDLE state handler.
*
* @param[in] pDownloadHelper - Reference to PlaylistDownloadHelper
* @return
* HTTPDL_WAITING - Successfully initiated connection and GET request posted
*                  to the HTTP stack
* HTTPDL_ERROR_ABORT - Otherwise
*/
HTTPDownloadStatus PlaylistDownloadHelper::IdleStateHandler::Execute
(
 PlaylistDownloadHelper* pDownloadHelper
 )
{
  QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_LOW,
    "PlaylistDownloadHelper::IdleStateHandler::Execute()" );
  HTTPDownloadStatus status = HTTPCommon::HTTPDL_ERROR_ABORT;
  PlaylistDownloadHelper* pSelf = pDownloadHelper;

  //Validity check
  if (pSelf)
  {
    char* pLaunchURL = pSelf->m_pLaunchURL;

    //Fill in default port if port already not present in URL
    if (pSelf->ParseURL(HTTP_DEFAULT_PORT, pLaunchURL) && pLaunchURL)
    {
      HTTPMethodType methodType = HTTP_GET;
      status = HTTPCommon::HTTPDL_SUCCESS;
      pSelf->m_pLaunchURL = pLaunchURL;
      HTTPStackInterface& HTTPStack = *(pSelf->m_pHTTPStack);

      if(HTTPStack.CreateRequest(pSelf->m_nRequestID) == HTTP_SUCCESS)
      {
        URL url = pSelf->GetURL();
        char hostName[HTTP_MAX_HOSTNAME_LEN] = {0};
        if (url.GetHost(hostName, sizeof(hostName)) == URL::URL_OK)
        {
            (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "Host", (int)std_strlen("Host"),
            hostName, (int)std_strlen(hostName));
        }
        const char* pUserAgent = (pSelf->m_sessionInfo).GetUserAgent();
        if (pUserAgent)
        {
          (void)HTTPStack.SetHeader(pSelf->m_nRequestID, "User-Agent",
          (int)std_strlen("User-Agent"),
                                     pUserAgent, (int)std_strlen(pUserAgent));
        }
        HTTPCommon::AddIPStreamProtocolHeaders(pSelf->m_sessionInfo,HTTPStack,methodType, pSelf->m_nRequestID);
        //Send GET to get the playlist

          HTTPReturnCode result = HTTPStack.SendRequest(pSelf->m_nRequestID, methodType,
          pLaunchURL,
          (int)std_strlen(pLaunchURL));
        if (result == HTTP_SUCCESS)
        {
          //HTTP GET request successfully composed and posted to the HTTP stack.
          //So change state to WAITING_FOR_PLAYLIST and check back later
          status = HTTPCommon::HTTPDL_WAITING;
          pSelf->SetStateHandler(&pSelf->m_WaitingForPlaylistStateHandler);
          QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_HIGH,
            "HTTP GET request to get playlist successfully composed and posted "
            "to HTTP stack - proceeding to WAITING_FOR_PLAYLIST" );
        }
        else
        {
          QTV_MSG_PRIO1( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
            "Error: HTTP GET request send failed %d",
            result );
          status = HTTPCommon::HTTPDL_ERROR_ABORT;
        }
      }
      else
      {
        QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
                      "Error Creating Request");
      }
    }
    else
    {
      QTV_MSG_PRIO( QTVDIAG_HTTP_STREAMING, QTVDIAG_PRIO_ERROR,
        "Error: ParseURL failed" );
    }// if (pSelf->ParseURL(HTTP_DEFAULT_PORT, pLaunchURL) && pLaunchURL)
  }// if (pSelf && pSelf->GetState() == IDLE)

  return status;
}