From 8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 Mon Sep 17 00:00:00 2001 From: Constantin Jucovschi Date: Fri, 24 Apr 2009 07:20:22 -0400 Subject: Initial commit --- rasmgr/rasmgr_comm.cc | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 rasmgr/rasmgr_comm.cc (limited to 'rasmgr/rasmgr_comm.cc') diff --git a/rasmgr/rasmgr_comm.cc b/rasmgr/rasmgr_comm.cc new file mode 100644 index 0000000..02fffcf --- /dev/null +++ b/rasmgr/rasmgr_comm.cc @@ -0,0 +1,294 @@ +/* +* This file is part of rasdaman community. +* +* Rasdaman community is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Rasdaman community is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with rasdaman community. If not, see . +* +* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / +rasdaman GmbH. +* +* For more information please see +* or contact Peter Baumann via . +/ +/** + * SOURCE: rasmgr_comm.cc + * + * MODULE: rasmgr + * CLASS: HTTPComm + * + * PURPOSE: + * Performs reliable, but blocking HTTP communication. used by the slave rasmgr + * + * COMMENTS: + * Will be removed, the plan is to have only non-blocking communication + * +*/ + +#include "rasmgr_comm.hh" + +#ifdef X86 + #define r_Socklen_t socklen_t +#endif + +#ifdef AIX + #define r_Socklen_t socklen_t +#endif + +#ifdef SOLARIS + #define r_Socklen_t socklen_t +#endif + +#ifdef DECALPHA + #define r_Socklen_t int +#endif + +#include "debug.hh" + + +HTTPComm::HTTPComm() + { //parentPID=getpid(); + listen_socket=-1; + exitRequest=false;; + } +HTTPComm::~HTTPComm() + { + ENTER("HTTPComm::~HTTPComm: enter." ); + closeListenSocket(); + LEAVE("HTTPComm::~HTTPComm: leave." ); + } + +void HTTPComm::closeListenSocket() + { + ENTER("HTTPComm::closeListenSocket: enter." ); + + if(listen_socket>=0) close(listen_socket); + + LEAVE("HTTPComm::closeListenSocket: leave." ); + } + +int HTTPComm::sendAnswer(int socket,int len) + { + int result = 0; + + ENTER("HTTPComm::sendAnswer: enter." << std::endl ); + + int write_count=writeWholeMessage(socket,outBuffer,len); + + // adapted logic to single point of return -- PB 26-may-2003 + if(write_count<0) + { TALK( "HTTPComm::sendAnswer: Error writing answer" ); + result = -1; + } + else + result = 0; + + LEAVE("HTTPComm::sendAnswer: leave. result=" << result ); + return result; + } + +int HTTPComm::getMessage() + { + ENTER("HTTPComm::getMessage: enter." << std::endl ); + + int socket=realGetMessage(); + + if(socket>0) + { + header=inBuffer; + body=strstr(inBuffer,"\r\n\r\n"); + if(body!=NULL) + { + *body=0; + body+=4; + } + else + { close(socket); + socket = -1; + } + } + + LEAVE("HTTPComm::getMessage: leave. socket=" << socket ); + return socket; + } + + +int HTTPComm::realGetMessage() + { + struct sockaddr_in clientname; + r_Socklen_t size=sizeof(clientname); + + ENTER("HTTPComm::getRealMessage: enter." ); + + int socket=accept(listen_socket,(struct sockaddr*)&clientname,&size); + if(socket<0) + { TALK( "HTTPComm::realGetMessage: Error accepting connection."); + socket = -1; // normalize error feedback + } + + if (socket >= 0) // accept() worked fine, so wa can continue + { + int read_count=readWholeMessage(socket,inBuffer,MAXMSG); + + if(read_count<0) + { TALK( "HTTPComm::realGetMessage: Error reading message."<p_proto); + if(sock<0) + { + TALK("HTTPComm::makeSocket: socket failed. errno=" << errno ); + exitbyerror("make socket"); + } + + name.sin_family=AF_INET; + name.sin_port=htons(port); + name.sin_addr.s_addr=htonl(INADDR_ANY); + +#ifdef SO_REUSEADDR + int val = 1; + int len = sizeof( val ); + if(setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char*)&val, len )) + { + TALK( "HTTPComm::makeSocket: Can't set address reusable: "<< strerror(errno) ); + } +#endif + + int sockResult = bind(sock,(sockaddr*)&name,sizeof(name)); + TALK( "HTTPComm::makeSocket: bind() with socket=" << sock << ", name.sin_port="<< name.sin_port << " returned " << sockResult ); + if(sockResult < 0) + { + TALK( "HTTPComm::makeSocket: bind failed: "<< strerror(errno) ); + exitbyerror("bind"); + // This is OK to exit, program just starts and we can't have an address + } + + ENTER("HTTPComm::makeSocket: leave. socket=" << sock << std::endl ); + return sock; + } + +void HTTPComm::shouldExit() + { + exitRequest=true; + } + +bool HTTPComm::isMessage(const char *messageStart) + { + ENTER("HTTPComm::isMessage: enter. messageStarte=" << messageStart ); + + bool rasp= (strncasecmp(header,messageStart,strlen(messageStart))==0) ? true:false; + if(rasp) + { + TALK("HTTPComm::isMessage: (b) Message=" << messageStart ); + } + + LEAVE("HTTPComm::isMessage: leave. result=" << rasp ); + return rasp; + } + +// +int readWholeMessage(int socket,char *destBuffer,int buffSize) + { + ENTER("HTTPComm::readWholeMessage: enter. socket=" << socket << ", destBuffer=" << destBuffer << ", buffSize=" << buffSize ); + + // we read what is comming in until we encounter a '\0' + // this is our end-sign. + int totalLength=0; + int redNow; + while(1) + { + redNow = read(socket,destBuffer+totalLength,buffSize-totalLength); + if(redNow == -1) + { if(errno == EINTR) continue; // read was interrupted by signal + + TALK("HTTPComm::readWholeMessage: read error. errno=" << errno ); + return -1; // another error + } + totalLength+=redNow; + + if(destBuffer[totalLength-1]==0) break; // THE END + } + + LEAVE("HTTPComm::readWholeMessage: leave. totalLength=" << totalLength ); + return totalLength; + } + +int writeWholeMessage(int socket,char *destBuffer,int buffSize) + { + ENTER("HTTPComm::writeWholeMessage: enter. socket=" << socket << ", destBuffer=" << destBuffer << ", buffSize=" << buffSize ); + + // we write the whole message, including the ending '\0', which is already in + // the buffSize provided by the caller + int totalLength=0; + int writeNow; + while(1) + { + writeNow = write(socket,destBuffer+totalLength,buffSize-totalLength); + if(writeNow == -1) + { if(errno == EINTR) continue; // read was interrupted by signal + + TALK("HTTPComm::writeWholeMessage: read error. errno=" << errno ); + return -1; // another error + } + totalLength+=writeNow; + + if( totalLength==buffSize ) break; // THE END + } + + LEAVE("HTTPComm::writeWholeMessage: leave. totalLength=" << totalLength ); + return totalLength; + } + -- cgit