00001
00018
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
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
00072 if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) throw ErrorClass( "failure creating socket");
00073
00074 memset(&httpServAddr, 0, sizeof(httpServAddr));
00075 httpServAddr.sin_family = AF_INET;
00076 httpServAddr.sin_addr.s_addr = ResolveName( servIP);
00077 httpServAddr.sin_port = htons(httpServPort);
00078
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
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
00117 }
00118 }
00119 #endif
00120
00121 ret_message << httpBuffer;
00122
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
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
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 }
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
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
00227 }
00228
00229
00230 string WSUtil::SOAPify(string inputstring){
00231
00232
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 << "<";
00244 break;
00245 case '>':
00246 body << ">";
00247 break;
00248 case '\"':
00249 body << """;
00250 break;
00251 case '\'':
00252 body << """;
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
00264
00265
00266 ostringstream body;
00267 int i = 0;
00268 int loopsize = inputstring.length();
00269 while (i < loopsize){
00270
00271
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 }
00297 }
00298 else{
00299 body << inputstring[i];
00300 i++;
00301 }
00302 }
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
00322
00323
00324
00325
00326
00327
00328
00329 string WSUtil::getOSxL(string soapstring, string serviceMethod){
00330
00331
00332
00333 string start = "";
00334 string end = "";
00335 string result = "";
00336 start = "<" + serviceMethod + "Return";
00337 end = "</"+serviceMethod + "Return";
00338
00339
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
00348 string::size_type endxml = soapstring.find(end , startxml);
00349 if(endxml == string::npos){
00350 return result;
00351 }
00352 else{
00353
00354
00355
00356 startxml++;
00357 result = soapstring.substr(startxml, endxml - startxml);
00358 return result;
00359 }
00360 }
00361 return result;
00362 }