/home/coin/SVN-release/OS-2.3.3/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 }

Generated on Sun Mar 20 03:06:16 2011 by  doxygen 1.4.7