(file) Return to HTTPAcceptor.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/HTTPAcceptor.cpp between version 1.24.2.3 and 1.25

version 1.24.2.3, 2003/02/10 22:07:56 version 1.25, 2003/03/11 21:26:54
Line 67 
Line 67 
 // //
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
  
 struct HTTPAcceptorRep  class HTTPAcceptorRep
   {
   public:
       HTTPAcceptorRep(Boolean local)
       {
           if (local)
 { {
 #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET
       struct sockaddr_un address;              address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);
               address_size = sizeof(struct sockaddr_un);
   #else
               PEGASUS_ASSERT(false);
   #endif
           }
           else
           {
               address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);
               address_size = sizeof(struct sockaddr_in);
           }
       }
   
       struct sockaddr* address;
   
   #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
      size_t address_size;
   #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
      socklen_t address_size;
 #else #else
       struct sockaddr_in address;     int address_size;
 #endif #endif
       Mutex _connection_mut;  
  
       Sint32 socket;       Sint32 socket;
       Array<HTTPConnection*> connections;       Array<HTTPConnection*> connections;
Line 86 
Line 108 
 // //
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
  
 HTTPAcceptor::HTTPAcceptor(Monitor* monitor, MessageQueue* outputMessageQueue)  HTTPAcceptor::HTTPAcceptor(Monitor* monitor,
    : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),                             MessageQueue* outputMessageQueue,
      _monitor(monitor), _outputMessageQueue(outputMessageQueue),                             Boolean localConnection,
      _rep(0), _sslcontext(NULL), _entry_index(-1)                             Uint32 portNumber,
 {  
   
    _inet_address[0] = 0x00;  
    Socket::initializeInterface();  
 }  
   
 HTTPAcceptor::HTTPAcceptor(Monitor* monitor, MessageQueue* outputMessageQueue,  
                            SSLContext * sslcontext)                            SSLContext * sslcontext)
    :       Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),     : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),  // ATTN: Need unique names?
            _monitor(monitor), _outputMessageQueue(outputMessageQueue),       _monitor(monitor),
        _outputMessageQueue(outputMessageQueue),
            _rep(0),            _rep(0),
            _sslcontext(sslcontext),       _entry_index(-1),
            _entry_index(-1)       _localConnection(localConnection),
        _portNumber(portNumber),
        _sslcontext(sslcontext)
 { {
    _inet_address[0] = 0x00;  
    Socket::initializeInterface();  
 }  
   
 HTTPAcceptor::HTTPAcceptor(Monitor* monitor, MessageQueue* outputMessageQueue,  
                            SSLContext * sslcontext,  
                            char *inet_address)  
    :       Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),  
            _monitor(monitor), _outputMessageQueue(outputMessageQueue),  
            _rep(0),  
            _sslcontext(sslcontext),  
            _entry_index(-1)  
 {  
    strncpy(_inet_address, inet_address, 16);  
    _inet_address[16] = 0x00;  
    Socket::initializeInterface();    Socket::initializeInterface();
 } }
  
 HTTPAcceptor::~HTTPAcceptor() HTTPAcceptor::~HTTPAcceptor()
 { {
    unbind();    unbind();
      // ATTN: Is this correct in a multi-HTTPAcceptor server?
    Socket::uninitializeInterface();    Socket::uninitializeInterface();
 } }
  
Line 159 
Line 163 
          CloseConnectionMessage* closeConnectionMessage          CloseConnectionMessage* closeConnectionMessage
             = (CloseConnectionMessage*)message;             = (CloseConnectionMessage*)message;
  
          _rep->_connection_mut.lock(pegasus_thread_self());  
   
          for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)          for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
          {          {
             HTTPConnection* connection = _rep->connections[i];             HTTPConnection* connection = _rep->connections[i];
Line 171 
Line 173 
                _monitor->unsolicitSocketMessages(socket);                _monitor->unsolicitSocketMessages(socket);
                _rep->connections.remove(i);                _rep->connections.remove(i);
                delete connection;                delete connection;
                PEGASUS_STD(cout) << "Closing HTTP Connection; Current Connection Table Size: " <<  
                _rep->connections.size() << PEGASUS_STD(endl);  
                break;                break;
             }             }
          }          }
          _rep->_connection_mut.unlock();  
       }       }
  
       default:       default:
Line 199 
Line 198 
  
 } }
  
 void HTTPAcceptor::bind(Uint32 portNumber)  void HTTPAcceptor::bind()
 { {
    if (_rep)    if (_rep)
       throw BindFailedException("HTTPAcceptor already bound");       throw BindFailedException("HTTPAcceptor already bound");
  
    _rep = new HTTPAcceptorRep;     _rep = new HTTPAcceptorRep(_localConnection);
   
    _portNumber = portNumber;  
  
    // bind address    // bind address
    _bind();    _bind();
Line 224 
Line 221 
  
    // Create address:    // Create address:
  
    memset(&_rep->address, 0, sizeof(_rep->address));     memset(_rep->address, 0, sizeof(*_rep->address));
  
      if (_localConnection)
      {
 #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET
    _rep->address.sun_family = AF_UNIX;         reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family =
    strcpy(_rep->address.sun_path, "/var/opt/wbem/cimxml.socket");             AF_UNIX;
    ::unlink(_rep->address.sun_path);         strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path,
                 PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);
          ::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 #else #else
    if(_inet_address[0] != 0x00)         PEGASUS_ASSERT(false);
    {  #endif
       _rep->address.sin_addr.s_addr = inet_addr(_inet_address);  
       cout << "binding to " << _inet_address << endl;  
    }    }
    else    else
    {    {
       _rep->address.sin_addr.s_addr = INADDR_ANY;         reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_addr.s_addr =
              INADDR_ANY;
          reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_family =
              AF_INET;
          reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_port =
              htons(_portNumber);
    }    }
  
    _rep->address.sin_family = AF_INET;  
    _rep->address.sin_port = htons(_portNumber);  
 #endif  
   
    // Create socket:    // Create socket:
  
 #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET     if (_localConnection)
      {
    _rep->socket = socket(AF_UNIX, SOCK_STREAM, 0);    _rep->socket = socket(AF_UNIX, SOCK_STREAM, 0);
 #else     }
      else
      {
    _rep->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);    _rep->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 #endif     }
  
    if (_rep->socket < 0)    if (_rep->socket < 0)
    {    {
Line 260 
Line 263 
       throw BindFailedException("Failed to create socket");       throw BindFailedException("Failed to create socket");
    }    }
  
 #ifndef PEGASUS_PLATFORM_WIN32_IX86_MSVC  
    int sock_flags;  
  if( (sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0)  
    {  
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,  
                         "HTTPAcceptor: fcntl(F_GETFD) failed");  
    }  
    else  
    {  
       sock_flags |= FD_CLOEXEC;  
       if (fcntl(_rep->socket, F_SETFD, sock_flags) < 0)  
       {  
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,  
                         "HTTPAcceptor: fcntl(F_SETFD) failed");  
       }  
    }  
 #endif  
    //    //
    // Set the socket option SO_REUSEADDR to reuse the socket address so    // Set the socket option SO_REUSEADDR to reuse the socket address so
    // that we can rebind to a new socket using the same address when we    // that we can rebind to a new socket using the same address when we
Line 294 
Line 280 
  
    // Bind socket to port:    // Bind socket to port:
  
    if (::bind(_rep->socket,     if (::bind(_rep->socket, _rep->address, _rep->address_size) < 0)
               reinterpret_cast<struct sockaddr*>(&_rep->address),  
               sizeof(_rep->address)) < 0)  
    {    {
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
       delete _rep;       delete _rep;
Line 363 
Line 347 
 */ */
 Uint32 HTTPAcceptor::getOutstandingRequestCount() Uint32 HTTPAcceptor::getOutstandingRequestCount()
 { {
    Uint32 count = 0;  
   
    _rep->_connection_mut.lock(pegasus_thread_self());  
    if (_rep->connections.size() > 0)    if (_rep->connections.size() > 0)
    {    {
       HTTPConnection* connection = _rep->connections[0];       HTTPConnection* connection = _rep->connections[0];
       count = connection->getRequestCount();        return(connection->getRequestCount());
      }
      else
      {
         return(0);
    }    }
    _rep->_connection_mut.unlock();  
    return count;  
   
 } }
  
 void HTTPAcceptor::unbind() void HTTPAcceptor::unbind()
Line 381 
Line 363 
    if (_rep)    if (_rep)
    {    {
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
   
         if (_localConnection)
         {
   #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET
            ::unlink(
                reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
   #else
            PEGASUS_ASSERT(false);
   #endif
         }
   
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
    }    }
Line 390 
Line 383 
 { {
    // For each connection created by this object:    // For each connection created by this object:
  
    _rep->_connection_mut.lock(pegasus_thread_self());  
    for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)    for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
    {    {
       HTTPConnection* connection = _rep->connections[i];       HTTPConnection* connection = _rep->connections[i];
Line 407 
Line 399 
    }    }
  
    _rep->connections.clear();    _rep->connections.clear();
    _rep->_connection_mut.unlock();  
 } }
  
 void HTTPAcceptor::_acceptConnection() void HTTPAcceptor::_acceptConnection()
Line 421 
Line 412 
  
    // Accept the connection (populate the address):    // Accept the connection (populate the address):
  
    sockaddr_in address;     struct sockaddr* accept_address;
   #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
      size_t address_size;
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX)  #elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
    size_t n = sizeof(address);     socklen_t address_size;
 #else #else
    int n = sizeof(address);     int address_size;
 #endif #endif
  
      if (_localConnection)
 #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)     {
    Sint32 socket = accept(  #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET
       _rep->socket, (struct sockaddr*)&address, (socklen_t *)&n);         accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);
          address_size = sizeof(struct sockaddr_un);
 #else #else
    Sint32 socket = accept(_rep->socket, reinterpret_cast<struct sockaddr*>(&address), &n);         PEGASUS_ASSERT(false);
 #endif #endif
   
   
   
    if (socket < 0)  
    {  
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,  
                         "HTTPAcceptor: accept() failed");  
       return;  
    }    }
 #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)     else
    if( _inet_address[0] != 0x00)  
    {  
       if( 1023 < htons(address.sin_port) )  
       {       {
          shutdown(socket, 2);         accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);
          Socket::close(socket);         address_size = sizeof(struct sockaddr_in);
          return;  
       }       }
    }  
   
 #endif  
  
      Sint32 socket = accept(_rep->socket, accept_address, &address_size);
  
      delete accept_address;
  
 #ifndef PEGASUS_PLATFORM_WIN32_IX86_MSVC     if (socket < 0)
    int sock_flags;  
  if( (sock_flags = fcntl(socket, F_GETFD, 0)) < 0)  
    {  
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,  
                         "HTTPAcceptor: fcntl(F_GETFD) failed");  
    }  
    else  
    {  
       sock_flags |= FD_CLOEXEC;  
       if (fcntl(socket, F_SETFD, sock_flags) < 0)  
       {       {
        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,        PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,
                         "HTTPAcceptor: fcntl(F_SETFD) failed");                          "HTTPAcceptor: accept() failed");
       }        return;
    }    }
 #endif  
   
  
    // Create a new conection and add it to the connection list:    // Create a new conection and add it to the connection list:
  
Line 496 
Line 463 
    // Solicit events on this new connection's socket:    // Solicit events on this new connection's socket:
    int index;    int index;
  
    if (! (index = _monitor->solicitSocketMessages(     if (-1 ==  (index = _monitor->solicitSocketMessages(
           socket,           socket,
           SocketMessage::READ | SocketMessage::EXCEPTION,           SocketMessage::READ | SocketMessage::EXCEPTION,
           connection->getQueueId(), Monitor::CONNECTION)) )           connection->getQueueId(), Monitor::CONNECTION)) )
Line 507 
Line 474 
  
    // Save the socket for cleanup later:    // Save the socket for cleanup later:
    connection->_entry_index = index;    connection->_entry_index = index;
    _rep->_connection_mut.lock(pegasus_thread_self());  
    _rep->connections.append(connection);  
    _rep->_connection_mut.unlock();  
    PEGASUS_STD(cout) << "Creating new HTTP Connection; Current Connection Table Size: " <<  
    _rep->connections.size() << " entries" << endl;  
  
      _rep->connections.append(connection);
 } }
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.24.2.3  
changed lines
  Added in v.1.25

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2