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