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