/Users/kmartin/Documents/files/code/cpp/OScpp/COIN-OS/OS/src/OSAgent/OSWSUtil.cpp

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

Generated on Sat Mar 29 22:38:01 2008 by  doxygen 1.5.3