⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpacceptor.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        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 + -