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