version 1.64, 2005/05/03 13:05:05
|
version 1.81.8.8, 2006/07/19 15:41:47
|
|
|
//%2005//////////////////////////////////////////////////////////////////////// |
//%2006//////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development | // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. | // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
|
|
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. | // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; | // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
// EMC Corporation; VERITAS Software Corporation; The Open Group. | // EMC Corporation; VERITAS Software Corporation; The Open Group. |
|
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
|
// EMC Corporation; Symantec Corporation; The Open Group. |
// | // |
// 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 |
// of this software and associated documentation files (the "Software"), to | // of this software and associated documentation files (the "Software"), to |
|
|
// Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) | // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) |
// Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com) | // Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com) |
// Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2065 | // Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2065 |
// David Dillard, VERITAS Software Corp. |
// David Dillard, Symantec Corp. (david_dillard@symantec.com) |
// (david.dillard@veritas.com) |
// John Alex, IBM (johnalex@us.ibm.com) for Bug#3312 |
// | // |
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
|
|
#include <iostream> | #include <iostream> |
#include "Socket.h" | #include "Socket.h" |
| |
#ifdef PEGASUS_PLATFORM_WIN32_IX86_MSVC |
#ifdef PEGASUS_OS_TYPE_WINDOWS |
#include <windows.h> | #include <windows.h> |
#else | #else |
# include <cctype> | # include <cctype> |
|
|
# include <fcntl.h> | # include <fcntl.h> |
# include <netdb.h> | # include <netdb.h> |
# include <netinet/in.h> | # include <netinet/in.h> |
|
# include <netinet/tcp.h> |
# include <arpa/inet.h> | # include <arpa/inet.h> |
# include <sys/socket.h> | # include <sys/socket.h> |
# ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | # ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
|
|
#include "OS400ConvertChar.h" | #include "OS400ConvertChar.h" |
#endif | #endif |
| |
|
|
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
static int MAX_CONNECTION_QUEUE_LENGTH = -1; |
|
| |
|
static int MAX_CONNECTION_QUEUE_LENGTH = -1; |
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
// | // |
|
|
{ | { |
if (local) | if (local) |
{ | { |
|
#ifndef PEGASUS_OS_TYPE_WINDOWS |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
|
|
address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un); | address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un); |
address_size = sizeof(struct sockaddr_un); | address_size = sizeof(struct sockaddr_un); |
#else | #else |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
|
|
|
#endif |
} | } |
else | else |
{ | { |
|
|
address_size = sizeof(struct sockaddr_in); | address_size = sizeof(struct sockaddr_in); |
} | } |
} | } |
|
~HTTPAcceptorRep() |
|
{ |
|
delete address; |
|
} |
struct sockaddr* address; | struct sockaddr* address; |
| |
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_VMS) |
PEGASUS_SOCKLEN_T address_size; |
size_t address_size; |
|
#elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || (defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC) && !defined(SUNOS_5_6)) |
|
socklen_t address_size; |
|
#else |
|
int address_size; |
|
#endif |
|
Mutex _connection_mut; | Mutex _connection_mut; |
| |
Sint32 socket; |
PEGASUS_SOCKET socket; |
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
NamedPipeServer* namedPipeServer; |
|
#endif |
Array<HTTPConnection*> connections; | Array<HTTPConnection*> connections; |
|
/* |
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
// This method creates and connects to a named pipe |
|
void createNamedPipe(); |
|
NamedPipeServer* namedPipeServer; |
|
void _acceptNamedPipeConnection(NamedPipeMessage* namedPipeMessage); |
|
#endif |
|
*/ |
|
|
|
|
}; | }; |
| |
|
//------------------------------------------------------------------------------ |
|
// |
|
// _setTCPNoDelay() |
|
// |
|
//------------------------------------------------------------------------------ |
|
|
|
inline void _setTCPNoDelay(PEGASUS_SOCKET socket) |
|
{ |
|
// This function disables "Nagle's Algorithm" also known as "the TCP delay |
|
// algorithm", which causes read operations to obtain whatever data is |
|
// already in the input queue and then wait a little longer to see if |
|
// more data arrives. This algorithm optimizes the case in which data is |
|
// sent in only one direction but severely impairs performance of round |
|
// trip servers. Disabling TCP delay is a standard technique for round |
|
// trip servers. |
|
|
|
int opt = 1; |
|
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*)&opt, sizeof(opt)); |
|
} |
|
|
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
// | // |
// HTTPAcceptor | // HTTPAcceptor |
|
|
| |
HTTPAcceptor::~HTTPAcceptor() | HTTPAcceptor::~HTTPAcceptor() |
{ | { |
|
destroyConnections(); |
unbind(); | unbind(); |
// ATTN: Is this correct in a multi-HTTPAcceptor server? | // ATTN: Is this correct in a multi-HTTPAcceptor server? |
Socket::uninitializeInterface(); | Socket::uninitializeInterface(); |
|
|
if (! message) | if (! message) |
return; | return; |
| |
|
PEGASUS_ASSERT(_rep != 0); |
switch (message->getType()) | switch (message->getType()) |
{ | { |
case SOCKET_MESSAGE: | case SOCKET_MESSAGE: |
|
|
| |
break; | break; |
} | } |
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
case NAMEDPIPE_MESSAGE: |
|
{ |
|
NamedPipeMessage* namedPipeMessage = (NamedPipeMessage*)message; |
| |
|
if (((namedPipeMessage->namedPipe.getPipe()) == ( _rep->namedPipeServer->getPipe())) && |
|
(namedPipeMessage->events & NamedPipeMessage::READ)) |
|
{ |
|
_acceptNamedPipeConnection(); |
|
} |
|
else |
|
{ |
|
// ATTN! this can't happen! |
|
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
"HTTPAcceptor::handleEnqueue: Invalid NAMEDPIPE_MESSAGE received."); |
|
} |
|
|
|
break; |
|
|
|
} |
|
#endif |
|
// may Need to close connection for Named Pipe too.....?? |
case CLOSE_CONNECTION_MESSAGE: | case CLOSE_CONNECTION_MESSAGE: |
{ | { |
CloseConnectionMessage* closeConnectionMessage | CloseConnectionMessage* closeConnectionMessage |
|
|
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]; |
Sint32 socket = connection->getSocket(); |
if(!connection->isNamedPipeConnection()) |
|
{ |
|
|
|
PEGASUS_SOCKET socket = connection->getSocket(); |
| |
if (socket == closeConnectionMessage->socket) | if (socket == closeConnectionMessage->socket) |
{ | { |
|
|
break; | break; |
} | } |
} | } |
|
else |
|
{ |
|
NamedPipe namedPipe = connection->getNamedPipe(); |
|
//NamedPipeMessage* namedPipeMessage = (NamedPipeMessage*)message; |
|
|
|
if (namedPipe.getPipe() == closeConnectionMessage->namedPipe.getPipe()) |
|
{ |
|
_monitor->unsolicitPipeMessages(namedPipe); |
|
_rep->connections.remove(i); |
|
delete connection; |
|
break; |
|
} |
|
} |
|
} |
| |
break; | break; |
} | } |
|
|
*/ | */ |
void HTTPAcceptor::_bind() | void HTTPAcceptor::_bind() |
{ | { |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) << "in HTTPAcceptor::_bind at the begining" << PEGASUS_STD(endl); |
|
PEGASUS_STD(cout) << "in HTTPAcceptor::_bind before ASSERT" << PEGASUS_STD(endl); |
|
} |
|
PEGASUS_ASSERT(_rep != 0); |
// Create address: | // Create address: |
| |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) << "in HTTPAcceptor::_bind before memset" << PEGASUS_STD(endl); |
|
} |
|
|
|
|
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
if (!_localConnection) |
|
{ |
|
memset(_rep->address, 0, sizeof(*_rep->address)); |
|
} |
|
#else |
memset(_rep->address, 0, sizeof(*_rep->address)); | memset(_rep->address, 0, sizeof(*_rep->address)); |
|
#endif |
|
|
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) << "in HTTPAcceptor::_bind After memset" << PEGASUS_STD(endl); |
|
} |
| |
if (_localConnection) | if (_localConnection) |
{ | { |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
|
|
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) |
|
<< "in HTTPAcceptor::_bind before calling _createNamedPipe() " |
|
<< PEGASUS_STD(endl); |
|
} |
|
// _rep->createNamedPipe(); |
|
_createNamedPipe(); |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) << "in HTTPAcceptor::_bind after calling _createNamedPipe() " << PEGASUS_STD(endl); |
|
} |
|
return; |
|
#else |
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family = | reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family = |
AF_UNIX; | AF_UNIX; |
strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path, |
strcpy( |
|
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path, |
PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); | PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); |
|
|
#ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM | #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM |
AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); | AtoE(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
#endif | #endif |
::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); | ::unlink(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
|
#endif |
|
|
#else | #else |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
|
|
} | } |
| |
// Create socket: | // Create socket: |
|
|
if (_localConnection) | 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); |
|
|
|
_setTCPNoDelay(_rep->socket); |
} | } |
| |
if (_rep->socket < 0) | if (_rep->socket < 0) |
|
|
| |
// set the close-on-exec bit for this file handle. | // set the close-on-exec bit for this file handle. |
// any unix that forks needs this bit set. | // any unix that forks needs this bit set. |
#if !defined PEGASUS_PLATFORM_WIN32_IX86_MSVC && !defined(PEGASUS_OS_VMS) |
#if !defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_OS_VMS) |
int sock_flags; | int sock_flags; |
if( (sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0) | if( (sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0) |
{ | { |
|
|
if ( _portNumber == 0 ) | if ( _portNumber == 0 ) |
{ | { |
sockaddr_in buf; | sockaddr_in buf; |
int bufSize = sizeof(buf); |
PEGASUS_SOCKLEN_T bufSize = sizeof(buf); |
if ( getsockname(_rep->socket, reinterpret_cast<sockaddr *>(&buf), &bufSize) == 0 ) | if ( getsockname(_rep->socket, reinterpret_cast<sockaddr *>(&buf), &bufSize) == 0 ) |
{ | { |
_portNumber = ntohs(buf.sin_port); | _portNumber = ntohs(buf.sin_port); |
|
|
"HTTPAcceptor::_bind: Failed to solicit socket messages(2)."); | "HTTPAcceptor::_bind: Failed to solicit socket messages(2)."); |
throw BindFailedException(parms); | throw BindFailedException(parms); |
} | } |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) << "in HTTPAcceptor::_bind at the End" << PEGASUS_STD(endl); |
|
} |
|
|
} | } |
| |
/** | /** |
|
|
| |
// close the socket | // close the socket |
Socket::close(_rep->socket); | Socket::close(_rep->socket); |
|
// Unlink Local Domain Socket Bug# 3312 |
|
if (_localConnection) |
|
{ |
|
#ifndef PEGASUS_OS_TYPE_WINDOWS |
|
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
|
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, |
|
"HTTPAcceptor::closeConnectionSocket Unlinking local connection." ); |
|
::unlink( |
|
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
|
#else |
|
PEGASUS_ASSERT(false); |
|
#endif |
|
#endif |
|
} |
|
|
} | } |
else | else |
{ | { |
|
|
Uint32 HTTPAcceptor::getOutstandingRequestCount() const | Uint32 HTTPAcceptor::getOutstandingRequestCount() const |
{ | { |
Uint32 count = 0; | Uint32 count = 0; |
|
if (_rep) |
|
{ |
AutoMutex autoMut(_rep->_connection_mut); | AutoMutex autoMut(_rep->_connection_mut); |
if (_rep->connections.size() > 0) | if (_rep->connections.size() > 0) |
{ | { |
HTTPConnection* connection = _rep->connections[0]; | HTTPConnection* connection = _rep->connections[0]; |
count = connection->getRequestCount(); | count = connection->getRequestCount(); |
} | } |
|
} |
return count; | return count; |
} | } |
| |
|
|
if (_localConnection) | if (_localConnection) |
{ | { |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
|
#ifndef PEGASUS_OS_TYPE_WINDOWS |
|
|
::unlink( | ::unlink( |
reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); | reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path); |
|
#endif |
#else | #else |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
|
|
| |
void HTTPAcceptor::destroyConnections() | void HTTPAcceptor::destroyConnections() |
{ | { |
|
if (_rep) |
|
{ |
// For each connection created by this object: | // For each connection created by this object: |
| |
AutoMutex autoMut(_rep->_connection_mut); | AutoMutex autoMut(_rep->_connection_mut); |
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]; |
Sint32 socket = connection->getSocket(); |
if(!connection->isNamedPipeConnection()) |
|
{ |
|
|
|
PEGASUS_SOCKET socket = connection->getSocket(); |
| |
// Unsolicit SocketMessages: | // Unsolicit SocketMessages: |
| |
_monitor->unsolicitSocketMessages(socket); | _monitor->unsolicitSocketMessages(socket); |
| |
// Destroy the connection (causing it to close): | // Destroy the connection (causing it to close): |
|
} |
|
else |
|
{ |
|
NamedPipe namedPipe = connection->getNamedPipe(); |
|
_monitor->unsolicitPipeMessages(namedPipe); |
| |
while (connection->refcount.value()) { } |
::FlushFileBuffers(namedPipe.getPipe()); |
|
::DisconnectNamedPipe(namedPipe.getPipe()); |
|
::CloseHandle(namedPipe.getPipe()); |
|
} |
|
|
|
while (connection->refcount.get()) { } |
delete connection; | delete connection; |
} | } |
| |
_rep->connections.clear(); | _rep->connections.clear(); |
|
} |
} | } |
| |
void HTTPAcceptor::_acceptConnection() | void HTTPAcceptor::_acceptConnection() |
|
|
// Accept the connection (populate the address): | // Accept the connection (populate the address): |
| |
struct sockaddr* accept_address; | struct sockaddr* accept_address; |
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) || defined(PEGASUS_OS_VMS) |
PEGASUS_SOCKLEN_T address_size; |
size_t address_size; |
|
#elif defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX) || defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || (defined(PEGASUS_OS_SOLARIS) && !defined(SUNOS_5_6)) |
|
socklen_t address_size; |
|
#else |
|
int address_size; |
|
#endif |
|
| |
if (_localConnection) | if (_localConnection) |
{ | { |
|
#ifndef PEGASUS_OS_TYPE_WINDOWS |
#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET | #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET |
accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un); | accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un); |
address_size = sizeof(struct sockaddr_un); | address_size = sizeof(struct sockaddr_un); |
#else | #else |
PEGASUS_ASSERT(false); | PEGASUS_ASSERT(false); |
#endif | #endif |
|
#endif |
} | } |
else | else |
{ | { |
|
|
address_size = sizeof(struct sockaddr_in); | address_size = sizeof(struct sockaddr_in); |
} | } |
| |
Sint32 socket = accept(_rep->socket, accept_address, &address_size); |
PEGASUS_SOCKET socket = accept(_rep->socket, accept_address, &address_size); |
| |
delete accept_address; | delete accept_address; |
| |
|
|
} | } |
| |
// set the close on exec flag | // set the close on exec flag |
#if !defined PEGASUS_PLATFORM_WIN32_IX86_MSVC && !defined(PEGASUS_OS_VMS) |
#if !defined(PEGASUS_OS_TYPE_WINDOWS) && !defined(PEGASUS_OS_VMS) |
int sock_flags; | int sock_flags; |
if( (sock_flags = fcntl(socket, F_GETFD, 0)) < 0) | if( (sock_flags = fcntl(socket, F_GETFD, 0)) < 0) |
{ | { |
|
|
#endif | #endif |
| |
| |
Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, |
PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0, |
"HTTPAcceptor - accept() success. Socket: $1" |
"HTTPAcceptor - accept() success. Socket: $1" ,socket)); |
,socket); |
|
| |
// Create a new conection and add it to the connection list: |
AutoPtr<MP_Socket> mp_socket(new MP_Socket( |
|
socket, _sslcontext, _sslContextObjectLock, _exportConnection)); |
| |
AutoPtr<MP_Socket> mp_socket(new MP_Socket(socket, _sslcontext, _exportConnection)); |
// Perform the SSL handshake, if applicable. Make the socket non-blocking |
|
// for this operation so we can send it back to the Monitor's select() loop |
|
// if it takes a while. |
| |
Sint32 retVal; |
mp_socket->disableBlocking(); |
|
Sint32 socketAcceptStatus = mp_socket->accept(); |
|
mp_socket->enableBlocking(); |
| |
if (_sslcontext) |
if (socketAcceptStatus < 0) |
{ |
|
// |
|
// For SSL connections, obtain read lock to SSLContext object before |
|
// calling the accept() method of MP_Socket. |
|
// |
|
ReadLock rlock(*_sslContextObjectLock); |
|
retVal = mp_socket->accept(); |
|
} |
|
else |
|
{ |
|
retVal = mp_socket->accept(); |
|
} |
|
|
|
if (retVal < 0) |
|
{ | { |
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, | PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
"HTTPAcceptor: SSL_accept() failed"); | "HTTPAcceptor: SSL_accept() failed"); |
|
|
return; | return; |
} | } |
| |
|
// Create a new connection and add it to the connection list: |
|
|
HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket, | HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket, |
this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection); | this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection); |
| |
|
if (socketAcceptStatus == 0) |
|
{ |
|
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, |
|
"HTTPAcceptor: SSL_accept() pending"); |
|
connection->_acceptPending = true; |
|
} |
|
|
// Solicit events on this new connection's socket: | // Solicit events on this new connection's socket: |
int index; | int index; |
| |
|
|
_rep->connections.append(connection); | _rep->connections.append(connection); |
} | } |
| |
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
void HTTPAcceptor::_createNamedPipe() |
|
{ |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) << "Entering HTTPAcceptor::_createNamedPipe()." << PEGASUS_STD(endl); |
|
} |
|
|
|
_rep->namedPipeServer = new NamedPipeServer("\\\\.\\pipe\\MyNamedPipe"); |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) << "in HTTPAcceptor::_createNamedPipe() after calling the pipe server constructor" << PEGASUS_STD(endl); |
|
} |
|
|
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
cout << "Named pipe...in _createNamedPipe..." << _rep->namedPipeServer->getPipe() << endl; |
|
} |
|
// Register to receive Messages on Connection pipe: |
|
|
|
if ( -1 == ( _entry_index = _monitor->solicitPipeMessages( |
|
*_rep->namedPipeServer, |
|
NamedPipeMessage::READ | NamedPipeMessage::EXCEPTION, |
|
getQueueId(), |
|
Monitor::ACCEPTOR))) |
|
{ |
|
::CloseHandle(_rep->namedPipeServer->getPipe()); |
|
delete _rep; |
|
_rep = 0; |
|
//l10n |
|
//throw BindFailedException("Failed to solicit socket messaeges"); |
|
MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES", |
|
"Failed to solicit socket messaeges"); |
|
PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
"HTTPAcceptor::_bind: Failed to solicit socket messages(2)."); |
|
throw BindFailedException(parms); |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); //added |
|
PEGASUS_STD(cout) << "in HTTPAcceptor::_createNamedPipe() _monitor->solicitSocketMessages failed" << PEGASUS_STD(endl); |
|
} |
|
|
|
} |
|
|
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) << "Leaving HTTPAcceptor::_createNamedPipe()." << PEGASUS_STD(endl); |
|
} |
|
return; |
|
|
|
} |
|
#endif |
|
|
|
|
|
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
void HTTPAcceptor::_acceptNamedPipeConnection() |
|
{ |
|
PEGASUS_ASSERT(_rep != 0); |
|
|
|
if (!_rep) |
|
return; |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
cout <<"In HTTPAcceptor::_acceptNamedPipeConnection " << endl; |
|
} |
|
|
|
// shouldnt we be using the private var.... |
|
// _namedPipeServer->accept() |
|
|
|
NamedPipeServerEndPiont nPSEndPoint = _rep->namedPipeServer->accept(); |
|
// Registerpe to receive Messages on Connection pipe: |
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
cout << " In _acceptNamedPipeConnection -- after calling namedPipeServer->accept()" << endl; |
|
} |
|
HTTPConnection* connection = new HTTPConnection(_monitor, nPSEndPoint, |
|
this, static_cast<MessageQueue *>(_outputMessageQueue), _exportConnection); |
|
|
|
/* NOT SURE WHAT TO DO HERE .... |
|
if (socketAcceptStatus == 0) |
|
{ |
|
PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, |
|
"HTTPAcceptor: SSL_accept() pending"); |
|
connection->_acceptPending = true; |
|
} |
|
|
|
*/ |
|
|
|
// Solicit events on this new connection's socket: |
|
int index; |
|
|
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
cout << endl << connection->getNamedPipe().getName() << " has a this as a QueueID " << |
|
connection->getQueueId() << endl; |
|
} |
|
if (-1 == (index = _monitor->solicitPipeMessages( |
|
connection->getNamedPipe(), |
|
NamedPipeMessage::READ | NamedPipeMessage::EXCEPTION, |
|
connection->getQueueId(), Monitor::ACCEPTOR)) ) |
|
{ |
|
// ATTN-DE-P2-2003100503::TODO::Need to enhance code to return |
|
// an error message to Client application. |
|
Tracer::trace(TRC_DISCARDED_DATA, Tracer::LEVEL2, |
|
"HTTPAcceptor::_acceptPipeConnection: Attempt to allocate entry in _entries table failed."); |
|
delete connection; |
|
// May have to close the PIPE here... |
|
//Socket::close(socket); |
|
return; |
|
} |
|
|
|
// Save the socket for cleanup later: |
|
connection->_entry_index = index; |
|
AutoMutex autoMut(_rep->_connection_mut); |
|
_rep->connections.append(connection); |
|
|
|
{ |
|
AutoMutex automut(Monitor::_cout_mut); |
|
PEGASUS_STD(cout) |
|
<< "in HTTPAcceptor::_acceptNamedPipeConnection() at the end" << PEGASUS_STD(endl); |
|
} |
|
|
|
} |
|
#endif |
|
|
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |