- Main Page
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

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

Go to the documentation of this file.

    00001 /* $Id: OSWSUtil.cpp 3246 2010-02-27 00:03:53Z kmartin $ */
    00018 //#define DEBUG
    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                 /* code taken from "TCP/IP Sockets in C" by Donahoo and Calvert */
    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                 /* Create a reliable, stream socket using TCP */
    00072                 if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) throw ErrorClass( "failure creating socket");
    00073                 /* Construct the server address structure */
    00074                 memset(&httpServAddr, 0, sizeof(httpServAddr));     /* Zero out structure */
    00075                 httpServAddr.sin_family      = AF_INET;             /* Internet address family */
    00076                 httpServAddr.sin_addr.s_addr = ResolveName( servIP);   /* Server IP address */
    00077                 httpServAddr.sin_port        = htons(httpServPort); /* Server port */
    00078                 /* Establish the connection to the http server */
    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                 /* Send the string to the server */
    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                                                 //cout << "char_val = " << char_val << endl;
    00117                                         }
    00118                                 }
    00119                         #endif
    00120                         //httpBuffer[ recvMsgSize ] = '\0';
    00121                         ret_message << httpBuffer;
    00122                         // clear the buffer
    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 //              OSResult osresult;
    00137 //              OSrLWriter osrlwriter;
    00138 //              string osrl;
    00139 //              osresult.setGeneralMessage( eclass.errormsg);
    00140 //              osresult.setGeneralStatusType( "error");
    00141 //              osrl = osrlwriter.writeOSrL( &osresult);
    00142 //              throw ErrorClass( osrl);
    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         //request << "POST "  <<  postURI << " HTTP/1.0" <<  "\r";
    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         //body << "<?xml version='1.0' encoding='utf-8' ?>" << endl;
    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 }// end createSOAPMessage
    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         //request << "Referer: /servlets-examples/fileupload.html" << endl;
    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         //return theFile;
    00228 }// end createFromDataUpload
    00229
    00230
    00231 string WSUtil::SOAPify(std::string inputstring, bool useCDATA){
    00232         /* replace all occurances of "<" with "&lt;"  all
    00233         occurances of ">" with "&gt;" and all occurances of " or ' with &quote;
    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 << "&lt;";
    00250                                         break;
    00251                                 case '>':
    00252                                         body << "&gt;";
    00253                                         break;
    00254                                 case '\"':
    00255                                         body << "&quot;";
    00256                                         break;
    00257                                 case '\'':
    00258                                         body << "&quot;";
    00259                                         break;
    00260                                 default:
    00261                                 body << inputstring[i];
    00262                         }
    00263                         i++;
    00264                 }//end while
    00265         }
    00266         return body.str();
    00267 }
    00268
    00269 string WSUtil::deSOAPify(std::string inputstring, bool useCDATA){
    00270         /* replace all occurances of "&lt;" with "<"  all
    00271         occurances of "&gt;" with ">" and all occurances of "&quote;" with "
    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                 //kipp -- put in error checking
    00283
    00284         }else{
    00285                 while (i < loopsize){
    00286                         //i = inputstring.find('&', i);
    00287                         //if (i == string::npos)  return ostringstream.str();
    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                                 } //end switch
    00313                         } // end if'&"
    00314                         else{
    00315                                 body << inputstring[i];
    00316                                 i++;
    00317                         }
    00318                 }// end while
    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 //void DieWithError(char *errorMessage)
    00339 //{
    00340 //      #ifdef DEBUG
    00341 //    cout << errorMessage << endl;
    00342 //      #endif
    00343 //    exit(1);
    00344 //}
    00345
    00346 string WSUtil::getOSxL(string soapstring, string serviceMethod){
    00347         /*  get the string that starts with <osxl
    00348          * inside the soap envelope
    00349          */
    00350         //string start = "";
    00351         //string end = "";
    00352         string result = "";
    00353         //start = "<" + serviceMethod + "Return";
    00354         //end = "</"+serviceMethod + "Return";
    00355         // strip off the return header information
    00356         // find start of XML information
    00357         string::size_type startxml = soapstring.find(serviceMethod+"Return" , 1);
    00358         string::size_type pos;
    00359         if (startxml == string::npos){
    00360                 //something went wrong, perhaps we had an error in service location
    00361
    00362                 OSResult *osresult = NULL;
    00363                 OSrLWriter *osrlwriter = NULL;
    00364                 osrlwriter = new OSrLWriter();
    00365                 osresult = new OSResult();
    00366                 // see if the SOAP contains <faultstring> -- if so use it
    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                 // find the end of the string
    00390                 string::size_type endxml = soapstring.find( "</", startxml);
    00391                 // now go back for the </
    00392
    00393                 if(endxml == string::npos){
    00394                         return result;
    00395                 }
    00396                 else{
    00397                         // get the > that ends </osxl
    00398                         //endxml = soapstring.find(">", endxml - 1);
    00399                         // now get the substring
    00400                         startxml++;
    00401                         result = soapstring.substr(startxml, endxml - startxml);
    00402                         return result;
    00403                 }
    00404         }
    00405         return result;
    00406 }