/home/coin/SVN-release/OS-2.4.1/OS/src/OSAgent/OSWSUtil.cpp

Go to the documentation of this file.
00001 /* $Id: OSWSUtil.cpp 4292 2011-09-21 05:47:18Z kmartin $ */
00016 //#define DEBUG
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 // need to include OSParameters.h after winsock.h, because it may include unistd.h, which needs to know that winsock.h has already been included
00031 // unfortunately, the windows stuff defines a macro named "max", and maybe also "min"? so undefine these first
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         /* code taken from "TCP/IP Sockets in C" by Donahoo and Calvert */
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         /* Create a reliable, stream socket using TCP */
00083         if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) throw ErrorClass( "failure creating socket");
00084         /* Construct the server address structure */
00085         memset(&httpServAddr, 0, sizeof(httpServAddr));     /* Zero out structure */
00086         httpServAddr.sin_family      = AF_INET;             /* Internet address family */
00087         httpServAddr.sin_addr.s_addr = ResolveName( servIP);   /* Server IP address */
00088         httpServAddr.sin_port        = htons(httpServPort); /* Server port */
00089         /* Establish the connection to the http server */
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         /* Send the string to the server */
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                     //cout << "char_val = " << char_val << endl;
00132                 }
00133             }
00134 #endif
00135             //httpBuffer[ recvMsgSize ] = '\0';
00136             ret_message << httpBuffer;
00137             // clear the buffer
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 //              OSResult osresult;
00154 //              OSrLWriter osrlwriter;
00155 //              string osrl;
00156 //              osresult.setGeneralMessage( eclass.errormsg);
00157 //              osresult.setGeneralStatusType( "error");
00158 //              osrl = osrlwriter.writeOSrL( &osresult);
00159 //              throw ErrorClass( osrl);
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     //request << "POST "  <<  postURI << " HTTP/1.0" <<  "\r";
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     //body << "<?xml version='1.0' encoding='utf-8' ?>" << endl;
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 }// end createSOAPMessage
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     //request << "Referer: /servlets-examples/fileupload.html" << endl;
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     //return theFile;
00248 }// end createFromDataUpload
00249 
00250 
00251 string WSUtil::SOAPify(std::string inputstring, bool useCDATA)
00252 {
00253     /* replace all occurances of "<" with "&lt;"  all
00254     occurances of ">" with "&gt;" and all occurances of " or ' with &quote;
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 << "&lt;";
00276                 break;
00277             case '>':
00278                 body << "&gt;";
00279                 break;
00280             case '\"':
00281                 body << "&quot;";
00282                 break;
00283             case '\'':
00284                 body << "&quot;";
00285                 break;
00286             default:
00287                 body << inputstring[i];
00288             }
00289             i++;
00290         }//end while
00291     }
00292     return body.str();
00293 }
00294 
00295 string WSUtil::deSOAPify(std::string inputstring, bool useCDATA)
00296 {
00297     /* replace all occurances of "&lt;" with "<"  all
00298     occurances of "&gt;" with ">" and all occurances of "&quote;" with "
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         //kipp -- put in error checking
00311 
00312     }
00313     else
00314     {
00315         while (i < loopsize)
00316         {
00317             //i = inputstring.find('&', i);
00318             //if (i == string::npos)  return ostringstream.str();
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                 } //end switch
00349             } // end if'&"
00350             else
00351             {
00352                 body << inputstring[i];
00353                 i++;
00354             }
00355         }// end while
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 //void DieWithError(char *errorMessage)
00380 //{
00381 //      #ifdef DEBUG
00382 //    cout << errorMessage << endl;
00383 //      #endif
00384 //    exit(1);
00385 //}
00386 
00387 string WSUtil::getOSxL(string soapstring, string serviceMethod)
00388 {
00389     /*  get the string that starts with <osxl
00390      * inside the soap envelope
00391      */
00392     //string start = "";
00393     //string end = "";
00394     string result = "";
00395     //start = "<" + serviceMethod + "Return";
00396     //end = "</"+serviceMethod + "Return";
00397     // strip off the return header information
00398     // find start of XML information
00399     string::size_type startxml = soapstring.find(serviceMethod+"Return" , 1);
00400     string::size_type pos;
00401     if (startxml == string::npos)
00402     {
00403         //something went wrong, perhaps we had an error in service location
00404 
00405         OSResult *osresult = NULL;
00406         OSrLWriter *osrlwriter = NULL;
00407         osrlwriter = new OSrLWriter();
00408         osresult = new OSResult();
00409         // see if the SOAP contains <faultstring> -- if so use it
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         // find the end of the string
00436         string::size_type endxml = soapstring.find( "</", startxml);
00437         // now go back for the </
00438 
00439         if(endxml == string::npos)
00440         {
00441             return result;
00442         }
00443         else
00444         {
00445             // get the > that ends </osxl
00446             //endxml = soapstring.find(">", endxml - 1);
00447             // now get the substring
00448             startxml++;
00449             result = soapstring.substr(startxml, endxml - startxml);
00450             return result;
00451         }
00452     }
00453     return result;
00454 }

Generated on Thu Nov 10 03:05:47 2011 by  doxygen 1.4.7