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