📄 psoap.cxx
字号:
/* * psoap.cxx * * SOAP client / server classes. * * Portable Windows Library * * Copyright (c) 2003 Andreas Sikkema * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Andreas Sikkema * * Contributor(s): ______________________________________. * * $Log: psoap.cxx,v $ * Revision 1.8 2004/04/24 01:06:32 rjongbloed * Apploed patch that impliments a number of checks to avoid segfaults when dealing with * various clients. Thanks Ben Lear * * Revision 1.7 2004/01/17 17:45:59 csoutheren * Changed to use PString::MakeEmpty * * Revision 1.6 2003/10/08 21:58:13 dereksmithies * Add client authentication support. many thanks to Ben Lear. * * Revision 1.5 2003/04/28 00:09:14 craigs * Patches from Andreas Sikkema * * Revision 1.4 2003/03/31 06:20:56 craigs * Split the expat wrapper from the XML file handling to allow reuse of the parser * * Revision 1.3 2003/02/09 23:31:54 robertj * Added referention PString's for efficiency. * * Revision 1.2 2003/02/09 23:22:46 robertj * Fixed spelling errors, and setting return values, thanks Andreas Sikkema * * Revision 1.1 2003/02/04 22:46:48 robertj * Added basic SOAP support, thanks Andreas Sikkema * */#ifdef __GNUC__#pragma implementation "psoap.h"#endif#include <ptlib.h>#if P_EXPAT#include <ptclib/psoap.h>/* SOAP message classes #################### */PSOAPMessage::PSOAPMessage( int options ) : PXML( options ), pSOAPBody( 0 ), pSOAPMethod( 0 ), faultCode( PSOAPMessage::NoFault ){}PSOAPMessage::PSOAPMessage( const PString & method, const PString & nameSpace ) : PXML( PXMLParser::Indent + PXMLParser::NewLineAfterElement ), pSOAPBody( 0 ), pSOAPMethod( 0 ), faultCode( PSOAPMessage::NoFault ){ SetMethod( method, nameSpace );}void PSOAPMessage::SetMethod( const PString & name, const PString & nameSpace ){ PXMLElement* rtElement = 0; if ( pSOAPBody == 0 ) { SetRootElement("SOAP-ENV:Envelope"); rtElement = GetRootElement(); rtElement->SetAttribute("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", TRUE ); rtElement->SetAttribute("xmlns:xsi", "http://www.w3.org/1999/XMLSchema-instance", TRUE ); rtElement->SetAttribute("xmlns:xsd", "http://www.w3.org/1999/XMLSchema", TRUE ); rtElement->SetAttribute("xmlns:SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", TRUE ); pSOAPBody = new PXMLElement( rtElement, "SOAP-ENV:Body"); rtElement->AddChild( pSOAPBody, TRUE ); } if ( pSOAPMethod == 0 ) { rtElement = GetRootElement(); pSOAPMethod = new PXMLElement( rtElement, PString( "m:") + name ); if ( nameSpace != "" ) { pSOAPMethod->SetAttribute("xmlns:m", nameSpace, TRUE ); } pSOAPBody->AddChild( pSOAPMethod, TRUE ); }}void PSOAPMessage::GetMethod( PString & name, PString & nameSpace ){ PString fullMethod = pSOAPMethod->GetName(); PINDEX sepLocation = fullMethod.Find(':'); if (sepLocation != P_MAX_INDEX) { PString methodID = fullMethod.Left(sepLocation); name = fullMethod.Right(fullMethod.GetSize() - 2 - sepLocation); nameSpace = pSOAPMethod->GetAttribute( "xmlns:" + methodID ); }}void PSOAPMessage::AddParameter( PString name, PString type, PString value ){ if ( pSOAPMethod ) { PXMLElement* rtElement = GetRootElement(); PXMLElement* pParameter = new PXMLElement( rtElement, name); PXMLData* pParameterData = new PXMLData( pParameter, value); if ( type != "" ) { pParameter->SetAttribute( "xsi:type", PString( "xsd:" ) + type ); } pParameter->AddChild( pParameterData, TRUE ); AddParameter( pParameter, TRUE ); }}void PSOAPMessage::AddParameter( PXMLElement* parameter, BOOL dirty ){ if ( pSOAPMethod ) { pSOAPMethod->AddChild( parameter, dirty ); }}void PSOAPMessage::PrintOn(ostream & strm) const{ BOOL newLine = ( options & PXMLParser::NewLineAfterElement ) != 0; PString ver = version; PString enc = encoding; int salone = standAlone; if ( ver.IsEmpty() ) ver= "1.0"; if ( enc.IsEmpty() ) enc = "UTF-8"; if ( salone == -2 ) salone = -1; strm << "<?xml version=\"" << ver << "\" encoding=\"" << enc << "\""; switch ( salone ) { case 0: strm << " standalone=\"no\""; break; case 1: strm << " standalone=\"yes\""; break; default: break; } strm << "?>"; if ( newLine ) strm << endl; if ( rootElement != NULL ) { rootElement->Output(strm, *(this), 2 ); }}PString PSOAPMessage::AsString( void ){ PStringStream stringStream; PrintOn( stringStream ); PString SOAPString = stringStream; return SOAPString;}PString faultCodeToString( PINDEX faultCode ){ PString faultCodeStr; switch ( faultCode ) { case PSOAPMessage::VersionMismatch: faultCodeStr = "VersionMisMatch"; break; case PSOAPMessage::MustUnderstand: faultCodeStr = "MustUnderstand"; break; case PSOAPMessage::Client: faultCodeStr = "Client"; break; case PSOAPMessage::Server: faultCodeStr = "Server"; break; default: // Default it's the server's fault. Can't blame it on the customer, because he/she is king ;-) faultCodeStr = "Server"; break; } return faultCodeStr;}PINDEX stringToFaultCode( PString & faultStr ){ if ( faultStr == "VersionMisMatch" ) return PSOAPMessage::VersionMismatch; if ( faultStr == "MustUnderstand" ) return PSOAPMessage::MustUnderstand; if ( faultStr == "Client" ) return PSOAPMessage::Client; if ( faultStr == "Server" ) return PSOAPMessage::Server; return PSOAPMessage::Server;}BOOL PSOAPMessage::GetParameter( const PString & name, PString & value ){ PXMLElement* pElement = GetParameter( name ); if(pElement == NULL) return FALSE; if ( pElement->GetAttribute( "xsi:type") == "xsd:string" ) { value = pElement->GetData(); return TRUE; } value.MakeEmpty(); return FALSE;}BOOL PSOAPMessage::GetParameter( const PString & name, int & value ){ PXMLElement* pElement = GetParameter( name ); if(pElement == NULL) return FALSE; if ( pElement->GetAttribute( "xsi:type") == "xsd:int" ) { value = pElement->GetData().AsInteger(); return TRUE; } value = -1; return FALSE;}PXMLElement* PSOAPMessage::GetParameter( const PString & name ){ if ( pSOAPMethod ) { return pSOAPMethod->GetElement( name, 0 ); } else { return 0; }}BOOL PSOAPMessage::Load( const PString & str ){ if ( !PXML::Load( str ) ) return FALSE; if ( rootElement != NULL ) { PString soapEnvelopeName = rootElement->GetName(); PString soapEnvelopeID = soapEnvelopeName.Left( soapEnvelopeName.Find(':') ); pSOAPBody = rootElement->GetElement( soapEnvelopeID + ":Body", 0 ); if ( pSOAPBody != NULL ) { PXMLObjectArray subObjects = pSOAPBody->GetSubObjects() ; PINDEX idx; PINDEX size = subObjects.GetSize(); for ( idx = 0; idx < size; idx++ ) { if ( subObjects[ idx ].IsElement() ) { // First subobject being an element is the method pSOAPMethod = ( PXMLElement * ) &subObjects[ idx ]; PString method; PString nameSpace; GetMethod( method, nameSpace ); // Check if method name is "Fault" if ( method == "Fault" ) { // The SOAP server has signalled an error PString faultCodeData = GetParameter( "faultcode" )->GetData(); faultCode = stringToFaultCode( faultCodeData ); faultText = GetParameter( "faultstring" )->GetData(); } else { return TRUE; } } } } } return FALSE;}void PSOAPMessage::SetFault( PINDEX code, const PString & text)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -