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