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

   1 karl  1.80 //%2006////////////////////////////////////////////////////////////////////////
   2 mike  1.2  //
   3 karl  1.52 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
   4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   6 karl  1.43 // IBM Corp.; EMC Corporation, The Open Group.
   7 karl  1.52 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   9 karl  1.57 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
  11 karl  1.80 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  12            // EMC Corporation; Symantec Corporation; The Open Group.
  13 mike  1.2  //
  14            // Permission is hereby granted, free of charge, to any person obtaining a copy
  15 kumpf 1.20 // of this software and associated documentation files (the "Software"), to
  16            // deal in the Software without restriction, including without limitation the
  17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  18 mike  1.2  // sell copies of the Software, and to permit persons to whom the Software is
  19            // furnished to do so, subject to the following conditions:
  20 mreddy 1.81.8.6 //
  21 kumpf  1.20     // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  22 mike   1.2      // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  23                 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  24 kumpf  1.20     // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  25                 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  26                 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  27 mike   1.2      // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28                 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29                 //
  30                 //==============================================================================
  31                 //
  32                 // Author: Mike Brasher (mbrasher@bmc.com)
  33                 //
  34                 // Modified By:
  35 david.dillard 1.64     //          Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
  36                        //          Nag Boranna, Hewlett-Packard Company (nagaraja_boranna@hp.com)
  37                        //          Dave Rosckes (rosckes@us.ibm.com)
  38                        //          Denise Eckstein (denise.eckstein@hp.com)
  39                        //          Alagaraja Ramasubramanian (alags_raj@in.ibm.com) for Bug#1090
  40                        //          Amit Arora, IBM (amita@in.ibm.com) for Bug#2541
  41                        //          Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
  42                        //          Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)
  43                        //          Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2065
  44 david.dillard 1.74     //          David Dillard, Symantec Corp. (david_dillard@symantec.com)
  45 j.alex        1.67     //          John Alex, IBM (johnalex@us.ibm.com) for Bug#3312
  46 mike          1.2      //
  47                        //%/////////////////////////////////////////////////////////////////////////////
  48                        
  49                        #include "Config.h"
  50 kumpf         1.15     #include "Constants.h"
  51 mike          1.2      #include <iostream>
  52 w.white       1.81.8.1 #include "Socket.h"
  53 mike          1.2      
  54 david.dillard 1.78     #ifdef PEGASUS_OS_TYPE_WINDOWS
  55 mday          1.12     #include <windows.h>
  56 mike          1.2      #else
  57                        # include <cctype>
  58                        # include <cstdlib>
  59                        # include <errno.h>
  60                        # include <fcntl.h>
  61                        # include <netdb.h>
  62                        # include <netinet/in.h>
  63 mike          1.79     # include <netinet/tcp.h>
  64 mike          1.2      # include <arpa/inet.h>
  65                        # include <sys/socket.h>
  66 h.sterling    1.63     # ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
  67 kumpf         1.26     # include <unistd.h>
  68 kumpf         1.11     #  include <sys/un.h>
  69                        # endif
  70 mike          1.2      #endif
  71                        
  72                        #include "Socket.h"
  73                        #include "TLS.h"
  74                        #include "HTTPAcceptor.h"
  75                        #include "HTTPConnection.h"
  76 kumpf         1.19     #include "Tracer.h"
  77 humberto      1.30     #include <Pegasus/Common/MessageLoader.h> //l10n
  78 mike          1.2      
  79 chuck         1.38     #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
  80                        #include "OS400ConvertChar.h"
  81                        #endif
  82                        
  83 mike          1.79     
  84 mike          1.2      PEGASUS_USING_STD;
  85                        
  86                        PEGASUS_NAMESPACE_BEGIN
  87                        
  88 david.dillard 1.65     
  89 a.arora       1.51     static int MAX_CONNECTION_QUEUE_LENGTH = -1;
  90                        
  91 mike          1.2      ////////////////////////////////////////////////////////////////////////////////
  92                        //
  93                        // HTTPAcceptorRep
  94                        //
  95                        ////////////////////////////////////////////////////////////////////////////////
  96                        
  97 kumpf         1.25     class HTTPAcceptorRep
  98 mike          1.2      {
  99 kumpf         1.25     public:
 100                            HTTPAcceptorRep(Boolean local)
 101                            {
 102                                if (local)
 103                                {
 104 j.alex        1.81.8.2 #ifndef PEGASUS_OS_TYPE_WINDOWS
 105 h.sterling    1.63     #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
 106 j.alex        1.81.8.2 
 107 kumpf         1.25                 address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);
 108                                    address_size = sizeof(struct sockaddr_un);
 109 kumpf         1.11     #else
 110 kumpf         1.25                 PEGASUS_ASSERT(false);
 111 kumpf         1.11     #endif
 112 j.alex        1.81.8.2 
 113                        #endif
 114 david.dillard 1.64             }
 115 kumpf         1.25             else
 116                                {
 117                                    address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);
 118                                    address_size = sizeof(struct sockaddr_in);
 119                                }
 120                            }
 121 konrad.r      1.69         ~HTTPAcceptorRep()
 122                            {
 123 david.dillard 1.73             delete address;
 124 konrad.r      1.69         }
 125 kumpf         1.25         struct sockaddr* address;
 126                        
 127 mike          1.77         PEGASUS_SOCKLEN_T address_size;
 128                            Mutex _connection_mut;
 129 david.dillard 1.64     
 130 mike          1.77         PEGASUS_SOCKET socket;
 131 j.alex        1.81.8.2 #ifdef PEGASUS_OS_TYPE_WINDOWS
 132                            NamedPipeServer* namedPipeServer;
 133                        #endif
 134 mreddy        1.81.8.6     Array<HTTPConnection*> connections;
 135 j.alex        1.81.8.2  /*
 136                        #ifdef PEGASUS_OS_TYPE_WINDOWS
 137                              // This method creates and connects to a named pipe
 138                            void createNamedPipe();
 139                            NamedPipeServer* namedPipeServer;
 140                            void _acceptNamedPipeConnection(NamedPipeMessage* namedPipeMessage);
 141                        #endif
 142                        */
 143 w.white       1.81.8.1 
 144                        
 145 mike          1.2      };
 146                        
 147 mike          1.79     //------------------------------------------------------------------------------
 148                        //
 149                        // _setTCPNoDelay()
 150                        //
 151                        //------------------------------------------------------------------------------
 152                        
 153                        inline void _setTCPNoDelay(PEGASUS_SOCKET socket)
 154                        {
 155                            // This function disables "Nagle's Algorithm" also known as "the TCP delay
 156                            // algorithm", which causes read operations to obtain whatever data is
 157 mreddy        1.81.8.6     // already in the input queue and then wait a little longer to see if
 158                            // more data arrives. This algorithm optimizes the case in which data is
 159                            // sent in only one direction but severely impairs performance of round
 160                            // trip servers. Disabling TCP delay is a standard technique for round
 161 mike          1.79         // trip servers.
 162                        
 163                           int opt = 1;
 164                           setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt));
 165                        }
 166                        
 167 mike          1.2      ////////////////////////////////////////////////////////////////////////////////
 168                        //
 169                        // HTTPAcceptor
 170                        //
 171                        ////////////////////////////////////////////////////////////////////////////////
 172                        
 173 kumpf         1.25     HTTPAcceptor::HTTPAcceptor(Monitor* monitor,
 174                                                   MessageQueue* outputMessageQueue,
 175                                                   Boolean localConnection,
 176                                                   Uint32 portNumber,
 177 kumpf         1.49                                SSLContext * sslcontext,
 178 nag.boranna   1.59                                Boolean exportConnection,
 179                                                   ReadWriteSem* sslContextObjectLock)
 180 kumpf         1.25        : Base(PEGASUS_QUEUENAME_HTTPACCEPTOR),  // ATTN: Need unique names?
 181                             _monitor(monitor),
 182                             _outputMessageQueue(outputMessageQueue),
 183                             _rep(0),
 184                             _entry_index(-1),
 185                             _localConnection(localConnection),
 186                             _portNumber(portNumber),
 187 kumpf         1.49          _sslcontext(sslcontext),
 188 nag.boranna   1.59          _exportConnection(exportConnection),
 189                             _sslContextObjectLock(sslContextObjectLock)
 190 mike          1.2      {
 191 mday          1.7         Socket::initializeInterface();
 192 david.dillard 1.64     
 193 a.arora       1.51        /*
 194                                Platforms interpret the value of MAX_CONNECTION_QUEUE_LENGTH differently.  Some platforms interpret
 195                                the value literally, while others multiply a fudge factor. When the server is under
 196                                stress from multiple clients with multiple requests, toggling this number may prevent clients from
 197                                being dropped.  Instead of hard coding the value, we allow an environment variable to be set which
 198                                specifies a number greater than the maximum concurrent client connections possible.  If this environment
 199                                var is not specified, then MAX_CONNECTION_QUEUE_LENGTH = 15.
 200                           */
 201                        
 202                        //To engage runtime backlog queue length: uncomment the following block AND comment out the line MAX_CONNECTION_QUEUE_LENGTH = 15
 203                        
 204                        /*
 205                           if(MAX_CONNECTION_QUEUE_LENGTH == -1){
 206                        #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
 207                        #pragma convert(37)
 208 h.sterling    1.63         const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");
 209                            EtoA(env);
 210 a.arora       1.51     #pragma convert(0)
 211                        #else
 212 h.sterling    1.63         const char* env = getenv("PEGASUS_MAX_BACKLOG_CONNECTION_QUEUE");
 213 a.arora       1.51     #endif
 214 h.sterling    1.63         if(!env){
 215                                MAX_CONNECTION_QUEUE_LENGTH = 15;
 216 david.dillard 1.64         }else{
 217 h.sterling    1.63             char *end = NULL;
 218                                MAX_CONNECTION_QUEUE_LENGTH = strtol(env, &end, 10);
 219                                if(*end)
 220                                    MAX_CONNECTION_QUEUE_LENGTH = 15;
 221                                cout << " MAX_CONNECTION_QUEUE_LENGTH = " << MAX_CONNECTION_QUEUE_LENGTH << endl;
 222                            }
 223 a.arora       1.51        }
 224                        */
 225                           MAX_CONNECTION_QUEUE_LENGTH = 15;
 226 david.dillard 1.64     
 227 mike          1.2      }
 228                        
 229                        HTTPAcceptor::~HTTPAcceptor()
 230                        {
 231 konrad.r      1.70        destroyConnections();
 232 mday          1.7         unbind();
 233 kumpf         1.25        // ATTN: Is this correct in a multi-HTTPAcceptor server?
 234 mday          1.7         Socket::uninitializeInterface();
 235 mike          1.2      }
 236                        
 237 mday          1.7      void HTTPAcceptor::handleEnqueue(Message *message)
 238 mike          1.2      {
 239 mday          1.7         if (! message)
 240                              return;
 241 david.dillard 1.64     
 242 konrad.r      1.68        PEGASUS_ASSERT(_rep != 0);
 243 mday          1.7         switch (message->getType())
 244                           {
 245                              case SOCKET_MESSAGE:
 246                              {
 247 w.white       1.81.8.1           SocketMessage* socketMessage = (SocketMessage*)message;
 248 david.dillard 1.64     
 249 w.white       1.81.8.1          // If this is a connection request:
 250 h.sterling    1.63     
 251 w.white       1.81.8.1          if (socketMessage->socket == _rep->socket &&
 252                                     socketMessage->events & SocketMessage::READ)
 253                                 {
 254                                     _acceptConnection();
 255                                 }
 256                                 else
 257                                 {
 258                                    // ATTN! this can't happen!
 259 kumpf         1.44                 Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 260                                      "HTTPAcceptor::handleEnqueue: Invalid SOCKET_MESSAGE received.");
 261 w.white       1.81.8.1          }
 262                        
 263                                 break;
 264                              }
 265 j.alex        1.81.8.2  #ifdef PEGASUS_OS_TYPE_WINDOWS
 266 w.white       1.81.8.1       case NAMEDPIPE_MESSAGE:
 267                              {
 268 j.alex        1.81.8.5          NamedPipeMessage* namedPipeMessage = (NamedPipeMessage*)message;
 269 w.white       1.81.8.1 
 270 j.alex        1.81.8.3          if (((namedPipeMessage->namedPipe.getPipe()) == ( _rep->namedPipeServer->getPipe())) &&
 271 j.alex        1.81.8.5              (namedPipeMessage->events & NamedPipeMessage::READ))
 272 w.white       1.81.8.1          {
 273 j.alex        1.81.8.2              _acceptNamedPipeConnection();
 274 w.white       1.81.8.1          }
 275 j.alex        1.81.8.3          else
 276 w.white       1.81.8.1          {
 277                                    // ATTN! this can't happen!
 278                                    Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 279 j.alex        1.81.8.2               "HTTPAcceptor::handleEnqueue: Invalid NAMEDPIPE_MESSAGE received.");
 280 mreddy        1.81.8.6          }
 281                        
 282 w.white       1.81.8.1          break;
 283 mday          1.7      
 284                              }
 285 j.alex        1.81.8.2 #endif
 286                             // may Need to close connection for Named Pipe too.....??
 287                             case CLOSE_CONNECTION_MESSAGE:
 288 mday          1.7            {
 289 j.alex        1.81.8.7         CloseConnectionMessage* closeConnectionMessage
 290                                   = (CloseConnectionMessage*)message;
 291 h.sterling    1.63     
 292 j.alex        1.81.8.7         AutoMutex autoMut(_rep->_connection_mut);
 293 mday          1.7      
 294 j.alex        1.81.8.7         for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
 295 h.sterling    1.63             {
 296 j.alex        1.81.8.7             HTTPConnection* connection = _rep->connections[i];
 297                                    if(!connection->isNamedPipeConnection())
 298                                    {
 299                                
 300                                        PEGASUS_SOCKET socket = connection->getSocket();
 301                        
 302                                        if (socket == closeConnectionMessage->socket)
 303                                        {
 304                                            _monitor->unsolicitSocketMessages(socket);
 305                                            _rep->connections.remove(i);
 306                                            delete connection;
 307                                            break;
 308                                         }
 309                                  }
 310                                  else
 311                                     {
 312                                         NamedPipe namedPipe = connection->getNamedPipe();
 313                                         //NamedPipeMessage* namedPipeMessage = (NamedPipeMessage*)message;
 314                        
 315                                         if (namedPipe.getPipe() == closeConnectionMessage->namedPipe.getPipe())
 316                                         {
 317 j.alex        1.81.8.7                      _monitor->unsolicitPipeMessages(namedPipe);
 318                                             _rep->connections.remove(i);
 319                                             delete connection;
 320                                             break;
 321                                         } 
 322                                    }
 323                                 }
 324 david.dillard 1.64     
 325 j.alex        1.81.8.7       break;
 326 mday          1.7            }
 327 mike          1.2      
 328 kumpf         1.10           default:
 329                              // ATTN: need unexpected message error!
 330 kumpf         1.44           Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 331                                   "HTTPAcceptor::handleEnqueue: Invalid MESSAGE received.");
 332 mday          1.7            break;
 333                           };
 334 mike          1.2      
 335 mday          1.7         delete message;
 336                        }
 337 mike          1.2      
 338                        
 339 mday          1.7      void HTTPAcceptor::handleEnqueue()
 340                        {
 341                           Message* message = dequeue();
 342 mike          1.2      
 343 mday          1.7         if (!message)
 344 kumpf         1.44        {
 345                              Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 346                                   "HTTPAcceptor::handleEnqueue(): No message on queue.");
 347 mday          1.7            return;
 348 kumpf         1.44        }
 349 david.dillard 1.64     
 350 mday          1.7         handleEnqueue(message);
 351 mike          1.2      
 352                        }
 353                        
 354 kumpf         1.25     void HTTPAcceptor::bind()
 355 mike          1.2      {
 356 humberto      1.30        if (_rep){
 357 h.sterling    1.63         //l10n
 358 david.dillard 1.64           //throw BindFailedException("HTTPAcceptor already bound");
 359 humberto      1.34     
 360 humberto      1.30           MessageLoaderParms parms("Common.HTTPAcceptor.ALREADY_BOUND",
 361 h.sterling    1.63                        "HTTPAcceptor already bound");
 362 humberto      1.34     
 363 kumpf         1.44           Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 364                                   "HTTPAcceptor::bind: HTTPAcceptor already bound.");
 365 humberto      1.30           throw BindFailedException(parms);
 366                           }
 367 mike          1.2      
 368 kumpf         1.25        _rep = new HTTPAcceptorRep(_localConnection);
 369 mike          1.2      
 370 mday          1.7         // bind address
 371                           _bind();
 372 mike          1.2      
 373 mday          1.7         return;
 374 mike          1.2      }
 375                        
 376                        /**
 377 mday          1.7         _bind - creates a new server socket and bind socket to the port address.
 378 h.sterling    1.63        If PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET is not defined, the port number is ignored and
 379 kumpf         1.11        a domain socket is bound.
 380 mike          1.2      */
 381                        void HTTPAcceptor::_bind()
 382                        {
 383 mreddy        1.81.8.6     {
 384                                AutoMutex automut(Monitor::_cout_mut);
 385                                PEGASUS_STD(cout) << "in HTTPAcceptor::_bind at the begining" << PEGASUS_STD(endl);
 386                                PEGASUS_STD(cout) << "in HTTPAcceptor::_bind before ASSERT" << PEGASUS_STD(endl);
 387                            }
 388 konrad.r      1.68        PEGASUS_ASSERT(_rep != 0);
 389 mday          1.7         // Create address:
 390 mike          1.2      
 391 mreddy        1.81.8.6    {
 392                               AutoMutex automut(Monitor::_cout_mut);
 393                               PEGASUS_STD(cout) << "in HTTPAcceptor::_bind before memset" << PEGASUS_STD(endl);
 394                           }
 395 j.alex        1.81.8.2 
 396                        
 397                        #ifdef PEGASUS_OS_TYPE_WINDOWS
 398                           if (!_localConnection)
 399                           {
 400                               memset(_rep->address, 0, sizeof(*_rep->address));
 401                           }
 402                        #else
 403 kumpf         1.25        memset(_rep->address, 0, sizeof(*_rep->address));
 404 j.alex        1.81.8.2 #endif
 405                        
 406 mreddy        1.81.8.6    {
 407                               AutoMutex automut(Monitor::_cout_mut);
 408                               PEGASUS_STD(cout) << "in HTTPAcceptor::_bind After memset" << PEGASUS_STD(endl);
 409                           }
 410 j.alex        1.81.8.2 
 411                           if (_localConnection)
 412                           {
 413 mreddy        1.81.8.6 #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
 414 kumpf         1.6      
 415 j.alex        1.81.8.2 #ifdef PEGASUS_OS_TYPE_WINDOWS
 416 mreddy        1.81.8.6        {
 417                                AutoMutex automut(Monitor::_cout_mut);
 418                               PEGASUS_STD(cout)
 419                                   << "in HTTPAcceptor::_bind before calling _createNamedPipe() "
 420 j.alex        1.81.8.5            << PEGASUS_STD(endl);
 421 mreddy        1.81.8.6        }
 422 j.alex        1.81.8.5      // _rep->createNamedPipe();
 423 w.white       1.81.8.1        _createNamedPipe();
 424 mreddy        1.81.8.6        {
 425                                AutoMutex automut(Monitor::_cout_mut);
 426 w.white       1.81.8.1        PEGASUS_STD(cout) << "in HTTPAcceptor::_bind after calling _createNamedPipe() " << PEGASUS_STD(endl);
 427 mreddy        1.81.8.6        }
 428 w.white       1.81.8.1        return;
 429 j.alex        1.81.8.5 #else
 430 mreddy        1.81.8.6        reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family =
 431 kumpf         1.25                AF_UNIX;
 432 j.alex        1.81.8.5        strcpy(
 433                                   reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path,
 434 mreddy        1.81.8.6            PEGASUS_LOCAL_DOMAIN_SOCKET_PATH);
 435 j.alex        1.81.8.5 
 436 chuck         1.38     #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
 437                               AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 438                        #endif
 439 kumpf         1.25            ::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 440 j.alex        1.81.8.5 #endif
 441                        
 442 kumpf         1.6      #else
 443 kumpf         1.25            PEGASUS_ASSERT(false);
 444 kumpf         1.11     #endif
 445 kumpf         1.25        }
 446                           else
 447                           {
 448                               reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_addr.s_addr =
 449                                   INADDR_ANY;
 450                               reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_family =
 451                                   AF_INET;
 452                               reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_port =
 453                                   htons(_portNumber);
 454                           }
 455 mike          1.2      
 456 mday          1.7         // Create socket:
 457 kumpf         1.25        if (_localConnection)
 458                           {
 459                               _rep->socket = socket(AF_UNIX, SOCK_STREAM, 0);
 460                           }
 461                           else
 462                           {
 463                               _rep->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 464 mike          1.79     
 465                               _setTCPNoDelay(_rep->socket);
 466 kumpf         1.25        }
 467 mike          1.2      
 468 mday          1.7         if (_rep->socket < 0)
 469                           {
 470                              delete _rep;
 471                              _rep = 0;
 472 humberto      1.30           //l10n
 473                              //throw BindFailedException("Failed to create socket");
 474                              MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_CREATE_SOCKET",
 475 h.sterling    1.63                        "Failed to create socket");
 476 kumpf         1.44           Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 477                                   "HTTPAcceptor::_bind _rep->socket < 0");
 478 humberto      1.30           throw BindFailedException(parms);
 479 mday          1.7         }
 480                        
 481 mday          1.28     
 482                        // set the close-on-exec bit for this file handle.
 483 david.dillard 1.64     // any unix that forks needs this bit set.
 484 david.dillard 1.78     #if !defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_OS_VMS)
 485 mday          1.28        int sock_flags;
 486                         if( (sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0)
 487                           {
 488 kumpf         1.44            PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 489                                          "HTTPAcceptor::_bind: fcntl(F_GETFD) failed");
 490 mday          1.28        }
 491                           else
 492                           {
 493                              sock_flags |= FD_CLOEXEC;
 494                              if (fcntl(_rep->socket, F_SETFD, sock_flags) < 0)
 495                              {
 496 kumpf         1.44            PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 497                                          "HTTPAcceptor::_bind: fcntl(F_SETFD) failed");
 498 mday          1.28           }
 499                           }
 500 david.dillard 1.64     #endif
 501 mday          1.28     
 502                        
 503 mday          1.7         //
 504                           // Set the socket option SO_REUSEADDR to reuse the socket address so
 505                           // that we can rebind to a new socket using the same address when we
 506                           // need to resume the cimom as a result of a timeout during a Shutdown
 507                           // operation.
 508                           //
 509                           int opt=1;
 510                           if (setsockopt(_rep->socket, SOL_SOCKET, SO_REUSEADDR,
 511 h.sterling    1.63               (char *)&opt, sizeof(opt)) < 0)
 512 mday          1.7         {
 513 mday          1.28           Socket::close(_rep->socket);
 514 mday          1.7            delete _rep;
 515                              _rep = 0;
 516 humberto      1.30           //l10n
 517                              //throw BindFailedException("Failed to set socket option");
 518                              MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SET_SOCKET_OPTION",
 519 h.sterling    1.63                        "Failed to set socket option");
 520 kumpf         1.44           PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 521                                           "HTTPAcceptor::_bind: Failed to set socket option.");
 522 humberto      1.30           throw BindFailedException(parms);
 523 mday          1.7         }
 524                        
 525 david.dillard 1.64     
 526                           //
 527 mday          1.7         // Bind socket to port:
 528 david.dillard 1.64        //
 529 kumpf         1.25        if (::bind(_rep->socket, _rep->address, _rep->address_size) < 0)
 530 mday          1.7         {
 531                              Socket::close(_rep->socket);
 532                              delete _rep;
 533                              _rep = 0;
 534 humberto      1.30           //l10n
 535                              //throw BindFailedException("Failed to bind socket");
 536                              MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
 537 h.sterling    1.63                        "Failed to bind socket");
 538 kumpf         1.44           PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 539                                                "HTTPAcceptor::_bind: Failed to bind socket.");
 540 humberto      1.30           throw BindFailedException(parms);
 541 mday          1.7         }
 542                        
 543 david.dillard 1.64     
 544                           //
 545                           // Get the actual port value used if the caller specified a port value of 0.
 546                           //
 547                           if ( _portNumber == 0 )
 548                           {
 549                              sockaddr_in buf;
 550 david.dillard 1.65           PEGASUS_SOCKLEN_T bufSize = sizeof(buf);
 551 david.dillard 1.64           if ( getsockname(_rep->socket, reinterpret_cast<sockaddr *>(&buf), &bufSize) == 0 )
 552                              {
 553                                  _portNumber = ntohs(buf.sin_port);
 554                              }
 555                           }
 556                        
 557                        
 558 w.otsuka      1.54        //
 559                           //  Change permissions on Linux local domain socket to allow writes by others.
 560                           //
 561 h.sterling    1.63     #if !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) && defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU)
 562 w.otsuka      1.54        if (_localConnection)
 563                           {
 564 david.dillard 1.64          if (::chmod( PEGASUS_LOCAL_DOMAIN_SOCKET_PATH,
 565                                          S_IRUSR | S_IWUSR | S_IXUSR |
 566 w.otsuka      1.54                       S_IRGRP | S_IWGRP | S_IXGRP |
 567                                          S_IROTH | S_IWOTH | S_IXOTH ) < 0 )
 568                             {
 569                               Socket::close(_rep->socket);
 570                               delete _rep;
 571                               _rep = 0;
 572                               //l10n
 573                               //throw BindFailedException("Failed to bind socket");
 574                               MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
 575 h.sterling    1.63                        "Failed to bind socket");
 576 w.otsuka      1.54            PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 577                                      "HTTPAcceptor::_bind: Failed to set domain socket permissions.");
 578                               throw BindFailedException(parms);
 579                             }
 580                           }
 581                        #endif
 582                        
 583 kumpf         1.11        // Set up listening on the given socket:
 584 mday          1.7      
 585 a.arora       1.51        //int const MAX_CONNECTION_QUEUE_LENGTH = 15;
 586 mday          1.7      
 587                           if (listen(_rep->socket, MAX_CONNECTION_QUEUE_LENGTH) < 0)
 588                           {
 589                              Socket::close(_rep->socket);
 590                              delete _rep;
 591                              _rep = 0;
 592 humberto      1.30           //l10n
 593                              //throw BindFailedException("Failed to bind socket");
 594                              MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET",
 595 h.sterling    1.63                        "Failed to bind socket");
 596 kumpf         1.44           PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 597                                          "HTTPAcceptor::_bind: Failed to bind socket(1).");
 598 humberto      1.30           throw BindFailedException(parms);
 599 mday          1.7         }
 600                        
 601                           // Register to receive SocketMessages on this socket:
 602                        
 603 mday          1.21        if ( -1 == ( _entry_index = _monitor->solicitSocketMessages(
 604 h.sterling    1.63           _rep->socket,
 605                              SocketMessage::READ | SocketMessage::EXCEPTION,
 606 david.dillard 1.64           getQueueId(),
 607 h.sterling    1.63           Monitor::ACCEPTOR)))
 608 mday          1.7         {
 609                              Socket::close(_rep->socket);
 610                              delete _rep;
 611                              _rep = 0;
 612 humberto      1.30           //l10n
 613                              //throw BindFailedException("Failed to solicit socket messaeges");
 614                              MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES",
 615 h.sterling    1.63                        "Failed to solicit socket messaeges");
 616 kumpf         1.44           PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 617                                          "HTTPAcceptor::_bind: Failed to solicit socket messages(2).");
 618 humberto      1.30           throw BindFailedException(parms);
 619 mday          1.7         }
 620 mreddy        1.81.8.6    {
 621                            AutoMutex automut(Monitor::_cout_mut);
 622 j.alex        1.81.8.2    PEGASUS_STD(cout) << "in HTTPAcceptor::_bind at the End" << PEGASUS_STD(endl);
 623 mreddy        1.81.8.6    }
 624 j.alex        1.81.8.2 
 625 mike          1.2      }
 626                        
 627                        /**
 628 mday          1.7         closeConnectionSocket - close the server listening socket to disallow
 629                           new client connections.
 630 mike          1.2      */
 631                        void HTTPAcceptor::closeConnectionSocket()
 632                        {
 633 mday          1.7         if (_rep)
 634                           {
 635                              // unregister the socket
 636 kumpf         1.35     
 637                              // ATTN - comment out - see CIMServer::stopClientConnection()
 638                              //_monitor->unsolicitSocketMessages(_rep->socket);
 639 mday          1.7      
 640                              // close the socket
 641                              Socket::close(_rep->socket);
 642 j.alex        1.67           // Unlink Local Domain Socket Bug# 3312
 643                              if (_localConnection)
 644                              {
 645 j.alex        1.81.8.5 #ifndef PEGASUS_OS_TYPE_WINDOWS
 646                         #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
 647 denise.eckstein 1.71               PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,
 648 j.alex          1.67                             "HTTPAcceptor::closeConnectionSocket Unlinking local connection." );
 649                                   ::unlink(
 650                                       reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 651 j.alex          1.81.8.5  #else
 652 j.alex          1.67              PEGASUS_ASSERT(false);
 653 j.alex          1.81.8.5  #endif
 654 j.alex          1.67     #endif
 655                                }
 656                          
 657 mday            1.7         }
 658 kumpf           1.44        else
 659                             {
 660                                PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 661                                                  "HTTPAcceptor::closeConnectionSocket failure _rep is null." );
 662                             }
 663 mike            1.2      }
 664                          
 665                          /**
 666 mday            1.7         reopenConnectionSocket - creates a new server socket.
 667 mike            1.2      */
 668                          void HTTPAcceptor::reopenConnectionSocket()
 669                          {
 670 mday            1.7         if (_rep)
 671                             {
 672                                _bind();
 673                             }
 674 kumpf           1.44        else
 675                             {
 676                                PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 677                                                  "HTTPAcceptor::reopenConnectionSocket failure _rep is null." );
 678                             }
 679 mike            1.2      }
 680                          
 681                          /**
 682 mday            1.7         getOutstandingRequestCount - returns the number of outstanding requests.
 683 mike            1.2      */
 684 david.dillard   1.64     Uint32 HTTPAcceptor::getOutstandingRequestCount() const
 685 mike            1.2      {
 686 mday            1.28        Uint32 count = 0;
 687 konrad.r        1.68        if (_rep)
 688 mday            1.7         {
 689 konrad.r        1.68           AutoMutex autoMut(_rep->_connection_mut);
 690                                if (_rep->connections.size() > 0)
 691                                {
 692                                   HTTPConnection* connection = _rep->connections[0];
 693                                   count = connection->getRequestCount();
 694                                }
 695 mday            1.7         }
 696 mday            1.28        return count;
 697 mike            1.2      }
 698                          
 699 david.dillard   1.64     
 700                          /**
 701                              getPortNumber - returns the port number used for the connection
 702                          */
 703                          Uint32 HTTPAcceptor::getPortNumber() const
 704                          {
 705                              return _portNumber;
 706                          }
 707                          
 708 mike            1.2      void HTTPAcceptor::unbind()
 709                          {
 710 mday            1.7         if (_rep)
 711                             {
 712 david.dillard   1.64           _portNumber = 0;
 713 mday            1.7            Socket::close(_rep->socket);
 714 kumpf           1.25     
 715                                if (_localConnection)
 716                                {
 717 h.sterling      1.63     #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
 718 j.alex          1.81.8.5 #ifndef PEGASUS_OS_TYPE_WINDOWS
 719                          
 720 kumpf           1.25              ::unlink(
 721                                       reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);
 722 j.alex          1.81.8.5 #endif
 723 kumpf           1.25     #else
 724                                   PEGASUS_ASSERT(false);
 725                          #endif
 726                                }
 727                          
 728 mday            1.7            delete _rep;
 729                                _rep = 0;
 730                             }
 731 kumpf           1.44        else
 732                             {
 733                                PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 734                                        "HTTPAcceptor::unbind failure _rep is null." );
 735                             }
 736 mike            1.2      }
 737                          
 738                          void HTTPAcceptor::destroyConnections()
 739                          {
 740 konrad.r        1.68        if (_rep)
 741                             {
 742                               // For each connection created by this object:
 743 mday            1.28     
 744 konrad.r        1.68          AutoMutex autoMut(_rep->_connection_mut);
 745                               for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
 746                               {
 747                                  HTTPConnection* connection = _rep->connections[i];
 748 j.alex          1.81.8.7         if(!connection->isNamedPipeConnection())
 749                                  {
 750 mike            1.2      
 751 j.alex          1.81.8.7             PEGASUS_SOCKET socket = connection->getSocket();
 752 mike            1.2      
 753 j.alex          1.81.8.7            // Unsolicit SocketMessages:
 754                          
 755                                     _monitor->unsolicitSocketMessages(socket);
 756 mike            1.2      
 757 j.alex          1.81.8.7            // Destroy the connection (causing it to close):
 758                                  }
 759                                  else 
 760                                  {
 761                                      NamedPipe namedPipe = connection->getNamedPipe();
 762                                      _monitor->unsolicitPipeMessages(namedPipe);
 763                                       
 764                                  }
 765 mike            1.2      
 766 mike            1.75             while (connection->refcount.get()) { }
 767 konrad.r        1.68             delete connection;
 768                               }
 769 mike            1.2      
 770 konrad.r        1.68          _rep->connections.clear();
 771 mday            1.7         }
 772 mike            1.2      }
 773                          
 774                          void HTTPAcceptor::_acceptConnection()
 775                          {
 776 mday            1.7         // This function cannot be called on an invalid socket!
 777 mike            1.2      
 778 mday            1.7         PEGASUS_ASSERT(_rep != 0);
 779 mike            1.2      
 780 mday            1.7         if (!_rep)
 781                                return;
 782 mike            1.2      
 783 mday            1.7         // Accept the connection (populate the address):
 784 mike            1.2      
 785 kumpf           1.25        struct sockaddr* accept_address;
 786 mike            1.77        PEGASUS_SOCKLEN_T address_size;
 787 mike            1.2      
 788 kumpf           1.25        if (_localConnection)
 789                             {
 790 j.alex          1.81.8.5 #ifndef PEGASUS_OS_TYPE_WINDOWS
 791 h.sterling      1.63     #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET
 792 kumpf           1.25            accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un);
 793                                 address_size = sizeof(struct sockaddr_un);
 794 mike            1.2      #else
 795 kumpf           1.25            PEGASUS_ASSERT(false);
 796 mike            1.2      #endif
 797 j.alex          1.81.8.5 #endif
 798 kumpf           1.25        }
 799                             else
 800                             {
 801                                 accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in);
 802                                 address_size = sizeof(struct sockaddr_in);
 803                             }
 804                          
 805 david.dillard   1.73        PEGASUS_SOCKET socket = accept(_rep->socket, accept_address, &address_size);
 806 kumpf           1.25     
 807                             delete accept_address;
 808 mike            1.2      
 809 mday            1.7         if (socket < 0)
 810                             {
 811 mday            1.36     
 812 david           1.27            Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
 813 h.sterling      1.63                "HTTPAcceptor - accept() failure.  errno: $0"
 814                                     ,errno);
 815 david           1.27     
 816 kumpf           1.44            PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 817 kumpf           1.19                             "HTTPAcceptor: accept() failed");
 818 mday            1.7            return;
 819                             }
 820 david           1.27     
 821 david.dillard   1.64     // set the close on exec flag
 822 david.dillard   1.78     #if !defined(PEGASUS_OS_TYPE_WINDOWS) && !defined(PEGASUS_OS_VMS)
 823 mday            1.28        int sock_flags;
 824                           if( (sock_flags = fcntl(socket, F_GETFD, 0)) < 0)
 825                             {
 826 kumpf           1.44            PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 827 mday            1.28                             "HTTPAcceptor: fcntl(F_GETFD) failed");
 828                             }
 829                             else
 830                             {
 831                                sock_flags |= FD_CLOEXEC;
 832                                if (fcntl(socket, F_SETFD, sock_flags) < 0)
 833                                {
 834 kumpf           1.44            PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 835 mday            1.28                             "HTTPAcceptor: fcntl(F_SETFD) failed");
 836                                }
 837                             }
 838 david.dillard   1.64     #endif
 839 mday            1.28     
 840                          
 841 mike            1.76        PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0,
 842                                 "HTTPAcceptor - accept() success.  Socket: $1" ,socket));
 843 mike            1.2      
 844 kumpf           1.72        AutoPtr<MP_Socket> mp_socket(new MP_Socket(
 845                                 socket, _sslcontext, _sslContextObjectLock, _exportConnection));
 846 mike            1.2      
 847 kumpf           1.72        // Perform the SSL handshake, if applicable.  Make the socket non-blocking
 848                             // for this operation so we can send it back to the Monitor's select() loop
 849                             // if it takes a while.
 850                          
 851                             mp_socket->disableBlocking();
 852                             Sint32 socketAcceptStatus = mp_socket->accept();
 853                             mp_socket->enableBlocking();
 854 nag.boranna     1.59     
 855 kumpf           1.72        if (socketAcceptStatus < 0)
 856 kumpf           1.19        {
 857 nag.boranna     1.61            PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 858 kumpf           1.19                             "HTTPAcceptor: SSL_accept() failed");
 859 nag.boranna     1.61            mp_socket->close();
 860                                 return;
 861 mday            1.7         }
 862 mike            1.2      
 863 kumpf           1.72        // Create a new connection and add it to the connection list:
 864                          
 865 david.dillard   1.64        HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket,
 866 kumpf           1.49            this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection);
 867 mike            1.2      
 868 kumpf           1.72        if (socketAcceptStatus == 0)
 869                             {
 870                                 PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,
 871                                     "HTTPAcceptor: SSL_accept() pending");
 872                                 connection->_acceptPending = true;
 873                             }
 874                          
 875 mday            1.7         // Solicit events on this new connection's socket:
 876 mday            1.21        int index;
 877 david.dillard   1.64     
 878 mday            1.22        if (-1 ==  (index = _monitor->solicitSocketMessages(
 879 h.sterling      1.63           connection->getSocket(),
 880                                SocketMessage::READ | SocketMessage::EXCEPTION,
 881                                connection->getQueueId(), Monitor::CONNECTION)) )
 882 mday            1.7         {
 883 kumpf           1.37           // ATTN-DE-P2-2003100503::TODO::Need to enhance code to return
 884                                // an error message to Client application.
 885 kumpf           1.44           Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 886                                    "HTTPAcceptor::_acceptConnection: Attempt to allocate entry in _entries table failed.");
 887 mday            1.7            delete connection;
 888                                Socket::close(socket);
 889 kumpf           1.37           return;
 890 mday            1.7         }
 891 a.arora         1.48     
 892 mday            1.7         // Save the socket for cleanup later:
 893 mday            1.21        connection->_entry_index = index;
 894 a.arora         1.50        AutoMutex autoMut(_rep->_connection_mut);
 895 mday            1.7         _rep->connections.append(connection);
 896 mike            1.2      }
 897 mday            1.32     
 898 j.alex          1.81.8.2 #ifdef PEGASUS_OS_TYPE_WINDOWS
 899 w.white         1.81.8.1 void HTTPAcceptor::_createNamedPipe()
 900                          {
 901 mreddy          1.81.8.6     {
 902                               AutoMutex automut(Monitor::_cout_mut);
 903 j.alex          1.81.8.5     PEGASUS_STD(cout) << "Entering  HTTPAcceptor::_createNamedPipe()." << PEGASUS_STD(endl);
 904 mreddy          1.81.8.6     }
 905 w.white         1.81.8.1 
 906 j.alex          1.81.8.2     _rep->namedPipeServer = new NamedPipeServer("\\\\.\\pipe\\MyNamedPipe");
 907 mreddy          1.81.8.6     {
 908                               AutoMutex automut(Monitor::_cout_mut);
 909 w.white         1.81.8.1     PEGASUS_STD(cout) << "in HTTPAcceptor::_createNamedPipe() after calling the pipe server constructor" << PEGASUS_STD(endl);
 910 mreddy          1.81.8.6     }
 911 j.alex          1.81.8.5 
 912 mreddy          1.81.8.6     {
 913                               AutoMutex automut(Monitor::_cout_mut);
 914 j.alex          1.81.8.5     cout << "Named pipe...in _createNamedPipe..." << _rep->namedPipeServer->getPipe() << endl;
 915 mreddy          1.81.8.6     }
 916 w.white         1.81.8.1     // Register to receive Messages on Connection pipe:
 917 mreddy          1.81.8.6 
 918 w.white         1.81.8.1    if ( -1 == ( _entry_index = _monitor->solicitPipeMessages(
 919 j.alex          1.81.8.2       *_rep->namedPipeServer,
 920                                NamedPipeMessage::READ | NamedPipeMessage::EXCEPTION,
 921 w.white         1.81.8.1       getQueueId(),
 922                                Monitor::ACCEPTOR)))
 923                             {
 924 j.alex          1.81.8.2        ::CloseHandle(_rep->namedPipeServer->getPipe());
 925                                 delete _rep;
 926                                 _rep = 0;
 927                                 //l10n
 928                                 //throw BindFailedException("Failed to solicit socket messaeges");
 929                                 MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES",
 930                                              "Failed to solicit socket messaeges");
 931                                 PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
 932                                             "HTTPAcceptor::_bind: Failed to solicit socket messages(2).");
 933                                 throw BindFailedException(parms);
 934 mreddy          1.81.8.6        {
 935                                  AutoMutex automut(Monitor::_cout_mut); //added
 936 w.white         1.81.8.1        PEGASUS_STD(cout) << "in HTTPAcceptor::_createNamedPipe() _monitor->solicitSocketMessages failed" << PEGASUS_STD(endl);
 937 mreddy          1.81.8.6        }
 938 w.white         1.81.8.1 
 939                             }
 940                          
 941 mreddy          1.81.8.6    {
 942                                 AutoMutex automut(Monitor::_cout_mut);
 943                                 PEGASUS_STD(cout) << "Leaving  HTTPAcceptor::_createNamedPipe()." << PEGASUS_STD(endl);
 944                             }
 945                             return;
 946 w.white         1.81.8.1 
 947                          }
 948 j.alex          1.81.8.2 #endif
 949 w.white         1.81.8.1 
 950 j.alex          1.81.8.2 
 951                          #ifdef PEGASUS_OS_TYPE_WINDOWS
 952                          void HTTPAcceptor::_acceptNamedPipeConnection()
 953 w.white         1.81.8.1 {
 954 j.alex          1.81.8.2     PEGASUS_ASSERT(_rep != 0);
 955                          
 956                              if (!_rep)
 957                                 return;
 958 mreddy          1.81.8.6     {
 959                                  AutoMutex automut(Monitor::_cout_mut);
 960                                  cout <<"In HTTPAcceptor::_acceptNamedPipeConnection " << endl;
 961                              }
 962 w.white         1.81.8.1 
 963 j.alex          1.81.8.2    // shouldnt we be using the private var....
 964                               //                 _namedPipeServer->accept()
 965                          
 966                              NamedPipeServerEndPiont nPSEndPoint = _rep->namedPipeServer->accept();
 967                              // Registerpe to receive Messages on Connection pipe:
 968 mreddy          1.81.8.6     {
 969                                  AutoMutex automut(Monitor::_cout_mut);
 970                                  cout << " In _acceptNamedPipeConnection -- after calling namedPipeServer->accept()" << endl;
 971                              }
 972 j.alex          1.81.8.2     HTTPConnection* connection = new HTTPConnection(_monitor, nPSEndPoint,
 973                                  this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection);
 974                          
 975                              /*  NOT SURE WHAT TO DO HERE  ....
 976                              if (socketAcceptStatus == 0)
 977                              {
 978                                  PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2,
 979                                      "HTTPAcceptor: SSL_accept() pending");
 980                                  connection->_acceptPending = true;
 981                              }
 982                          
 983                              */
 984                          
 985                              // Solicit events on this new connection's socket:
 986                              int index;
 987                          
 988 mreddy          1.81.8.6     {
 989                                  AutoMutex automut(Monitor::_cout_mut);
 990                                  cout << endl << connection->getNamedPipe().getName() << " has a this as a QueueID " <<
 991 w.white         1.81.8.4          connection->getQueueId() << endl;
 992 mreddy          1.81.8.6     }
 993 j.alex          1.81.8.2     if (-1 ==  (index = _monitor->solicitPipeMessages(
 994                                 connection->getNamedPipe(),
 995                                 NamedPipeMessage::READ | NamedPipeMessage::EXCEPTION,
 996 w.white         1.81.8.4        connection->getQueueId(), Monitor::ACCEPTOR)) )
 997 j.alex          1.81.8.2     {
 998                                 // ATTN-DE-P2-2003100503::TODO::Need to enhance code to return
 999                                 // an error message to Client application.
1000                                 Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2,
1001                                     "HTTPAcceptor::_acceptPipeConnection: Attempt to allocate entry in _entries table failed.");
1002                                 delete connection;
1003                                 //  May have to close the PIPE here...
1004                                 //Socket::close(socket);
1005                                 return;
1006                              }
1007                          
1008                              // Save the socket for cleanup later:
1009                              connection->_entry_index = index;
1010                              AutoMutex autoMut(_rep->_connection_mut);
1011                              _rep->connections.append(connection);
1012                          
1013 mreddy          1.81.8.6   {
1014                                AutoMutex automut(Monitor::_cout_mut);
1015                                PEGASUS_STD(cout)
1016 j.alex          1.81.8.2        << "in HTTPAcceptor::_acceptNamedPipeConnection() at the end" << PEGASUS_STD(endl);
1017 mreddy          1.81.8.6   }
1018 w.white         1.81.8.1 
1019                          }
1020 j.alex          1.81.8.2 #endif
1021 w.white         1.81.8.1 
1022 mike            1.2      PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2