void httpconnection_on_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
  HTTPConnection* c = static_cast<HTTPConnection*>(handle->data);

  if(nread < 0) {
    int r = uv_read_stop(handle);
    if(r) {
      RX_ERROR("> error uv_read_stop: %s", uv_strerror(uv_last_error(handle->loop)));
      
    }
    if(buf.base) {
      delete buf.base;
      buf.base = NULL;
    }

    uv_err_t err = uv_last_error(handle->loop);
    if(err.code != UV_EOF) {
      RX_ERROR("> disconnected from server but not correctly: %s",uv_strerror(uv_last_error(handle->loop))) ;
    }

    r = uv_shutdown(&c->shutdown_req, handle, httpconnection_on_shutdown);
    if(r) {
      RX_ERROR("> error shutting down client: %s", uv_strerror(uv_last_error(handle->loop)));
      RX_ERROR("@ todo should be `delete` the connection here?");
    }

    return;
  }

  c->addToInputBuffer(buf.base, nread);

  if(buf.base) {
    delete[] buf.base;
    buf.base = NULL;
  }
}
int httpconnection_on_status_complete(http_parser* p) {
  HTTPConnection* c = static_cast<HTTPConnection*>(p->data);
  if(c->cb_event) {
    c->cb_event(c, HTTP_ON_STATUS, NULL, 0, c->cb_event_user);
  }  
  return 0;
}
Example #3
0
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 CIMOperationResponseEncoder::enqueue(Message* message)
{
    try
    {
        handleEnqueue(message);
    }
    catch(PEGASUS_STD(bad_alloc)&)
    {
        MessageLoaderParms parms(
            "Server.CIMOperationResponseEncoder.OUT_OF_MEMORY",
            "A System error has occurred. Please retry the CIM Operation "
                "at a later time.");

        Logger::put_l(
            Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE, parms);

        CIMResponseMessage* response =
            dynamic_cast<CIMResponseMessage*>(message);
        Uint32 queueId = response->queueIds.top();
        MessageQueue* queue = MessageQueue::lookup(queueId);
        HTTPConnection* httpQueue = dynamic_cast<HTTPConnection*>(queue);
        PEGASUS_ASSERT(httpQueue);

        // Handle internal error on this connection.
        httpQueue->handleInternalServerError(
            response->getIndex(), response->isComplete());

        delete message;
    }
}
int httpconnection_on_message_complete(http_parser* p) {
  HTTPConnection* c = static_cast<HTTPConnection*>(p->data);
  if(c->cb_event) {
    c->cb_event(c, HTTP_ON_COMPLETE, NULL, 0, c->cb_event_user);
  }
  
  return 0;
}
int httpconnection_on_body(http_parser* p, const char* at, size_t len) {

  HTTPConnection* c = static_cast<HTTPConnection*>(p->data);
  if(c->cb_event) {
    c->cb_event(c, HTTP_ON_BODY, at, len, c->cb_event_user);
  }

  return 0;
}
Example #7
0
IHTTPConnection*     HTTPConnectionManager::initConnection(Chunk *chunk)
{
    HTTPConnection *con = new HTTPConnection(this->stream);
    if ( con->init(chunk) == false )
        return NULL;
    this->chunkMap[chunk] = con;
    this->chunkCount++;
    return con;
}
Example #8
0
HTTPConnection * HTTPConnectionManager::getConnection(const std::string &hostname, uint16_t port, int sockettype)
{
    std::vector<HTTPConnection *>::const_iterator it;
    for(it = connectionPool.begin(); it != connectionPool.end(); ++it)
    {
        HTTPConnection *conn = *it;
        if(conn->isAvailable() && conn->compare(hostname, port, sockettype))
            return conn;
    }
    return NULL;
}
Example #9
0
void HTTPAcceptor::handleEnqueue(Message *message)
{
    if (!message)
       return;

    PEGASUS_ASSERT(_rep != 0);
    switch (message->getType())
    {
        case SOCKET_MESSAGE:
        {
            SocketMessage* socketMessage = (SocketMessage*)message;

            // If this is a connection request:
            PEGASUS_ASSERT(socketMessage->socket == _rep->socket);

            PEGASUS_ASSERT(socketMessage->events & SocketMessage::READ);

            _acceptConnection();

            break;
        }

       case CLOSE_CONNECTION_MESSAGE:
       {
           CloseConnectionMessage* closeConnectionMessage =
               (CloseConnectionMessage*)message;

           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();

               if (socket == closeConnectionMessage->socket)
               {
                   _monitor->unsolicitSocketMessages(socket);
                   _rep->connections.remove(i);
                   delete connection;
                   break;
               }
           }

           break;
       }

       default:
           PEGASUS_ASSERT(false);
           break;
    }

    delete message;
}
void httpconnection_on_close(uv_handle_t* handle) {
  HTTPConnection* c = static_cast<HTTPConnection*>(handle->data);

  delete handle;
  handle = NULL;

  if(c->cb_event) {
    c->cb_event(c, HTTP_ON_CLOSED, NULL, 0, c->cb_event_user);
  }
  
  if(c->cb_close) {
    c->cb_close(c, HTTP_ON_CLOSED, NULL, 0, c->cb_close_user);
  }
}
Example #11
0
/**
    getOutstandingRequestCount - returns the number of outstanding requests.
*/
Uint32 HTTPAcceptor::getOutstandingRequestCount() const
{
    Uint32 count = 0;
    if (_rep)
    {
        AutoMutex autoMut(_rep->_connection_mut);
        for (Uint32 i = 0, n = _rep->connections.size(); i < n; i++)
        {
            HTTPConnection* connection = _rep->connections[i];
            if (connection->isResponsePending())
            {
                count++;
            }
        }
    }
    return count;
}
Example #12
0
bool HTTPChunkSource::prepare()
{
    if(prepared)
        return true;

    if(!connManager)
        return false;

    ConnectionParams connparams = params; /* can be changed on 301 */

    unsigned int i_redirects = 0;
    while(i_redirects++ < HTTPConnection::MAX_REDIRECTS)
    {
        if(!connection)
        {
            connection = connManager->getConnection(connparams);
            if(!connection)
                break;
        }

        requeststatus = connection->request(connparams.getPath(), bytesRange);
        if(requeststatus != RequestStatus::Success)
        {
            if(requeststatus == RequestStatus::Redirection)
            {
                HTTPConnection *httpconn = dynamic_cast<HTTPConnection *>(connection);
                if(httpconn)
                    connparams = httpconn->getRedirection();
                connection->setUsed(false);
                connection = NULL;
                if(httpconn)
                    continue;
            }
            break;
        }

        /* Because we don't know Chunk size at start, we need to get size
               from content length */
        contentLength = connection->getContentLength();
        prepared = true;
        return true;
    }

    return false;
}
Example #13
0
HTTPConnection * HTTPConnectionManager::getConnection(const std::string &scheme,
                                                      const std::string &hostname,
                                                      uint16_t port)
{
    if((scheme != "http" && scheme != "https") || hostname.empty())
        return NULL;

    const int sockettype = (scheme == "https") ? TLSSocket::TLS : Socket::REGULAR;
    vlc_mutex_lock(&lock);
    HTTPConnection *conn = getConnection(hostname, port, sockettype);
    if(!conn)
    {
        Socket *socket = (sockettype == TLSSocket::TLS) ? new (std::nothrow) TLSSocket()
                                                        : new (std::nothrow) Socket();
        if(!socket)
        {
            vlc_mutex_unlock(&lock);
            return NULL;
        }
        /* disable pipelined tls until we have ticket/resume session support */
        conn = new (std::nothrow) HTTPConnection(stream, socket, sockettype != TLSSocket::TLS);
        if(!conn)
        {
            delete socket;
            vlc_mutex_unlock(&lock);
            return NULL;
        }

        connectionPool.push_back(conn);

        if (!conn->connect(hostname, port))
        {
            vlc_mutex_unlock(&lock);
            return NULL;
        }
    }

    conn->setUsed(true);
    vlc_mutex_unlock(&lock);
    return conn;
}
Example #14
0
HTTPConnection* HTTP::sendRequest(HTTPRequest& r,                           /* the request that we will sent */
                                  httpconnection_event_callback eventCB,    /* this function gets called when we receive data, see HTTPConnection.h */
                                  void* user,                               /* the user pointer that gets passed into `eventCB` */
                                  SSL* ssl)                                 /* pass a SSL* when you want to make a secure connection */
{

  // create request string.
  std::string request_str;
  if(!r.toString(request_str)) {
    RX_ERROR("Cannot create request string");
    return NULL;
  }

  // create connection
  HTTPConnection* c = new HTTPConnection(loop, r.getURL().getHost(), r.getURL().getPort(), ssl);
  c->cb_close = http_on_connection_event;
  c->cb_close_user = this;
  c->addToOutputBuffer(request_str);
  c->connect(eventCB, user);

  connections.push_back(c);
  return c;
}
void httpconnection_on_flush_output_buffer(const char* data, size_t len, void* user) {
  HTTPConnection* c = static_cast<HTTPConnection*>(user);
  c->send((char*)data, len);
}
/*
    Pull operation version of SendResponse.  This adds one additional
    parameter (bodyParamsIn) that contains the parameters.  This is because
    the parameters are added only on the the final segment of a chunk
*/
void CIMOperationResponseEncoder::sendResponsePull(
    CIMResponseMessage* response,
    const String& name,
    Boolean isImplicit,
    Buffer* bodyParams,
    Buffer* bodygiven)
{
    PEG_METHOD_ENTER(TRC_DISPATCHER,
        "CIMOperationResponseEncoder::sendResponse");
    PEG_TRACE((TRC_HTTP, Tracer::LEVEL4,
        "name = %s",
        (const char*)name.getCString()));

    if (! response)
    {
        PEG_METHOD_EXIT();
        return;
    }

    Uint32 queueId = response->queueIds.top();

    Boolean closeConnect = response->getCloseConnect();
    PEG_TRACE((
        TRC_HTTP,
        Tracer::LEVEL4,
        "CIMOperationResponseEncoder::sendResponse()- "
            "response->getCloseConnect() returned %d",
        closeConnect));

    MessageQueue* queue = MessageQueue::lookup(queueId);

    if (!queue)
    {
        PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
            "ERROR: non-existent queueId = %u, response not sent.", queueId));
        PEG_METHOD_EXIT();
        return;
    }

    HttpMethod httpMethod = response->getHttpMethod();
    String& messageId = response->messageId;
    CIMException& cimException = response->cimException;
    Buffer message;

    // Note: the language is ALWAYS passed empty to the xml formatters because
    // it is HTTPConnection that needs to make the decision of whether to add
    // the languages to the HTTP message.
    ContentLanguageList contentLanguage;

    CIMName cimName(name);
    Uint32 messageIndex = response->getIndex();
    Boolean isFirst = messageIndex == 0 ? true : false;
    Boolean isLast = response->isComplete();
    Buffer bodylocal;
    Buffer& body = bodygiven ? *bodygiven : bodylocal;

    Buffer& bodyParamsBuf = bodyParams ? *bodyParams : bodylocal;

    // STAT_SERVEREND sets the getTotalServerTime() value in the message class
    STAT_SERVEREND

#ifndef PEGASUS_DISABLE_PERFINST
    Uint64 serverTime = response->getTotalServerTime();
#else
    Uint64 serverTime = 0;
#endif

    Buffer (*formatResponse)(
        const CIMName& iMethodName,
        const String& messageId,
        HttpMethod httpMethod,
        const ContentLanguageList& httpContentLanguages,
        const Buffer& bodyParams,
        const Buffer& body,
        Uint64 serverResponseTime,
        Boolean isFirst,
        Boolean isLast);

    Buffer (*formatError)(
        const CIMName& methodName,
        const String& messageId,
        HttpMethod httpMethod,
        const CIMException& cimException);

    if (isImplicit == false)
    {
        formatResponse = XmlWriter::formatSimpleMethodRspMessage;
        formatError = XmlWriter::formatSimpleMethodErrorRspMessage;
    }
    else
    {
        formatError = XmlWriter::formatSimpleIMethodErrorRspMessage;

        if (response->binaryResponse)
        {
            formatResponse = BinaryCodec::formatSimpleIMethodRspMessage;
        }
        else
        {
            formatResponse = XmlWriter::formatSimpleIMethodRspMessage;
        }
    }

    if (cimException.getCode() != CIM_ERR_SUCCESS)
    {
        HTTPConnection* httpQueue = dynamic_cast<HTTPConnection*>(queue);
        Boolean isChunkRequest = false;
        Boolean isFirstError = true;

        // Note:  The WMI Mapper may use a non-HTTPConnection queue here.
        if (httpQueue)
        {
            isChunkRequest = httpQueue->isChunkRequested();
            isFirstError =
                (httpQueue->cimException.getCode() == CIM_ERR_SUCCESS);
        }

        // only process the FIRST error
        if (isFirstError)
        {
            // NOTE: even if this error occurs in the middle, HTTPConnection
            // will flush the entire queued message and reformat.
            if (isChunkRequest == false)
            {
                message =
                    formatError(name, messageId, httpMethod, cimException);
            }

            // uri encode the error (for the http header) only when it is
            // non-chunking or the first error with chunking
            if (isChunkRequest == false ||
                (isChunkRequest == true && isFirst == true))
            {
                String msg =
                    TraceableCIMException(cimException).getDescription();
                String uriEncodedMsg = XmlWriter::encodeURICharacters(msg);
                CIMException cimExceptionUri(
                    cimException.getCode(), uriEncodedMsg);
                cimExceptionUri.setContentLanguages(
                    cimException.getContentLanguages());
                cimException = cimExceptionUri;
            }
        } // if first error in response stream

        // never put the error in chunked response (because it will end up in
        // the trailer), so just use the non-error response formatter to send
        // more data

        if (isChunkRequest == true)
        {
            message = formatResponse(
                cimName,
                messageId,
                httpMethod,
                contentLanguage,
                bodyParamsBuf,
                body,
                serverTime,
                isFirst,
                isLast);
        }
    }
    else
    {
        // else non-error condition
        try
        {
            message = formatResponse(
                cimName,
                messageId,
                httpMethod,
                contentLanguage,
                bodyParamsBuf,
                body,
                serverTime,
                isFirst,
                isLast);
        }
        catch (PEGASUS_STD(bad_alloc)&)
        {
            MessageLoaderParms parms(
                "Server.CIMOperationResponseEncoder.OUT_OF_MEMORY",
                "A System error has occurred. Please retry the CIM Operation "
                    "at a later time.");

            Logger::put_l(
                Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
                parms);

            cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, parms);

            // try again with new error and no body
            body.clear();
            sendResponse(response, name, isImplicit);
            PEG_METHOD_EXIT();
            return;
        }

        STAT_BYTESSENT
    }

    AutoPtr<HTTPMessage> httpMessage(
        new HTTPMessage(message, 0, &cimException));
    httpMessage->setComplete(isLast);
    httpMessage->setIndex(messageIndex);
    httpMessage->binaryResponse = response->binaryResponse;

    if (cimException.getCode() != CIM_ERR_SUCCESS)
    {
        httpMessage->contentLanguages = cimException.getContentLanguages();
    }
    else
    {
        const OperationContext::Container& container =
            response->operationContext.get(ContentLanguageListContainer::NAME);
        const ContentLanguageListContainer& listContainer =
            *dynamic_cast<const ContentLanguageListContainer*>(&container);
        contentLanguage = listContainer.getLanguages();
        httpMessage->contentLanguages = contentLanguage;
    }

    httpMessage->setCloseConnect(closeConnect);

    queue->enqueue(httpMessage.release());

    PEG_METHOD_EXIT();
}
void WsmResponseEncoder::enqueue(WsmResponse* response)
{
    PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmResponseEncoder::enqueue()");
    PEGASUS_ASSERT(response);

    PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL4,
        "WsmResponseEncoder::enqueue()- "
            "response->getHttpCloseConnect() returned %d",
        response->getHttpCloseConnect()));

    try
    {
        switch (response->getType())
        {
            case WS_TRANSFER_GET:
                _encodeWxfGetResponse((WxfGetResponse*) response);
                break;

            case WS_TRANSFER_PUT:
                _encodeWxfPutResponse((WxfPutResponse*) response);
                break;

            case WS_TRANSFER_CREATE:
                _encodeWxfCreateResponse((WxfCreateResponse*) response);
                break;

            case WS_TRANSFER_DELETE:
                _encodeWxfDeleteResponse((WxfDeleteResponse*) response);
                break;

            case WS_ENUMERATION_RELEASE:
                _encodeWsenReleaseResponse((WsenReleaseResponse*) response);
                break;

            case WSM_FAULT:
                _encodeWsmFaultResponse((WsmFaultResponse*) response);
                break;

            case SOAP_FAULT:
                _encodeSoapFaultResponse((SoapFaultResponse*) response);
                break;

            case WS_INVOKE:
                _encodeWsInvokeResponse((WsInvokeResponse*)response);
                break;

            case WS_ENUMERATION_ENUMERATE:
            case WS_ENUMERATION_PULL:
                // These cases are handled specially to allow for the message
                // contents to be tuned according to the MaxEnvelopeSize value.
            default:
                // Unexpected message type
                PEGASUS_ASSERT(0);
                break;
        }
    }
    catch (PEGASUS_STD(bad_alloc)&)
    {
       MessageLoaderParms parms(
            "WsmServer.WsmResponseEncoder.OUT_OF_MEMORY",
            "A System error has occurred. Please retry the "
                "WS-Management operation at a later time.");

        Logger::put_l(
            Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE, parms);

        MessageQueue* queue = MessageQueue::lookup(response->getQueueId());
        HTTPConnection* httpQueue = dynamic_cast<HTTPConnection*>(queue);
        PEGASUS_ASSERT(httpQueue);

        // Handle the internal server error on this connection.
        httpQueue->handleInternalServerError(0, true);
    }

    PEG_METHOD_EXIT();
}
HTTPMessageBodyChunk::HTTPMessageBodyChunk(
  HTTPConnection& connection,
  YO_NEW_REF Buffer* data
) : yield::http::HTTPMessageBodyChunk(data),
  connection(connection.inc_ref()) {
}