⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psoap.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
}

void PSOAPMessage::SetFault( PINDEX code, const PString & text) 
{ 
  faultCode = code; 
  faultText = text; 

  PString faultCodeStr = faultCodeToString( code );

  SetMethod( "Fault", "" );

  AddParameter( "faultcode", "", faultCodeStr );
  AddParameter( "faultstring", "", text );

}



/*
 SOAP server classes
 ####################
 */



PSOAPServerResource::PSOAPServerResource()
  : PHTTPResource( DEFAULT_SOAP_URL ),
  soapAction( " " )
{
}

PSOAPServerResource::PSOAPServerResource(
      const PHTTPAuthority & auth )    // Authorisation for the resource.
  : PHTTPResource( DEFAULT_SOAP_URL, auth ),
  soapAction( " " )
{
}
PSOAPServerResource::PSOAPServerResource(
      const PURL & url )               // Name of the resource in URL space.
  : PHTTPResource(url )
{
}

PSOAPServerResource::PSOAPServerResource(
      const PURL & url,              // Name of the resource in URL space.
      const PHTTPAuthority & auth    // Authorisation for the resource.
    )
  : PHTTPResource( url, auth )
{
}

BOOL PSOAPServerResource::SetMethod(const PString & methodName, const PNotifier & func)
{
  // Set the method for the notifier function and add it to the list
  PWaitAndSignal m( methodMutex );

  // Find the method, or create a new one
  PSOAPServerMethod * methodInfo;
  
  PINDEX pos = methodList.GetValuesIndex( methodName );
  if (pos != P_MAX_INDEX)
  {
    methodInfo = ( PSOAPServerMethod *) methodList.GetAt( pos );
  }
  else 
  {
    methodInfo = new PSOAPServerMethod( methodName );
    methodList.Append( methodInfo );
  }

  // set the function
  methodInfo->methodFunc = func;

  return TRUE;
}

BOOL PSOAPServerResource::LoadHeaders( PHTTPRequest& /* request */ )    // Information on this request.
{
  return TRUE;
}

BOOL PSOAPServerResource::OnPOSTData( PHTTPRequest & request,
                                const PStringToString & /*data*/)
{
  PTRACE( 2, "PSOAPServerResource\tReceived post data, request: " << request.entityBody );

  PString reply;

  BOOL ok = FALSE;

  // Check for the SOAPAction header
  PString* pSOAPAction = request.inMIME.GetAt( "SOAPAction" );
  if ( pSOAPAction )
  {
    // If it's available check if we are expecting a special header value
    if ( soapAction.IsEmpty() || soapAction == " " )
    {
      // A space means anything goes
      ok = OnSOAPRequest( request.entityBody, reply );
    }
    else
    {
      // Check if the incoming header is the same as we expected
      if ( *pSOAPAction == soapAction )
      {
        ok = OnSOAPRequest( request.entityBody, reply );
      }
      else
      {
        ok = FALSE;
        reply = FormatFault( PSOAPMessage::Client, "Incorrect SOAPAction in HTTP Header: " + *pSOAPAction ).AsString();
      }
    }
  }
  else
  {
    ok = FALSE;
    reply = FormatFault( PSOAPMessage::Client, "SOAPAction is missing in HTTP Header" ).AsString();
  }

  // If everything went OK, reply with ReturnCode 200 (OK)
  if ( ok )
    request.code = PHTTP::RequestOK;
  else
    // Reply with InternalServerError (500)
    request.code = PHTTP::InternalServerError;

  // Set the correct content-type
  request.outMIME.SetAt(PHTTP::ContentTypeTag, "text/xml");

  // Start constructing the response
  PINDEX len = reply.GetLength();
  request.server.StartResponse( request.code, request.outMIME, len );
  
  // Write the reply to the client
  return request.server.Write( (const char* ) reply, len );
}


BOOL PSOAPServerResource::OnSOAPRequest( const PString & body, PString & reply )
{
  // Load the HTTP body into the SOAP (XML) parser
  PSOAPMessage request;
  BOOL ok = request.Load( body );

  // If parsing the XML to SOAP failed reply with an error
  if ( !ok ) 
  { 
    reply = FormatFault( PSOAPMessage::Client, "XML error:" + request.GetErrorString() ).AsString();
    return FALSE;
  }


  PString method;
  PString nameSpace;

  // Retrieve the method from the SOAP messsage
  request.GetMethod( method, nameSpace );

  PTRACE( 3, "PSOAPServerResource\tReceived SOAP message for method " << method);

  return OnSOAPRequest( method, request, reply );
}

BOOL PSOAPServerResource::OnSOAPRequest( const PString & methodName, 
                                            PSOAPMessage & request,
                                            PString & reply )
{
  methodMutex.Wait();

  // Find the method information
  PINDEX pos = methodList.GetValuesIndex( methodName );

  if ( pos == P_MAX_INDEX ) 
  {
    reply = FormatFault( PSOAPMessage::Client, "Unknown method = " + methodName ).AsString();
    return FALSE;
  }
  
  PSOAPServerMethod * methodInfo = ( PSOAPServerMethod * )methodList.GetAt( pos );
  PNotifier notifier = methodInfo->methodFunc;
  
  methodMutex.Signal();

  // create a request/response container to be passed to the notifier function
  PSOAPServerRequestResponse p( request );

  // call the notifier
  notifier( p, 0 );

  // get the reply

  reply = p.response.AsString();

  return p.response.GetFaultCode() == PSOAPMessage::NoFault;
}


PSOAPMessage PSOAPServerResource::FormatFault( PINDEX code, const PString & str )
{
  PTRACE(2, "PSOAPServerResource\trequest failed: " << str);

  PSOAPMessage reply;

  PString faultCodeStr = faultCodeToString( code );

  reply.SetMethod( "Fault", "" );

  reply.AddParameter( "faultcode", "", faultCodeStr );
  reply.AddParameter( "faultstring", "", str );

  return reply;
}


/*
 SOAP client classes
 ####################
 */


PSOAPClient::PSOAPClient( const PURL & _url )
  : url(_url),
  soapAction( " " )
{
  timeout = 10000;
}

BOOL PSOAPClient::MakeRequest( const PString & method, const PString & nameSpace )
{
  PSOAPMessage request( method, nameSpace );
  PSOAPMessage response;

  return MakeRequest( request, response );
}

BOOL PSOAPClient::MakeRequest( const PString & method, const PString & nameSpace, PSOAPMessage & response )
{
  PSOAPMessage request( method, nameSpace );

  return MakeRequest( request, response );
}

BOOL PSOAPClient::MakeRequest( PSOAPMessage & request, PSOAPMessage & response )
{
  return  PerformRequest( request, response );
}

BOOL PSOAPClient::PerformRequest( PSOAPMessage & request, PSOAPMessage & response )
{
  // create SOAP request
  PString soapRequest;

  PStringStream txt;
  
  if ( !request.Save( soapRequest ) ) 
  {
    
    txt << "Error creating request XML ("
        << request.GetErrorLine() 
        << ") :" 
        << request.GetErrorString();
    return FALSE;
  }

  // End with a newline
  soapRequest += "\n";

  PTRACE( 5, "SOAPClient\tOutgoing SOAP is " << soapRequest );

  // do the request
  PHTTPClient client;
  PMIMEInfo sendMIME, replyMIME;
  sendMIME.SetAt( "Server", url.GetHostName() );
  sendMIME.SetAt( PHTTP::ContentTypeTag, "text/xml" );
  sendMIME.SetAt( "SOAPAction", soapAction );

  if(url.GetUserName() != "") {
      PStringStream SoapAuthToken;
      SoapAuthToken << url.GetUserName() << ":" << url.GetPassword();
      sendMIME.SetAt( "Authorization", PBase64::Encode(SoapAuthToken) );
  }

  // Set thetimeout
  client.SetReadTimeout( timeout );

  // Send the POST request to the server
  BOOL ok = client.PostData( url, sendMIME, soapRequest, replyMIME );

  // Find the length of the response
  PINDEX contentLength;
  if ( replyMIME.Contains( PHTTP::ContentLengthTag ) )
    contentLength = ( PINDEX ) replyMIME[ PHTTP::ContentLengthTag ].AsUnsigned();
  else if ( ok)
    contentLength = P_MAX_INDEX;
  else
    contentLength = 0;

  // Retrieve the response
  PString replyBody = client.ReadString( contentLength );

  PTRACE( 5, "PSOAP\tIncoming SOAP is " << replyBody );

  // Check if the server really gave us something
  if ( !ok || replyBody.IsEmpty() ) 
  {
    txt << "HTTP POST failed: "
        << client.GetLastResponseCode() << ' '
        << client.GetLastResponseInfo();
  }

  // Parse the response only if the response code from the server
  // is either 500 (Internal server error) or 200 (RequestOK)

  if ( ( client.GetLastResponseCode() == PHTTP::RequestOK ) ||
       ( client.GetLastResponseCode() == PHTTP::InternalServerError ) )
  {
    if (!response.Load(replyBody)) 
    {
      txt << "Error parsing response XML ("
        << response.GetErrorLine() 
        << ") :" 
        << response.GetErrorString();
      
      PStringArray lines = replyBody.Lines();
      for ( int offset = -2; offset <= 2; offset++ ) {
        int line = response.GetErrorLine() + offset;
        
        if ( line >= 0 && line < lines.GetSize() )
          txt << lines[ ( PINDEX ) line ];
      }
    }
  }


  if ( ( client.GetLastResponseCode() != PHTTP::RequestOK ) &&
       ( client.GetLastResponseCode() != PHTTP::InternalServerError ) && 
       ( !ok ) )
  {
    response.SetFault( PSOAPMessage::Server, txt );
    return FALSE;
  }


  return TRUE;
}


#endif // P_EXPAT


// End of File ////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -