📄 httpacceptor.cpp
字号:
if (getsockname(_rep->socket, reinterpret_cast<sockaddr *>(&buf), &bufSize) == 0 ) { _portNumber = ntohs(buf.sin_port); } } // // Change permissions on Linux local domain socket to allow writes by // others. //#if !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) && \ (defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \ defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)) if (_localConnection) { if (::chmod(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH ) < 0 ) { Socket::close(_rep->socket); delete _rep; _rep = 0; MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET", "Failed to bind socket"); PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor::_bind: Failed to set domain socket " "permissions."); throw BindFailedException(parms); } }#endif // Set up listening on the given socket: //int const MAX_CONNECTION_QUEUE_LENGTH = 15; if (listen(_rep->socket, MAX_CONNECTION_QUEUE_LENGTH) < 0) { Socket::close(_rep->socket); delete _rep; _rep = 0; MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_BIND_SOCKET", "Failed to bind socket"); PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor::_bind: Failed to bind socket(1)."); throw BindFailedException(parms); } // Register to receive SocketMessages on this socket: if (-1 == ( _entry_index = _monitor->solicitSocketMessages( _rep->socket, SocketMessage::READ | SocketMessage::EXCEPTION, getQueueId(), Monitor::ACCEPTOR))) { Socket::close(_rep->socket); delete _rep; _rep = 0; 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); }}/** closeConnectionSocket - close the server listening socket to disallow new client connections.*/void HTTPAcceptor::closeConnectionSocket(){ if (_rep) { // unregister the socket // ATTN - comment out - see CIMServer::stopClientConnection() //_monitor->unsolicitSocketMessages(_rep->socket); // close the socket Socket::close(_rep->socket); // Unlink Local Domain Socket Bug# 3312 if (_localConnection) {#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 } } else { PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor::closeConnectionSocket failure _rep is null."); }}/** reopenConnectionSocket - creates a new server socket.*/void HTTPAcceptor::reopenConnectionSocket(){ if (_rep) { _bind(); } else { PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor::reopenConnectionSocket failure _rep is null."); }}/** reconnectConnectionSocket - creates a new server socket.*/void HTTPAcceptor::reconnectConnectionSocket(){ if (_rep) { // unregister the socket _monitor->unsolicitSocketMessages(_rep->socket); // close the socket Socket::close(_rep->socket); // Unlink Local Domain Socket Bug# 3312 if (_localConnection) {#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET PEG_TRACE_STRING(TRC_HTTP, Tracer::LEVEL2, "HTTPAcceptor::reconnectConnectionSocket Unlinking local " "connection." ); ::unlink( reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);#else PEGASUS_ASSERT(false);#endif } // open the socket _bind(); } else { PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor::reconnectConnectionSocket failure _rep is null."); }}/** getOutstandingRequestCount - returns the number of outstanding requests.*/Uint32 HTTPAcceptor::getOutstandingRequestCount() const{ Uint32 count = 0; if (_rep) { AutoMutex autoMut(_rep->_connection_mut); if (_rep->connections.size() > 0) { HTTPConnection* connection = _rep->connections[0]; count = connection->getRequestCount(); } } return count;}/** getPortNumber - returns the port number used for the connection*/Uint32 HTTPAcceptor::getPortNumber() const{ return _portNumber;}void HTTPAcceptor::setSocketWriteTimeout(Uint32 socketWriteTimeout){ _socketWriteTimeout = socketWriteTimeout;}void HTTPAcceptor::unbind(){ if (_rep) { _portNumber = 0; Socket::close(_rep->socket); if (_localConnection) {#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET ::unlink( reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path);#else PEGASUS_ASSERT(false);#endif } delete _rep; _rep = 0; } else { PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor::unbind failure _rep is null." ); }}void HTTPAcceptor::destroyConnections(){ if (_rep) { // For each connection created by this object: AutoMutex autoMut(_rep->_connection_mut); for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++) { HTTPConnection* connection = _rep->connections[i]; SocketHandle socket = connection->getSocket(); // Unsolicit SocketMessages: _monitor->unsolicitSocketMessages(socket); // Destroy the connection (causing it to close): while (connection->refcount.get()) { } delete connection; } _rep->connections.clear(); }}void HTTPAcceptor::_acceptConnection(){ // This function cannot be called on an invalid socket! PEGASUS_ASSERT(_rep != 0); // Accept the connection (populate the address): struct sockaddr* accept_address; SocketLength address_size; if (_localConnection) {#ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_un); address_size = sizeof(struct sockaddr_un);#else PEGASUS_ASSERT(false);#endif } else { accept_address = reinterpret_cast<struct sockaddr*>(new struct sockaddr_in); address_size = sizeof(struct sockaddr_in); } SocketHandle socket = accept(_rep->socket, accept_address, &address_size); if (socket == PEGASUS_SOCKET_ERROR) { // the remote connection is invalid, destroy client address. delete accept_address; // TCPIP is down reconnect this acceptor if (getSocketError() == PEGASUS_NETWORK_TCPIP_STOPPED) { PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "Socket has an IO error. TCP/IP down. Try to reconnect."); reconnectConnectionSocket(); return; } Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE, "HTTPAcceptor - accept() failure. errno: $0", errno); PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor: accept() failed"); return; } String ipAddress; if (_localConnection) { ipAddress = "localhost"; } else { unsigned char* sa = reinterpret_cast<unsigned char*>( &reinterpret_cast<struct sockaddr_in*>( accept_address)->sin_addr.s_addr); char ipBuffer[32]; sprintf(ipBuffer, "%u.%u.%u.%u", sa[0], sa[1], sa[2], sa[3]); ipAddress = ipBuffer; } delete accept_address;// set the close on exec flag#if !defined(PEGASUS_OS_TYPE_WINDOWS) && !defined(PEGASUS_OS_VMS) int sock_flags; if ((sock_flags = fcntl(socket, F_GETFD, 0)) < 0) { PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor: fcntl(F_GETFD) failed"); } else { sock_flags |= FD_CLOEXEC; if (fcntl(socket, F_SETFD, sock_flags) < 0) { PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor: fcntl(F_SETFD) failed"); } }#endif PEG_LOGGER_TRACE((Logger::STANDARD_LOG, System::CIMSERVER, 0, "HTTPAcceptor - accept() success. Socket: $1" ,socket)); AutoPtr<MP_Socket> mp_socket(new MP_Socket( socket, _sslcontext, _sslContextObjectLock)); mp_socket->setSocketWriteTimeout(_socketWriteTimeout); // 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. mp_socket->disableBlocking(); Sint32 socketAcceptStatus = mp_socket->accept(); mp_socket->enableBlocking(); if (socketAcceptStatus < 0) { PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2, "HTTPAcceptor: SSL_accept() failed"); mp_socket->close(); return; } // Create a new connection and add it to the connection list: HTTPConnection* connection = new HTTPConnection(_monitor, mp_socket, ipAddress, this, static_cast<MessageQueue *>(_outputMessageQueue)); 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; if (-1 == (index = _monitor->solicitSocketMessages( connection->getSocket(), SocketMessage::READ | SocketMessage::EXCEPTION, connection->getQueueId(), Monitor::CONNECTION)) ) { // 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::_acceptConnection: Attempt to allocate entry in " "_entries table failed."); delete connection; Socket::close(socket); return; } // Save the socket for cleanup later: connection->_entry_index = index; AutoMutex autoMut(_rep->_connection_mut); _rep->connections.append(connection);}PEGASUS_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -