예제 #1
0
bool HTTPSession::ParseRequest(HTTPRequest& request, ReadBuffer& cmd, UrlParam& params)
{
    char*       qmark;
    ReadBuffer  rb;
    ReadBuffer  jsonCallback;
    ReadBuffer  mimeType;
    ReadBuffer  origin;
    
    // TODO: when adding keep-alive HTTP sessions, move this to an Init() function
    isFlushed = false;
    
    uri = request.line.uri;
    rb = request.line.uri;
    if (rb.GetCharAt(0) == '/')
        rb.Advance(1);
    
    mimeType.Reset();
    ParseType(rb);
    cmd = rb;

    qmark = NULL;
    if (rb.GetLength() > 0)
        qmark = FindInBuffer(rb.GetBuffer(), rb.GetLength() - 1, '?');

    if (qmark)
    {
        rb.Advance((unsigned) (qmark - rb.GetBuffer() + 1));
        params.Init(rb.GetBuffer(), rb.GetLength(), '&');
        cmd.SetLength((unsigned) (qmark - cmd.GetBuffer()));
        
        if (type == JSON)
        {
            HTTP_GET_OPT_PARAM(params, "callback", jsonCallback);
            json.SetCallbackPrefix(jsonCallback);
        }
        
        // mime type is overridable
        HTTP_GET_OPT_PARAM(params, "mimetype", mimeType);
        if (mimeType.GetLength() != 0)
            conn->SetContentType(mimeType);
            
        // CORS support
        // http://www.w3.org/TR/cors/
        HTTP_GET_OPT_PARAM(params, "origin", origin);
    }
    
    return true;
}
예제 #2
0
void ContextTransport::OnMessage(uint64_t nodeID, ReadBuffer msg)
{
    int         nread;
    char        proto;
    
    Log_Trace("%R", &msg);
    
    if (msg.GetLength() < 2)
        ASSERT_FAIL();

    nread = msg.Readf("%c:", &proto);
    if (nread < 2)
        ASSERT_FAIL();

    msg.Advance(2);
    
    switch (proto)
    {
        case PROTOCOL_CLUSTER:
            OnClusterMessage(nodeID, msg);
            break;
        case PROTOCOL_QUORUM:
            OnQuorumMessage(nodeID, msg);
            break;
        default:
            ASSERT_FAIL();
            break;
    }
}
예제 #3
0
void HTTPSession::ParseType(ReadBuffer& rb)
{
    const char  JSON_PREFIX[] = "json/";
    const char  HTML_PREFIX[] = "html/";
    
    if (HTTP_MATCH_PREFIX(rb, JSON_PREFIX))
    {
        SetType(JSON);
        rb.Advance(sizeof(JSON_PREFIX) - 1);
    }
    else if (HTTP_MATCH_PREFIX(rb, HTML_PREFIX))
    {
        SetType(HTML);
        rb.Advance(sizeof(HTML_PREFIX) - 1);
    }
    else
        SetType(PLAIN);
}
예제 #4
0
void ContextTransport::OnQuorumMessage(uint64_t nodeID, ReadBuffer& msg)
{
    int             nread;
    uint64_t        quorumID;
    QuorumContext*  quorumContext;

    nread = msg.Readf("%U:", &quorumID);
    if (nread < 2)
        ASSERT_FAIL();
    
    msg.Advance(nread);

    quorumContext = GetQuorumContext(quorumID);
    
    if (quorumContext)
        GetQuorumContext(quorumID)->OnMessage(nodeID, msg);
}
예제 #5
0
bool HTTPSession::RedirectLocalhost(HTTPConnection *conn, HTTPRequest &request)
{
    ReadBuffer  host;

    // fix Windows 7 IPv6 localhost name resolution issue
    host = request.header.GetField(HTTP_HEADER_HOST);
    if (host.BeginsWith("localhost"))
    {
        ReadBuffer  userAgent;
        Buffer      newHost;
        Buffer      ha;
        unsigned    i;
        int         pos;
        
        userAgent = request.header.GetField(HTTP_HEADER_USER_AGENT);
        pos = userAgent.Find(WINDOWS_NT_USER_AGENT);
        if (pos < 0)
            return false;

        newHost.Write("127.0.0.1");
        for (i = 0; i < host.GetLength(); i++)
        {
            if (host.GetCharAt(i) == ':')
            {
                host.Advance(i);
                newHost.Append(host);
                break;
            }
        }
        ha.Writef(HTTP_HEADER_LOCATION ": http://%B%R" HTTP_CS_CRLF, &newHost, &request.line.uri);
	    ha.NullTerminate();
		conn->ResponseHeader(HTTP_STATUS_CODE_TEMPORARY_REDIRECT, true, ha.GetBuffer());
        conn->Flush(true);
		return true;
    }

    return false;
}
예제 #6
0
bool ConfigMessage::Read(ReadBuffer& buffer)
{
    int         read;
    unsigned    numNodes, i;
    uint64_t    nodeID_;
    ReadBuffer  rb;
        
    if (buffer.GetLength() < 1)
        return false;
    
    switch (buffer.GetCharAt(0))
    {
        // Cluster management
        case CONFIGMESSAGE_SET_CLUSTER_ID:
            read = buffer.Readf("%c:%U",
             &type, &clusterID);
             break;
        case CONFIGMESSAGE_REGISTER_SHARDSERVER:
            read = buffer.Readf("%c:%U:%#R",
             &type, &nodeID, &rb);
            endpoint.Set(rb);
            break;
        case CONFIGMESSAGE_UNREGISTER_SHARDSERVER:
            read = buffer.Readf("%c:%U",
             &type, &nodeID);
            break;
        case CONFIGMESSAGE_CREATE_QUORUM:
            read = buffer.Readf("%c:%#R:%u",
             &type, &name, &numNodes);
             if (read < 0 || read == (signed)buffer.GetLength())
                return false;
            buffer.Advance(read);
            for (i = 0; i < numNodes; i++)
            {
                read = buffer.Readf(":%U", &nodeID_);
                if (read < 0)
                    return false;
                buffer.Advance(read);
                nodes.Append(nodeID_);
            }
            if (buffer.GetLength() == 0)
                return true;
            else
                return false;
            break;
        case CONFIGMESSAGE_RENAME_QUORUM:
            read = buffer.Readf("%c:%U:%#R",
             &type, &quorumID, &name);
            break;
        case CONFIGMESSAGE_DELETE_QUORUM:
            read = buffer.Readf("%c:%U",
             &type, &quorumID);
            break;
        case CONFIGMESSAGE_ADD_SHARDSERVER_TO_QUORUM:
            read = buffer.Readf("%c:%U:%U",
             &type, &quorumID, &nodeID);
            break;
        case CONFIGMESSAGE_REMOVE_SHARDSERVER_FROM_QUORUM:
            read = buffer.Readf("%c:%U:%U",
             &type, &quorumID, &nodeID);
            break;
        case CONFIGMESSAGE_ACTIVATE_SHARDSERVER:
            read = buffer.Readf("%c:%U:%U",
             &type, &quorumID, &nodeID);
            break;
        case CONFIGMESSAGE_DEACTIVATE_SHARDSERVER:
            read = buffer.Readf("%c:%U:%U",
             &type, &quorumID, &nodeID);
            break;

        // Database management
        case CONFIGMESSAGE_CREATE_DATABASE:
            read = buffer.Readf("%c:%#R",
             &type, &name);
            break;
        case CONFIGMESSAGE_RENAME_DATABASE:
            read = buffer.Readf("%c:%U:%#R",
             &type, &databaseID, &name);
            break;
        case CONFIGMESSAGE_DELETE_DATABASE:
            read = buffer.Readf("%c:%U", 
            &type, &databaseID);
            break;

        // Table management
        case CONFIGMESSAGE_CREATE_TABLE:
            read = buffer.Readf("%c:%U:%U:%#R",
             &type, &databaseID, &quorumID, &name);
            break;
        case CONFIGMESSAGE_RENAME_TABLE:
            read = buffer.Readf("%c:%U:%#R",
             &type, &tableID, &name);
            break;
        case CONFIGMESSAGE_DELETE_TABLE:
            read = buffer.Readf("%c:%U",
             &type, &tableID);
            break;
        case CONFIGMESSAGE_TRUNCATE_TABLE_BEGIN:
            read = buffer.Readf("%c:%U",
             &type, &tableID);
            break;
        case CONFIGMESSAGE_TRUNCATE_TABLE_COMPLETE:
            read = buffer.Readf("%c:%U",
             &type, &tableID);
            break;
        case CONFIGMESSAGE_FREEZE_TABLE:
            read = buffer.Readf("%c:%U",
             &type, &tableID);
            break;
        case CONFIGMESSAGE_UNFREEZE_TABLE:
            read = buffer.Readf("%c:%U",
             &type, &tableID);
            break;

        // Shard management
        case CONFIGMESSAGE_SPLIT_SHARD_BEGIN:
            read = buffer.Readf("%c:%U:%#B",
             &type, &shardID, &splitKey);
            break;
        case CONFIGMESSAGE_SPLIT_SHARD_COMPLETE:
            read = buffer.Readf("%c:%U",
             &type, &shardID);
            break;
        case CONFIGMESSAGE_SHARD_MIGRATION_BEGIN:
            read = buffer.Readf("%c:%U:%U",
             &type, &quorumID, &shardID);
            break;
        case CONFIGMESSAGE_SHARD_MIGRATION_COMPLETE:
            read = buffer.Readf("%c:%U:%U:%U",
             &type, &quorumID, &srcShardID, &dstShardID);
            break;

        default:
            return false;
    }
    
    return (read == (signed)buffer.GetLength() ? true : false);
}
예제 #7
0
bool SDBPRequestMessage::Read(ReadBuffer& buffer)
{
    int         read;
    unsigned    i, numNodes;
    uint64_t    nodeID;
    ReadBuffer  optional;

    if (buffer.GetLength() < 1)
        return false;

    switch (buffer.GetCharAt(0))
    {
    /* Master query */
    case CLIENTREQUEST_GET_MASTER:
        read = buffer.Readf("%c:%U",
                            &request->type, &request->commandID);
        break;

    /* Get config state: databases, tables, shards, quora */
    case CLIENTREQUEST_GET_CONFIG_STATE:
        read = buffer.Readf("%c:%U",
                            &request->type, &request->commandID);
        break;

    /* Quorum management */
    case CLIENTREQUEST_CREATE_QUORUM:
        read = buffer.Readf("%c:%U:%u",
                            &request->type, &request->commandID, &numNodes);
        if (read < 0 || read == (signed)buffer.GetLength())
            return false;
        buffer.Advance(read);
        for (i = 0; i < numNodes; i++)
        {
            read = buffer.Readf(":%U", &nodeID);
            if (read < 0)
                return false;
            buffer.Advance(read);
            request->nodes.Append(nodeID);
        }
        if (buffer.GetLength() == 0)
            return true;
        else
            return false;
        break;
    case CLIENTREQUEST_DELETE_QUORUM:
        read = buffer.Readf("%c:%U:%U",
                            &request->type, &request->commandID, &request->quorumID);
        break;
    case CLIENTREQUEST_ADD_NODE:
        read = buffer.Readf("%c:%U:%U:%U",
                            &request->type, &request->commandID, &request->quorumID, &request->nodeID);
        break;
    case CLIENTREQUEST_REMOVE_NODE:
        read = buffer.Readf("%c:%U:%U:%U",
                            &request->type, &request->commandID, &request->quorumID, &request->nodeID);
        break;
    case CLIENTREQUEST_ACTIVATE_NODE:
        read = buffer.Readf("%c:%U:%U",
                            &request->type, &request->commandID, &request->nodeID);
        break;

    /* Database management */
    case CLIENTREQUEST_CREATE_DATABASE:
        read = buffer.Readf("%c:%U:%#B",
                            &request->type, &request->commandID, &request->name);
        break;
    case CLIENTREQUEST_RENAME_DATABASE:
        read = buffer.Readf("%c:%U:%U:%#B",
                            &request->type, &request->commandID, &request->databaseID,
                            &request->name);
        break;
    case CLIENTREQUEST_DELETE_DATABASE:
        read = buffer.Readf("%c:%U:%U",
                            &request->type, &request->commandID, &request->databaseID);
        break;
    case CLIENTREQUEST_SPLIT_SHARD:
        read = buffer.Readf("%c:%U:%U:%#B",
                            &request->type, &request->commandID,
                            &request->shardID, &request->key);
        break;
    case CLIENTREQUEST_MIGRATE_SHARD:
        read = buffer.Readf("%c:%U:%U:%U",
                            &request->type, &request->commandID, &request->shardID, &request->quorumID);
        return true;

    /* Table management */
    case CLIENTREQUEST_CREATE_TABLE:
        read = buffer.Readf("%c:%U:%U:%U:%#B",
                            &request->type, &request->commandID, &request->databaseID,
                            &request->quorumID, &request->name);
        break;
    case CLIENTREQUEST_RENAME_TABLE:
        read = buffer.Readf("%c:%U:%U:%#B",
                            &request->type, &request->commandID,
                            &request->tableID, &request->name);
        break;
    case CLIENTREQUEST_DELETE_TABLE:
        read = buffer.Readf("%c:%U:%U",
                            &request->type, &request->commandID,
                            &request->tableID);
        break;
    case CLIENTREQUEST_TRUNCATE_TABLE:
        read = buffer.Readf("%c:%U:%U",
                            &request->type, &request->commandID,
                            &request->tableID);
        break;

    /* Data operations */
    case CLIENTREQUEST_GET:
        read = buffer.Readf("%c:%U:%U:%U:%#B",
                            &request->type, &request->commandID,
                            &request->tableID, &request->paxosID,
                            &request->key);
        break;
    case CLIENTREQUEST_SET:
    case CLIENTREQUEST_SET_IF_NOT_EXISTS:
    case CLIENTREQUEST_GET_AND_SET:
        read = buffer.Readf("%c:%U:%U:%#B:%#B",
                            &request->type, &request->commandID,
                            &request->tableID, &request->key, &request->value);
        break;
    case CLIENTREQUEST_TEST_AND_SET:
        read = buffer.Readf("%c:%U:%U:%#B:%#B:%#B",
                            &request->type, &request->commandID,
                            &request->tableID, &request->key, &request->test, &request->value);
        break;
    case CLIENTREQUEST_TEST_AND_DELETE:
        read = buffer.Readf("%c:%U:%U:%#B:%#B",
                            &request->type, &request->commandID,
                            &request->tableID, &request->key, &request->test);
        break;
    case CLIENTREQUEST_ADD:
        read = buffer.Readf("%c:%U:%U:%#B:%I",
                            &request->type, &request->commandID,
                            &request->tableID, &request->key, &request->number);
        break;
    case CLIENTREQUEST_APPEND:
        read = buffer.Readf("%c:%U:%U:%#B:%#B",
                            &request->type, &request->commandID,
                            &request->tableID, &request->key, &request->value);
        break;
    case CLIENTREQUEST_DELETE:
    case CLIENTREQUEST_REMOVE:
        read = buffer.Readf("%c:%U:%U:%#B",
                            &request->type, &request->commandID,
                            &request->tableID, &request->key);
        break;

    case CLIENTREQUEST_LIST_KEYS:
    case CLIENTREQUEST_LIST_KEYVALUES:
    case CLIENTREQUEST_COUNT:
        read = buffer.Readf("%c:%U:%U:%#B:%#B:%#B:%U:%U",
                            &request->type, &request->commandID,
                            &request->tableID, &request->key, &request->endKey, &request->prefix,
                            &request->count, &request->offset);
        break;

    case CLIENTREQUEST_SUBMIT:
        read = buffer.Readf("%c:%U",
                            &request->type, &request->quorumID);
        break;

    case CLIENTREQUEST_BULK_LOADING:
        read = buffer.Readf("%c:%U",
                            &request->type, &request->commandID);
        break;

    default:
        return false;
    }

    return (read == (signed)buffer.GetLength() ? true : false);
}
예제 #8
0
bool ClusterMessage::Read(ReadBuffer& buffer)
{
#define READ_SEPARATOR() \
    read = buffer.Readf(":"); \
    if (read != 1) \
        return false; \
    buffer.Advance(read); \

    int             read;
    ReadBuffer      tempBuffer;
        
    if (buffer.GetLength() < 1)
        return false;
    
    switch (buffer.GetCharAt(0))
    {
        case CLUSTERMESSAGE_SET_NODEID:
            read = buffer.Readf("%c:%U:%U",
             &type, &clusterID, &nodeID);
            break;
        case CLUSTERMESSAGE_UNREGISTER_STOP:
            read = buffer.Readf("%c",
             &type);
            break;
        case CLUSTERMESSAGE_HEARTBEAT:
            read = buffer.Readf("%c:%U:%u:%u",
             &type, &nodeID, &httpPort, &sdbpPort);
            if (read < 3)
                return false;
            buffer.Advance(read);
            READ_SEPARATOR();
            if (!QuorumInfo::ReadList(buffer, quorumInfos))
                return false;
            READ_SEPARATOR();
            if (!QuorumShardInfo::ReadList(buffer, quorumShardInfos))
                return false;
            return true;
            break;
        case CLUSTERMESSAGE_SET_CONFIG_STATE:
            type = CLUSTERMESSAGE_SET_CONFIG_STATE;
            return configState.Read(buffer, true);
        case CLUSTERMESSAGE_REQUEST_LEASE:
            read = buffer.Readf("%c:%U:%U:%U:%U:%U:%u",
             &type, &nodeID, &quorumID, &proposalID, &paxosID, &configID, &duration);
            break;
        case CLUSTERMESSAGE_RECEIVE_LEASE:
            read = buffer.Readf("%c:%U:%U:%U:%U:%u:%b",
             &type, &nodeID, &quorumID, &proposalID, &configID, &duration, &watchingPaxosID);
             if (read < 9)
                return false;
            buffer.Advance(read);
            READ_SEPARATOR();
            if (!MessageUtil::ReadIDList(activeNodes, buffer))
                return false;
            READ_SEPARATOR();
            if (!MessageUtil::ReadIDList(shards, buffer))
                return false;
            return true;
        case CLUSTERMESSAGE_SHARDMIGRATION_INITIATE:
            read = buffer.Readf("%c:%U:%U:%U:%U",
             &type, &nodeID, &quorumID, &srcShardID, &dstShardID);
            break;
        case CLUSTERMESSAGE_SHARDMIGRATION_BEGIN:
            read = buffer.Readf("%c:%U:%U:%U",
             &type, &quorumID, &srcShardID, &dstShardID);
            break;
        case CLUSTERMESSAGE_SHARDMIGRATION_SET:
            read = buffer.Readf("%c:%U:%U:%#R:%#R",
             &type, &quorumID, &shardID, &key, &value);
            break;
        case CLUSTERMESSAGE_SHARDMIGRATION_DELETE:
            read = buffer.Readf("%c:%U:%U:%#R",
             &type, &quorumID, &shardID, &key);
            break;
        case CLUSTERMESSAGE_SHARDMIGRATION_COMMIT:
            read = buffer.Readf("%c:%U:%U",
             &type, &quorumID, &shardID);
            break;
        case CLUSTERMESSAGE_SHARDMIGRATION_COMPLETE:
            read = buffer.Readf("%c:%U:%U",
             &type, &quorumID, &shardID);
            break;
        case CLUSTERMESSAGE_SHARDMIGRATION_PAUSE:
            read = buffer.Readf("%c",
             &type);
            break;
        case CLUSTERMESSAGE_SHARDMIGRATION_RESUME:
            read = buffer.Readf("%c",
             &type);
            break;
        case CLUSTERMESSAGE_HELLO:
            read = buffer.Readf("%c:%U:%#R",
             &type, &clusterID, &value);
            break;
        case CLUSTERMESSAGE_HTTP_ENDPOINT:
            read = buffer.Readf("%c:%U:%#R",
             &type, &nodeID, &endpoint);
            break;
        default:
            return false;
    }
    
    return (read == (signed)buffer.GetLength());
    
#undef READ_SEPARATOR
}