📄 psoap.cxx
字号:
}
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 + -