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

Go to the documentation of this file.
00001 /* $Id: OSWSUtil.cpp 2698 2009-06-09 04:14:07Z 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         }
00144 }
00145 
00146 std::string WSUtil::createSOAPMessage(int numInputs,  string solverAddress, string postURI, string smethod, 
00147         string* msInputs, string* msInputNames, string sSoapAction){
00148         ostringstream request, body, msg;
00149         int i;
00150         string mynamespace = "xmlns:ns1=\"http://www.optimizationservices.org\"";
00151         #ifdef DEBUG
00152         cout << "Solver address = " <<  solverAddress << endl;
00153         cout << "SOAP action = " <<  sSoapAction << endl;
00154         cout << "postURI = " <<  postURI << endl;
00155         #endif
00156         //request << "POST "  <<  postURI << " HTTP/1.0" <<  "\r";
00157         request << "POST "  <<  postURI << " HTTP/1.0" << endl ;
00158         request << "Content-Type: text/xml; charset=UTF-8" << endl;
00159         request << "Host: " ;
00160         request << solverAddress << endl;
00161         request << "Connection: close" << endl;
00162         request << "Accept: application/soap+xml, application/dime, multipart/related, text/*" << endl;
00163         request << "Cache-Control: no-cache" << endl;
00164         request << "Pragma: no-cache" << endl;
00165         request << "SOAPAction: ";
00166         request << "\"" << sSoapAction << "\"" << endl;
00167         //body << "<?xml version='1.0' encoding='utf-8' ?>" << endl;
00168         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;
00169         body << "<SOAP-ENV:Body>" << endl;
00170         body << "<ns1:" << smethod << " " << mynamespace << ">" << endl;
00171         for(i = 0; i < numInputs; i++){
00172                 body << "<" << msInputNames[ i] << " xsi:type=\"xsd:string\"" << ">" ;
00173                 body << msInputs[ i] ;
00174                 body << "</" << msInputNames[ i] << ">" << endl;
00175         }
00176         body << "</ns1:" << smethod << ">" << endl;
00177         body << "</SOAP-ENV:Body>" << endl;
00178         body << "</SOAP-ENV:Envelope>" << endl;
00179         body << "\n";
00180         request << "Content-Length: " << body.str().length();
00181         request << endl << endl;
00182 
00183         request << body.str();
00184         return request.str();
00185 }// end createSOAPMessage
00186 
00187 std::string WSUtil::createFormDataUpload(std::string solverAddress, std::string postURI, 
00188                 std::string fileName,  std::string theFile, std::string boundaryName){
00189         ostringstream request, body;
00190         std::cout << "Solver address = " <<  solverAddress << std::endl;
00191         std::cout << "postURI = " <<  postURI << std::endl;
00192         request << "POST "  <<  postURI << " HTTP/1.0" <<  "\r\n";
00193         request << "Host: " ;
00194         request << solverAddress << "\r\n";
00195         request << "Content-Type: multipart/form-data; boundary=" ;
00196         request << boundaryName << "\r\n";
00197         request << "Connection: keep-alive" << "\r\n";
00198         //request << "Referer: /servlets-examples/fileupload.html" << endl;
00199         body << "--" ;
00200         body << boundaryName  ;
00201         body << "\r\n";
00202         body << "Content-Disposition: form-data; name=\"";
00203         body << "myfile";
00204         body << "\"";
00205         body << ";";
00206         body << " filename=\"";
00207         body << fileName;
00208         body << "\"" << "\r\n";
00209         
00210         body << "Content-Type: text/plain" ;
00211         body << "\r\n" ;
00212         body << "\r\n";
00213         body << theFile ;
00214         body << "\r\n";
00215         body << "--" ;
00216         body << boundaryName;
00217         body << "--" ;
00218         body << "\r\n" ;
00219         
00220         
00221         request << "Content-Length: " << body.str().length();
00222         request << "\r\n";
00223         request << "\r\n";
00224         request << body.str();
00225         return request.str();
00226         //return theFile;
00227 }// end createFromDataUpload
00228 
00229 
00230 string WSUtil::SOAPify(string inputstring){
00231         /* replace all occurances of "<" with "&lt;"  all 
00232         occurances of ">" with "&gt;" and all occurances of " or ' with &quote;
00233         */
00234         #ifdef DEBUG
00235         cout << "prepare the XML for a SOAP envelope" << endl;
00236         #endif
00237         ostringstream body;
00238         int i = 0;
00239         int loopsize = inputstring.length();
00240         while (i < loopsize){
00241                 switch( inputstring[i]){
00242                         case '<':
00243                                 body << "&lt;";
00244                                 break;
00245                         case '>':
00246                                 body << "&gt;";
00247                                 break;
00248                         case '\"':
00249                                 body << "&quot;";
00250                                 break;
00251                         case '\'':
00252                                 body << "&quot;";
00253                                 break;
00254                         default:
00255                         body << inputstring[i];
00256                 }
00257                 i++;
00258         }
00259         return body.str();
00260 }
00261 
00262 string WSUtil::deSOAPify(string inputstring){
00263         /* replace all occurances of "&lt;" with "<"  all 
00264         occurances of "&gt;" with ">" and all occurances of "&quote;" with "
00265         */
00266         ostringstream body;
00267         int i = 0;
00268         int loopsize = inputstring.length();
00269         while (i < loopsize){
00270                 //i = inputstring.find('&', i);
00271                 //if (i == string::npos)  return ostringstream.str();
00272                 if(inputstring[i] == '&'){
00273                         switch (inputstring[i+1]) {
00274                         case 'l':
00275                                 if (inputstring[i + 2] == 't' && inputstring[i + 3] == ';') {
00276                                         body << "<";
00277                                 }
00278                                 i = i + 4;
00279                                 break;
00280                         case 'g':
00281                                 if (inputstring[i + 2] == 't' && inputstring[i + 3] == ';') {
00282                                         body << ">";
00283                                 }
00284                                 i = i + 4;
00285                                 break;
00286                         case 'q':
00287                                 if (inputstring[i + 2] == 'u' && inputstring[i + 3] == 'o' && inputstring[i + 4] == 't' && inputstring[i + 5] == ';') {
00288                                         body << "\"";
00289                                 }
00290                                 i = i + 6;
00291                                 break;
00292                         default:
00293                                 body << inputstring[i];
00294                                 i++;
00295                                 break;
00296                         } //end switch
00297                 } // end if'&"
00298                 else{
00299                         body << inputstring[i];
00300                         i++;
00301                 }
00302         }// end while
00303         return body.str();
00304 }
00305 
00306 unsigned long ResolveName(char *name){
00307         struct hostent *host;
00308         try{
00309                 if ((host = gethostbyname(name)) == NULL){
00310                         string s1 = &name[0];
00311                         string errormsg = "cannot resolve the domain name:  " + s1;
00312                         throw ErrorClass( errormsg);
00313                 }
00314                 return *((unsigned long *) host->h_addr_list[0]);
00315         }
00316         catch(const ErrorClass& eclass){
00317                 throw eclass;
00318         }
00319 }
00320 
00321 //void DieWithError(char *errorMessage)
00322 //{
00323 //      #ifdef DEBUG
00324 //    cout << errorMessage << endl;
00325 //      #endif
00326 //    exit(1);
00327 //}
00328 
00329 string WSUtil::getOSxL(string soapstring, string serviceMethod){
00330         /*  get the string that starts with <osxl
00331          * inside the soap envelope
00332          */
00333         string start = "";
00334         string end = "";
00335         string result = "";
00336         start = "<" + serviceMethod + "Return";
00337         end = "</"+serviceMethod + "Return";
00338         // strip off the return header information 
00339         // find start of XML information
00340         string::size_type startxml = soapstring.find(start , 1);
00341         if (startxml == string::npos){
00342                 return result;  
00343         }    
00344         else{
00345                 startxml = soapstring.find(">", startxml + 1);
00346                 if(startxml == string::npos) return result;
00347                 // find the end of the string
00348                 string::size_type endxml = soapstring.find(end , startxml);
00349                 if(endxml == string::npos){
00350                         return result;
00351                 }
00352                 else{
00353                         // get the > that ends </osxl
00354                         //endxml = soapstring.find(">", endxml - 1);
00355                         // now get the substring
00356                         startxml++;
00357                         result = soapstring.substr(startxml, endxml - startxml);
00358                         return result;
00359                 }
00360         }
00361         return result;
00362 }

Generated on Mon Aug 3 03:02:22 2009 by  doxygen 1.4.7