00001
00016 #include "OSConfig.h"
00017 #include "WSUtil.h"
00018 #ifdef WIN_
00019
00020 #include <winsock.h>
00021 #else
00022 #include <sys/socket.h>
00023 #include <arpa/inet.h>
00024 #include <unistd.h>
00025 #include <netdb.h>
00026 #endif
00027
00028 #include <cstring>
00029
00030
00031
00032 #include <iostream>
00033 #include <sstream>
00034 #include "ErrorClass.h"
00035 #include "OSResult.h"
00036 #include "OSrLWriter.h"
00037
00038 using std::string;
00039 using std::cout;
00040 using std::endl;
00041 using std::ostringstream;
00042
00043
00044 WSUtil::WSUtil(){
00045 }
00046
00047 WSUtil::~WSUtil(){
00048 }
00049
00050
00051
00052 string WSUtil::sendSOAPMessage(string theSOAP, string serviceIP, unsigned int servicePortNumber)
00053 {
00054 try{
00055
00056 unsigned long ResolveName(char *name);
00057 ostringstream ret_message;
00058 int sock;
00059 struct sockaddr_in httpServAddr;
00060 unsigned short httpServPort = servicePortNumber;
00061 char *servIP = &serviceIP[0];
00062 char httpBuffer[RCVBUFSIZE] = "";
00063 int httpStringLen;
00064 char* message = &theSOAP[0];
00065 #ifdef WIN_
00066 WSADATA wsaData;
00067 if( WSAStartup(MAKEWORD(2, 0), &wsaData) != 0 ) throw ErrorClass( "WSAStartup failed");
00068 #endif
00069
00070 if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) throw ErrorClass( "failure creating socket");
00071
00072 memset(&httpServAddr, 0, sizeof(httpServAddr));
00073 httpServAddr.sin_family = AF_INET;
00074 httpServAddr.sin_addr.s_addr = ResolveName( servIP);
00075 httpServAddr.sin_port = htons(httpServPort);
00076
00077 if (connect(sock, (struct sockaddr *) &httpServAddr, sizeof(httpServAddr)) < 0){
00078 string sipadd = &serviceIP[0];
00079 string errormsg = "failure connecting with remote socket at address: " + sipadd ;
00080 throw ErrorClass( errormsg );
00081 }
00082 #ifdef DEBUG
00083 cout << "Connection Established" << endl;
00084 #endif
00085 httpStringLen = strlen( message);
00086 #ifdef DEBUG
00087 cout << "HERE IS WHAT WE SEND" << endl;
00088 cout << message << endl;
00089 #endif
00090
00091 if (send(sock, message, httpStringLen, 0) != httpStringLen)
00092 throw ErrorClass("send() sent a different number of bytes than expected");
00093 #ifdef DEBUG
00094 cout << "OSiL sent to server" << endl;
00095 #endif
00096 int recvMsgSize = 1;
00097 int n;
00098 #ifdef DEBUG
00099 int char_val;
00100 #endif
00101 httpBuffer[ RCVBUFSIZE - 1] = '\0';
00102 while (recvMsgSize > 0) {
00103 #ifdef DEBUG
00104 cout << "start to receive" << endl;
00105 #endif
00106 if ((recvMsgSize = recv(sock, httpBuffer, RCVBUFSIZE-1, 0)) < 0)
00107 throw ErrorClass( "socket error receiving data");
00108 #ifdef DEBUG
00109 cout << "Message size = " << recvMsgSize << endl;
00110 printf("%s\n", httpBuffer);
00111 if(recvMsgSize < (RCVBUFSIZE - 1) ){
00112 for(n = 0; n < recvMsgSize; n++){
00113 char_val = httpBuffer[ n];
00114
00115 }
00116 }
00117 #endif
00118
00119 ret_message << httpBuffer;
00120
00121 for(n = 0; n < RCVBUFSIZE; n++){
00122 httpBuffer[ n] = 0;
00123 }
00124 }
00125 #ifdef WIN_
00126 closesocket( sock);
00127 WSACleanup();
00128 #else
00129 close( sock);
00130 #endif
00131 return ret_message.str();
00132 }
00133 catch(const ErrorClass& eclass){
00134 OSResult osresult;
00135 OSrLWriter osrlwriter;
00136 string osrl;
00137 osresult.setGeneralMessage( eclass.errormsg);
00138 osresult.setGeneralStatusType( "error");
00139 osrl = osrlwriter.writeOSrL( &osresult);
00140 throw ErrorClass( osrl);
00141 }
00142 }
00143
00144 std::string WSUtil::createSOAPMessage(int numInputs, string solverAddress, string postURI, string smethod,
00145 string* msInputs, string* msInputNames, string sSoapAction){
00146 ostringstream request, body, msg;
00147 int i;
00148 string mynamespace = "xmlns:ns1=\"http://www.optimizationservices.org\"";
00149 #ifdef DEBUG
00150 cout << "Solver address = " << solverAddress << endl;
00151 cout << "SOAP action = " << sSoapAction << endl;
00152 cout << "postURI = " << postURI << endl;
00153 #endif
00154
00155 request << "POST " << postURI << " HTTP/1.0" << endl ;
00156 request << "Content-Type: text/xml; charset=UTF-8" << endl;
00157 request << "Host: " ;
00158 request << solverAddress << endl;
00159 request << "Connection: close" << endl;
00160 request << "Accept: application/soap+xml, application/dime, multipart/related, text/*" << endl;
00161 request << "Cache-Control: no-cache" << endl;
00162 request << "Pragma: no-cache" << endl;
00163 request << "SOAPAction: ";
00164 request << "\"" << sSoapAction << "\"" << endl;
00165
00166 body << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" << endl;
00167 body << "<SOAP-ENV:Body>" << endl;
00168 body << "<ns1:" << smethod << " " << mynamespace << ">" << endl;
00169 for(i = 0; i < numInputs; i++){
00170 body << "<" << msInputNames[ i] << " xsi:type=\"xsd:string\"" << ">" ;
00171 body << msInputs[ i] ;
00172 body << "</" << msInputNames[ i] << ">" << endl;
00173 }
00174 body << "</ns1:" << smethod << ">" << endl;
00175 body << "</SOAP-ENV:Body>" << endl;
00176 body << "</SOAP-ENV:Envelope>" << endl;
00177 body << "\n";
00178 request << "Content-Length: " << body.str().length();
00179 request << endl << endl;
00180
00181 request << body.str();
00182 return request.str();
00183 }
00184
00185 std::string WSUtil::createFormDataUpload(std::string solverAddress, std::string postURI,
00186 std::string fileName, std::string theFile, std::string boundaryName){
00187 ostringstream request, body;
00188 std::cout << "Solver address = " << solverAddress << std::endl;
00189 std::cout << "postURI = " << postURI << std::endl;
00190 request << "POST " << postURI << " HTTP/1.0" << "\r\n";
00191 request << "Host: " ;
00192 request << solverAddress << "\r\n";
00193 request << "Content-Type: multipart/form-data; boundary=" ;
00194 request << boundaryName << "\r\n";
00195 request << "Connection: keep-alive" << "\r\n";
00196
00197 body << "--" ;
00198 body << boundaryName ;
00199 body << "\r\n";
00200 body << "Content-Disposition: form-data; name=\"";
00201 body << "myfile";
00202 body << "\"";
00203 body << ";";
00204 body << " filename=\"";
00205 body << fileName;
00206 body << "\"" << "\r\n";
00207
00208 body << "Content-Type: text/plain" ;
00209 body << "\r\n" ;
00210 body << "\r\n";
00211 body << theFile ;
00212 body << "\r\n";
00213 body << "--" ;
00214 body << boundaryName;
00215 body << "--" ;
00216 body << "\r\n" ;
00217
00218
00219 request << "Content-Length: " << body.str().length();
00220 request << "\r\n";
00221 request << "\r\n";
00222 request << body.str();
00223 return request.str();
00224
00225 }
00226
00227
00228 string WSUtil::SOAPify(string inputstring){
00229
00230
00231
00232 #ifdef DEBUG
00233 cout << "prepare the XML for a SOAP envelope" << endl;
00234 #endif
00235 ostringstream body;
00236 int i = 0;
00237 int loopsize = inputstring.length();
00238 while (i < loopsize){
00239 switch( inputstring[i]){
00240 case '<':
00241 body << "<";
00242 break;
00243 case '>':
00244 body << ">";
00245 break;
00246 case '\"':
00247 body << """;
00248 break;
00249 case '\'':
00250 body << """;
00251 break;
00252 default:
00253 body << inputstring[i];
00254 }
00255 i++;
00256 }
00257 return body.str();
00258 }
00259
00260 string WSUtil::deSOAPify(string inputstring){
00261
00262
00263
00264 ostringstream body;
00265 int i = 0;
00266 int loopsize = inputstring.length();
00267 while (i < loopsize){
00268
00269
00270 if(inputstring[i] == '&'){
00271 switch (inputstring[i+1]) {
00272 case 'l':
00273 if (inputstring[i + 2] == 't' && inputstring[i + 3] == ';') {
00274 body << "<";
00275 }
00276 i = i + 4;
00277 break;
00278 case 'g':
00279 if (inputstring[i + 2] == 't' && inputstring[i + 3] == ';') {
00280 body << ">";
00281 }
00282 i = i + 4;
00283 break;
00284 case 'q':
00285 if (inputstring[i + 2] == 'u' && inputstring[i + 3] == 'o' && inputstring[i + 4] == 't' && inputstring[i + 5] == ';') {
00286 body << "\"";
00287 }
00288 i = i + 6;
00289 break;
00290 default:
00291 body << inputstring[i];
00292 i++;
00293 break;
00294 }
00295 }
00296 else{
00297 body << inputstring[i];
00298 i++;
00299 }
00300 }
00301 return body.str();
00302 }
00303
00304 unsigned long ResolveName(char *name){
00305 struct hostent *host;
00306 try{
00307 if ((host = gethostbyname(name)) == NULL){
00308 string s1 = &name[0];
00309 string errormsg = "cannot resolve the domain name: " + s1;
00310 throw ErrorClass( errormsg);
00311 }
00312 return *((unsigned long *) host->h_addr_list[0]);
00313 }
00314 catch(const ErrorClass& eclass){
00315 throw eclass;
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 string WSUtil::getOSxL(string soapstring, string serviceMethod){
00328
00329
00330
00331 string start = "";
00332 string end = "";
00333 string result = "";
00334 start = "<" + serviceMethod + "Return";
00335 end = "</"+serviceMethod + "Return";
00336
00337
00338 string::size_type startxml = soapstring.find(start , 1);
00339 if (startxml == string::npos){
00340 return result;
00341 }
00342 else{
00343 startxml = soapstring.find(">", startxml + 1);
00344 if(startxml == string::npos) return result;
00345
00346 string::size_type endxml = soapstring.find(end , startxml);
00347 if(endxml == string::npos){
00348 return result;
00349 }
00350 else{
00351
00352
00353
00354 startxml++;
00355 result = soapstring.substr(startxml, endxml - startxml);
00356 return result;
00357 }
00358 }
00359 return result;
00360 }