Exemplo n.º 1
0
CJsonNode CReadJsonFromSocket::ReadMessage(CSocket& sock)
{
    try {
        char read_buffer[READ_BUFFER_SIZE];

        size_t bytes_read;

        do {
            s_ReadSocket(sock, read_buffer, READ_BUFFER_SIZE, &bytes_read);

            m_UTTPReader.SetNewBuffer(read_buffer, bytes_read);

        } while (!m_JSONReader.ReadMessage(m_UTTPReader));
    }
    catch (...) {
        sock.Close();
        throw;
    }

    if (m_UTTPReader.GetNextEvent() != CUTTPReader::eEndOfBuffer) {
        string server_address(sock.GetPeerAddress());
        sock.Close();
        NCBI_THROW_FMT(CNetStorageException, eIOError,
                "Extra bytes past message end while reading from " <<
                        server_address << " after receiving " <<
                        m_JSONReader.GetMessage().Repr() << '.');
    }

    return m_JSONReader.GetMessage();
}
Exemplo n.º 2
0
static void s_ReadSocket(CSocket& sock, void* buffer,
        size_t buffer_size, size_t* bytes_read)
{
    EIO_Status status;

    while ((status = sock.Read(buffer,
            buffer_size, bytes_read)) == eIO_Interrupt)
        /* no-op */;

    if (status != eIO_Success) {
        // eIO_Timeout, eIO_Closed, eIO_InvalidArg,
        // eIO_NotSupported, eIO_Unknown
        NCBI_THROW_FMT(CNetStorageException, eIOError,
                "I/O error while reading from NetStorage server " <<
                        sock.GetPeerAddress() << ". "
                "Socket status: " << IO_StatusStr(status) << '.');
    }
}
Exemplo n.º 3
0
static void s_WriteToSocket(CSocket& sock,
        const char* output_buffer, size_t output_buffer_size)
{
    size_t bytes_written;

    while (output_buffer_size > 0) {
        EIO_Status  status = sock.Write(output_buffer,
                output_buffer_size, &bytes_written);
        if (status != eIO_Success) {
            // Error writing to the socket.
            // Log what we can.
            string message_start;

            if (output_buffer_size > 32) {
                CTempString buffer_head(output_buffer, 32);
                message_start = NStr::PrintableString(buffer_head);
                message_start += " (TRUNCATED)";
            } else {
                CTempString buffer_head(output_buffer, output_buffer_size);
                message_start = NStr::PrintableString(buffer_head);
            }

            NCBI_THROW_FMT(CNetStorageException, eIOError,
                    "Error writing message to the NetStorage server " <<
                            sock.GetPeerAddress() << ". "
                    "Socket write error status: " <<
                            IO_StatusStr(status) << ". "
                    "Bytes written: " <<
                            NStr::NumericToString(bytes_written) << ". "
                    "Message begins with: " << message_start);
        }

        output_buffer += bytes_written;
        output_buffer_size -= bytes_written;
    }
}
Exemplo n.º 4
0
static void s_TrapErrors(const CJsonNode& request,
        const CJsonNode& reply, CSocket& sock,
        SNetStorage::SConfig::EErrMode err_mode)
{
    const string server_address(sock.GetPeerAddress());
    CJsonNode issues(reply.GetByKeyOrNull("Warnings"));

    if (issues) {
        for (CJsonIterator it = issues.Iterate(); it; ++it) {
            const SIssue issue(*it);
            LOG_POST(Warning << "NetStorage server " << server_address <<
                    " issued warning " << issue);
        }
    }

    const string status = reply.GetString("Status");
    const bool status_ok = status == "OK";
    issues = reply.GetByKeyOrNull("Errors");

    // Got errors
    if (!status_ok || issues) {
        if (status_ok && err_mode != SNetStorage::SConfig::eThrow) {
            if (err_mode == SNetStorage::SConfig::eLog) {
                for (CJsonIterator it = issues.Iterate(); it; ++it) {
                    const SIssue issue(*it);
                    LOG_POST(Error << "NetStorage server " << server_address <<
                            " issued error " << issue);
                }
            }
        } else {
            Int8 code = CNetStorageServerError::eUnknownError;
            Int8 sub_code = SIssue::kEmptySubCode;
            ostringstream errors;

            if (!issues)
                errors << status;
            else {
                const char* prefix = "error ";

                for (CJsonIterator it = issues.Iterate(); it; ++it) {
                    const SIssue issue(*it);
                    code = issue.code;
                    sub_code = issue.sub_code;
                    errors << prefix << issue;
                    prefix = ", error ";
                }
            }

            string err_msg = FORMAT("Error while executing " <<
                            request.GetString("Type") << " "
                    "on NetStorage server " <<
                            sock.GetPeerAddress() << ". "
                    "Server returned " << errors.str());

            s_ThrowError(code, sub_code, err_msg);
        }
    }

    if (reply.GetInteger("RE") != request.GetInteger("SN")) {
        NCBI_THROW_FMT(CNetStorageException, eServerError,
                "Message serial number mismatch "
                "(NetStorage server: " << sock.GetPeerAddress() << "; "
                "request: " << request.Repr() << "; "
                "reply: " << reply.Repr() << ").");
    }
}