(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.8 and 1.24.2.2

version 1.8, 2002/02/26 15:00:42 version 1.24.2.2, 2002/10/30 21:20:03
Line 1 
Line 1 
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001 BMC Software, Hewlett-Packard Company, IBM,  // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
 // The Open Group, Tivoli Systems // The Open Group, Tivoli Systems
 // //
 // Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
Line 30 
Line 30 
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
 #include "Config.h" #include "Config.h"
   #include "Constants.h"
 #include <iostream> #include <iostream>
 #include "Socket.h" #include "Socket.h"
  
 #ifdef PEGASUS_PLATFORM_WIN32_IX86_MSVC #ifdef PEGASUS_PLATFORM_WIN32_IX86_MSVC
 # include <winsock.h>  #include <windows.h>
 #else #else
 # include <cctype> # include <cctype>
 # include <unistd.h> # include <unistd.h>
Line 45 
Line 46 
 # include <netinet/in.h> # include <netinet/in.h>
 # include <arpa/inet.h> # include <arpa/inet.h>
 # include <sys/socket.h> # include <sys/socket.h>
   # ifdef PEGASUS_LOCAL_DOMAIN_SOCKET
   #  include <sys/un.h>
   # endif
 #endif #endif
  
 #include "Socket.h" #include "Socket.h"
 #include "TLS.h" #include "TLS.h"
 #include "HTTPAcceptor.h" #include "HTTPAcceptor.h"
 #include "HTTPConnection.h" #include "HTTPConnection.h"
   #include "Tracer.h"
  
 PEGASUS_USING_STD; PEGASUS_USING_STD;
  
Line 64 
Line 69 
  
 struct HTTPAcceptorRep struct HTTPAcceptorRep
 { {
   #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET
         struct sockaddr_un address;
   #else
       struct sockaddr_in address;       struct sockaddr_in address;
   #endif
         Mutex _connection_mut;
   
       Sint32 socket;       Sint32 socket;
       Array<HTTPConnection*> connections;       Array<HTTPConnection*> connections;
 }; };
Line 76 
Line 87 
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
  
 HTTPAcceptor::HTTPAcceptor(Monitor* monitor, MessageQueue* outputMessageQueue) HTTPAcceptor::HTTPAcceptor(Monitor* monitor, MessageQueue* outputMessageQueue)
    : Base("HTTPAcceptor", MessageQueue::getNextQueueId()),     : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),
      _monitor(monitor), _outputMessageQueue(outputMessageQueue),      _monitor(monitor), _outputMessageQueue(outputMessageQueue),
      _rep(0), _sslcontext(NULL)       _rep(0), _sslcontext(NULL), _entry_index(-1)
 { {
  
      _inet_address[0] = 0x00;
    Socket::initializeInterface();    Socket::initializeInterface();
 } }
  
 HTTPAcceptor::HTTPAcceptor(Monitor* monitor, MessageQueue* outputMessageQueue, HTTPAcceptor::HTTPAcceptor(Monitor* monitor, MessageQueue* outputMessageQueue,
                            SSLContext * sslcontext)                            SSLContext * sslcontext)
    :       Base("HTTPAcceptor", MessageQueue::getNextQueueId()),     :       Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),
            _monitor(monitor), _outputMessageQueue(outputMessageQueue), _rep(0),             _monitor(monitor), _outputMessageQueue(outputMessageQueue),
            _sslcontext(sslcontext)             _rep(0),
              _sslcontext(sslcontext),
              _entry_index(-1)
   {
      _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();
 } }
  
Line 130 
Line 159 
          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 140 
Line 171 
                _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:
       // Attn: need unexpected message error!        // ATTN: need unexpected message error!
       break;       break;
    };    };
  
Line 165 
Line 199 
  
 } }
  
 const char* HTTPAcceptor::getQueueName() const  
 {  
    return "HTTPAcceptor";  
 }  
   
 void HTTPAcceptor::bind(Uint32 portNumber) void HTTPAcceptor::bind(Uint32 portNumber)
 { {
    if (_rep)    if (_rep)
       throw BindFailed("HTTPAcceptor already bound");        throw BindFailedException("HTTPAcceptor already bound");
  
    _rep = new HTTPAcceptorRep;    _rep = new HTTPAcceptorRep;
  
Line 187 
Line 216 
  
 /** /**
    _bind - creates a new server socket and bind socket to the port address.    _bind - creates a new server socket and bind socket to the port address.
      If PEGASUS_LOCAL_DOMAIN_SOCKET is defined, the port number is ignored and
      a domain socket is bound.
 */ */
 void HTTPAcceptor::_bind() void HTTPAcceptor::_bind()
 { {
Line 195 
Line 226 
  
    memset(&_rep->address, 0, sizeof(_rep->address));    memset(&_rep->address, 0, sizeof(_rep->address));
  
 #ifdef PEGASUS_ACCEPT_ONLY_LOCAL_CONNECTIONS  #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET
    _rep->address.sin_addr.s_addr = INADDR_LOOPBACK;     _rep->address.sun_family = AF_UNIX;
      strcpy(_rep->address.sun_path, "/var/opt/wbem/cimxml.socket");
      ::unlink(_rep->address.sun_path);
 #else #else
      if(_inet_address[0] != 0x00)
      {
         _rep->address.sin_addr.s_addr = inet_addr(_inet_address);
         cout << "binding to " << _inet_address << endl;
   
      }
      else
      {
    _rep->address.sin_addr.s_addr = INADDR_ANY;    _rep->address.sin_addr.s_addr = INADDR_ANY;
 #endif     }
  
    _rep->address.sin_family = AF_INET;    _rep->address.sin_family = AF_INET;
    _rep->address.sin_port = htons(_portNumber);    _rep->address.sin_port = htons(_portNumber);
   #endif
  
    // Create socket:    // Create socket:
  
   #ifdef PEGASUS_LOCAL_DOMAIN_SOCKET
      _rep->socket = socket(AF_UNIX, SOCK_STREAM, 0);
   #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)
    {    {
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       throw BindFailed("Failed to create socket");        throw BindFailedException("Failed to create socket");
    }    }
  
    //    //
Line 227 
Line 273 
    {    {
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       throw BindFailed("Failed to set socket option");        throw BindFailedException("Failed to set socket option");
    }    }
  
    // Bind socket to port:    // Bind socket to port:
  
    if (::bind(_rep->socket,    if (::bind(_rep->socket,
               (struct sockaddr*)(void*)&_rep->address,                reinterpret_cast<struct sockaddr*>(&_rep->address),
               sizeof(_rep->address)) < 0)               sizeof(_rep->address)) < 0)
    {    {
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       throw BindFailed("Failed to bind socket to port");        throw BindFailedException("Failed to bind socket");
    }    }
  
    // Set up listening on the given port:     // Set up listening on the given socket:
  
    int const MAX_CONNECTION_QUEUE_LENGTH = 5;    int const MAX_CONNECTION_QUEUE_LENGTH = 5;
  
Line 251 
Line 297 
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       throw BindFailed("Failed to bind socket to port");        throw BindFailedException("Failed to bind socket");
    }    }
  
    // Register to receive SocketMessages on this socket:    // Register to receive SocketMessages on this socket:
  
    if (!_monitor->solicitSocketMessages(     if ( -1 == ( _entry_index = _monitor->solicitSocketMessages(
           _rep->socket,           _rep->socket,
           SocketMessage::READ | SocketMessage::EXCEPTION,           SocketMessage::READ | SocketMessage::EXCEPTION,
           getQueueId()))            getQueueId(),
             Monitor::ACCEPTOR)))
    {    {
       Socket::close(_rep->socket);       Socket::close(_rep->socket);
       delete _rep;       delete _rep;
       _rep = 0;       _rep = 0;
       throw BindFailed("Failed to solicit socket messaeges");        throw BindFailedException("Failed to solicit socket messaeges");
    }    }
 } }
  
Line 300 
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];
       return(connection->getRequestCount());        count = connection->getRequestCount();
    }  
    else  
    {  
       return(0);  
    }    }
      _rep->_connection_mut.unlock();
      return count;
   
 } }
  
 void HTTPAcceptor::unbind() void HTTPAcceptor::unbind()
Line 325 
Line 374 
 { {
    // 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 336 
Line 386 
  
       // Destroy the connection (causing it to close):       // Destroy the connection (causing it to close):
  
         while (connection->refcount.value()) { }
       delete connection;       delete connection;
    }    }
  
    _rep->connections.clear();    _rep->connections.clear();
      _rep->_connection_mut.unlock();
 } }
  
 void HTTPAcceptor::_acceptConnection() void HTTPAcceptor::_acceptConnection()
Line 355 
Line 407 
  
    sockaddr_in address;    sockaddr_in address;
  
   
 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX)
    size_t n = sizeof(address);    size_t n = sizeof(address);
 #else #else
    int n = sizeof(address);    int n = sizeof(address);
 #endif #endif
  
 #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU)  
   #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
    Sint32 socket = accept(    Sint32 socket = accept(
       _rep->socket, (struct sockaddr*)&address, (socklen_t *)&n);       _rep->socket, (struct sockaddr*)&address, (socklen_t *)&n);
 #else #else
    Sint32 socket = accept(_rep->socket, (struct sockaddr*)&address, &n);     Sint32 socket = accept(_rep->socket, reinterpret_cast<struct sockaddr*>(&address), &n);
 #endif #endif
  
   
   
    if (socket < 0)    if (socket < 0)
    {    {
       if (getenv("PEGASUS_TRACE"))         PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,
          cerr <<"HTTPAcceptor: accept() failed" << endl;                          "HTTPAcceptor: accept() failed");
   
       return;       return;
    }    }
   #if defined(PEGASUS_PLATFORM_LINUX_IX86_GNU) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
      if( _inet_address[0] != 0x00)
      {
         if( 1023 < htons(address.sin_port) )
         {
            shutdown(socket, 2);
            Socket::close(socket);
            return;
         }
      }
  
   #endif
    // Create a new conection and add it to the connection list:    // Create a new conection and add it to the connection list:
  
    MP_Socket * mp_socket = new MP_Socket(socket, _sslcontext);    MP_Socket * mp_socket = new MP_Socket(socket, _sslcontext);
    if (mp_socket->accept() < 0) {     if (mp_socket->accept() < 0)
       if (getenv("PEGASUS_TRACE"))     {
          cerr <<"HTTPAcceptor: SSL_accept() failed" << endl;         PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,
                           "HTTPAcceptor: SSL_accept() failed");
       return;       return;
    }    }
  
    HTTPConnection* connection = new HTTPConnection(    HTTPConnection* connection = new HTTPConnection(
       _monitor, mp_socket, this, static_cast<MessageQueueService *>(_outputMessageQueue));        _monitor, mp_socket, this, static_cast<MessageQueue *>(_outputMessageQueue));
  
    // Solicit events on this new connection's socket:    // Solicit events on this new connection's socket:
      int index;
  
    if (!_monitor->solicitSocketMessages(     if (! (index = _monitor->solicitSocketMessages(
           socket,           socket,
           SocketMessage::READ | SocketMessage::EXCEPTION,           SocketMessage::READ | SocketMessage::EXCEPTION,
           connection->getQueueId()))            connection->getQueueId(), Monitor::CONNECTION)) )
    {    {
       delete connection;       delete connection;
       Socket::close(socket);       Socket::close(socket);
    }    }
  
    // Save the socket for cleanup later:    // Save the socket for cleanup later:
      connection->_entry_index = index;
      _rep->_connection_mut.lock(pegasus_thread_self());
    _rep->connections.append(connection);    _rep->connections.append(connection);
      _rep->_connection_mut.unlock();
      PEGASUS_STD(cout) << "Creating new HTTP Connection; Current Connection Table Size: " <<
      _rep->connections.size() << " entries" << endl;
   
 } }
  
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.8  
changed lines
  Added in v.1.24.2.2

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2