00001
00024
00025
00027
00028 #pragma warning ( disable: 4786 )
00029 #include "SOAPonHTTP.h"
00030 #ifndef _SSTREAM_
00031 #include <sstream>
00032 #endif // _SSTREAM_
00033 #include <iostream>
00034 #if !defined(SOAPPARSER_H)
00035 #include "SOAPParser.h"
00036 #endif // !defined(SOAPPARSER_H)
00037 #if !defined(SOAPELEMENT_H)
00038 #include "SOAPElement.h"
00039 #endif // !defined(SOAPELEMENT_H)
00040 #if !defined(SOAPENCODER_H)
00041 #include "SOAPEncoder.h"
00042 #endif // SOAPENCODER_H
00043 #if !defined(SOAPMETHOD_H)
00044 #include "SOAPMethod.h"
00045 #endif // SOAPMETHOD_H
00046 #include "TcpSocket.h"
00047 #include "IpAddress.h"
00048 #include <iostream>
00049
00050
00051 #ifdef _MSC_VER
00052 #define sleep Sleep
00053 #define snprintf _snprintf
00054 #endif
00055
00057
00059
00060
00061 const std::string g_KszPost = "POST ";
00062 const std::string g_KszManHeader =
00063 "\"http://schemas.xmlsoap.org.soap/envelope/\"";
00064 const std::string g_KszContentType =
00065 "Content-type: text/xml; charset=utf-8";
00066 const std::string g_KszContentLength = "Content-Length: ";
00067 const std::string g_KszSOAPAction = "SOAPAction: ";
00068 const std::string g_KszHTTPversion = "HTTP/1.0";
00069 const std::string g_KszSOAP = "<SOAP";
00070 const std::string g_KszBody = "Body";
00071
00072 SOAPonHTTP::SOAPonHTTP()
00073 {
00074
00075 }
00076
00077 SOAPonHTTP::~SOAPonHTTP()
00078 {
00079
00080 }
00081
00082 std::string SOAPonHTTP::getSendableMessage(
00083 const std::string& szSOAPMessage,
00084 const std::string& szClassName,
00085 const std::string& szMethodName )
00086 {
00087 std::ostringstream szRetval;
00088 const long KnLength = szSOAPMessage.length();
00089
00090
00091
00092 szRetval << g_KszPost << "/" << szClassName << " "
00093 << g_KszHTTPversion << std::endl;
00094 szRetval << g_KszContentType << std::endl;
00095 szRetval << g_KszContentLength << szSOAPMessage.length()
00096 << std::endl;
00097 szRetval << g_KszSOAPAction << "\"" << szClassName << "#"
00098 << szMethodName << "\"" << std::endl << std::endl;
00099 szRetval << szSOAPMessage;
00100 return szRetval.str();
00101 }
00102
00103 void SOAPonHTTP::setHostAndPort( std::string szHost,
00104 long nPort )
00105 {
00106
00107 IpAddress ipAddress( szHost );
00108 m_socketAddress.setIpAddress( ipAddress );
00109 m_socketAddress.setPort( nPort );
00110 }
00111
00112 bool SOAPonHTTP::getMethodDetails( const std::string& KszMessage,
00113 std::string& szObjectName, std::string& szMethodName,
00114 SOAPElement& theCall )
00115 {
00116 bool retval = true;
00117
00118 long nPos = KszMessage.find( g_KszPost );
00119
00120
00121 nPos = KszMessage.find( "/", nPos );
00122
00123
00124
00125 long nEndPos = KszMessage.find( " ", nPos );
00126
00127 ++nPos;
00128 szObjectName = KszMessage.substr( nPos, nEndPos - nPos );
00129
00130 std::string szSOAPMessage;
00131
00132
00133 nPos = KszMessage.find( g_KszSOAP );
00134 if ( nPos >= 0 )
00135 {
00136 szSOAPMessage =
00137 KszMessage.substr( nPos, KszMessage.length() - nPos );
00138 }
00139
00140
00141 SOAPParser soapParser;
00142 retval = soapParser.parseMessage( szSOAPMessage, theCall );
00143 if ( retval )
00144 {
00145
00146
00147
00148
00149
00150
00151 SOAPElement* pBody = NULL;
00152 theCall.getElement( g_KszBody, &pBody );
00153 if ( NULL != pBody )
00154 {
00155 SOAPElement& aMethod = pBody->elementAt( 0 );
00156 szMethodName = aMethod.accessorName();
00157 }
00158 if ( szMethodName.length() <= 0 )
00159 {
00160
00161 retval = false;
00162 }
00163 }
00164 else
00165 {
00166 szObjectName =
00167 SOAPEncoder().encodeFault( *(soapParser.getFault()) );
00168 }
00169 return retval;
00170 }
00171
00172
00173 std::string SOAPonHTTP::getSendableResponse(
00174 const std::string& szSOAPMessage, bool bIsFault )
00175 {
00176 std::string retval;
00177
00178
00179
00180
00181
00182 retval = "HTTP/1.1 ";
00183 if ( bIsFault )
00184 {
00185 retval += "500 Internal Server Error\r\n";
00186 }
00187 else
00188 {
00189 retval += "200 OK\r\n";
00190 }
00191
00192 retval += g_KszContentType;
00193 retval += "\r\nContent-Length: ";
00194 char buffer[33];
00195 snprintf( buffer, 33, "%d", szSOAPMessage.length() );
00196 retval += buffer;
00197 retval += "\r\n\r\n";
00198 retval += szSOAPMessage;
00199 return retval;
00200 }
00201
00202 std::string SOAPonHTTP::send( const std::string& szClassName,
00203 SOAPMethod& aMethod )
00204 {
00205 SOAPEncoder soapEncoder;
00206
00207
00208 std::string szCall = soapEncoder.encodeMethodCall( aMethod );
00209
00210
00211 std::string szSend = getSendableMessage(
00212 szCall, szClassName, aMethod.methodName() );
00213 std::cerr << szSend;
00214
00215
00216 const int KnBuffSize = 10000;
00217 char *buffer = new char[KnBuffSize + 1];
00218 memset( buffer, 0, KnBuffSize );
00219 TcpSocket theSocket;
00220
00221
00222 theSocket.connectTo( m_socketAddress );
00223
00224
00225 theSocket.write( szSend.c_str(), szSend.length() );
00226
00227 szSend = "";
00228
00229
00230
00231 int bytes, zcnt = 0, cnt = 0;
00232 memset( buffer, 0, KnBuffSize );
00233 do
00234 {
00235 if ( (bytes = theSocket.read( buffer, KnBuffSize )) == 0 )
00236 {
00237 sleep( 100 );
00238 ++zcnt;
00239 }
00240
00241 if ( bytes )
00242 zcnt = 0;
00243
00244 cnt += bytes;
00245 buffer[bytes] = 0;
00246 szSend += buffer;
00247 }
00248 while ( ( strstr( buffer, "</SOAP-ENV:Envelope>" ) == NULL ) && ( zcnt < 20 ) );
00249
00250
00251 theSocket.close();
00252 delete buffer;
00253
00254
00255 return szSend;
00256 }