/home/coin/SVN-release/OS-1.0.0/OS/src/OSAgent/WSUtil.cpp

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

Generated on Thu May 15 22:15:04 2008 by  doxygen 1.4.7