mirror of
https://github.com/joyieldInc/predixy.git
synced 2025-12-24 22:46:41 +08:00
supports inline command protocol for command:PING/ECHO/AUTH/SELECT
This commit is contained in:
parent
1569b57bd7
commit
345ff2c20f
@ -527,7 +527,13 @@ bool Handler::preHandleRequest(Request* req, const String& key)
|
|||||||
directResponse(req, Response::Pong);
|
directResponse(req, Response::Pong);
|
||||||
} else {
|
} else {
|
||||||
ResponsePtr res = ResponseAlloc::create();
|
ResponsePtr res = ResponseAlloc::create();
|
||||||
res->setStr(key.data(), key.length());
|
if (req->isInline()) {
|
||||||
|
SString<Const::MaxKeyLen> k;
|
||||||
|
RequestParser::decodeInlineArg(k, key);
|
||||||
|
res->setStr(k.data(), k.length());
|
||||||
|
} else {
|
||||||
|
res->setStr(key.data(), key.length());
|
||||||
|
}
|
||||||
handleResponse(nullptr, req, res);
|
handleResponse(nullptr, req, res);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1400,10 +1406,14 @@ bool Handler::permission(Request* req, const String& key, Response::GenericCode&
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (req->type() == Command::Auth) {
|
if (req->type() == Command::Auth) {
|
||||||
|
SString<Const::MaxKeyLen> pw;
|
||||||
|
if (req->isInline()) {
|
||||||
|
RequestParser::decodeInlineArg(pw, key);
|
||||||
|
}
|
||||||
auto m = mProxy->authority();
|
auto m = mProxy->authority();
|
||||||
if (!m->hasAuth()) {
|
if (!m->hasAuth()) {
|
||||||
code = Response::NoPasswordSet;
|
code = Response::NoPasswordSet;
|
||||||
} else if (auto auth = m->get(key)) {
|
} else if (auto auth = m->get(req->isInline() ? pw : key)) {
|
||||||
c->setAuth(auth);
|
c->setAuth(auth);
|
||||||
code = Response::Ok;
|
code = Response::Ok;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -57,6 +57,7 @@ Request::Request():
|
|||||||
mType(Command::None),
|
mType(Command::None),
|
||||||
mDone(false),
|
mDone(false),
|
||||||
mDelivered(false),
|
mDelivered(false),
|
||||||
|
mInline(false),
|
||||||
mFollowers(0),
|
mFollowers(0),
|
||||||
mFollowersDone(0),
|
mFollowersDone(0),
|
||||||
mRedirectCnt(0),
|
mRedirectCnt(0),
|
||||||
@ -70,6 +71,7 @@ Request::Request(AcceptConnection* c):
|
|||||||
mType(Command::None),
|
mType(Command::None),
|
||||||
mDone(false),
|
mDone(false),
|
||||||
mDelivered(false),
|
mDelivered(false),
|
||||||
|
mInline(false),
|
||||||
mFollowers(0),
|
mFollowers(0),
|
||||||
mFollowersDone(0),
|
mFollowersDone(0),
|
||||||
mRedirectCnt(0),
|
mRedirectCnt(0),
|
||||||
@ -82,6 +84,7 @@ Request::Request(GenericCode code):
|
|||||||
mConn(nullptr),
|
mConn(nullptr),
|
||||||
mDone(false),
|
mDone(false),
|
||||||
mDelivered(false),
|
mDelivered(false),
|
||||||
|
mInline(false),
|
||||||
mFollowers(0),
|
mFollowers(0),
|
||||||
mFollowersDone(0),
|
mFollowersDone(0),
|
||||||
mRedirectCnt(0),
|
mRedirectCnt(0),
|
||||||
@ -164,6 +167,7 @@ void Request::set(const RequestParser& p, Request* leader)
|
|||||||
mReq = p.request();
|
mReq = p.request();
|
||||||
}
|
}
|
||||||
mKey = p.key();
|
mKey = p.key();
|
||||||
|
mInline = p.isInline();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Request::setAuth(const String& password)
|
void Request::setAuth(const String& password)
|
||||||
|
|||||||
@ -129,6 +129,10 @@ public:
|
|||||||
{
|
{
|
||||||
return mDelivered;
|
return mDelivered;
|
||||||
}
|
}
|
||||||
|
bool isInline() const
|
||||||
|
{
|
||||||
|
return mInline;
|
||||||
|
}
|
||||||
void setDelivered()
|
void setDelivered()
|
||||||
{
|
{
|
||||||
mDelivered = true;
|
mDelivered = true;
|
||||||
@ -163,6 +167,7 @@ private:
|
|||||||
ResponsePtr mRes;
|
ResponsePtr mRes;
|
||||||
bool mDone;
|
bool mDone;
|
||||||
bool mDelivered;
|
bool mDelivered;
|
||||||
|
bool mInline;
|
||||||
Segment mHead; //for multi key command mget/mset/del...
|
Segment mHead; //for multi key command mget/mset/del...
|
||||||
Segment mReq;
|
Segment mReq;
|
||||||
Segment mKey;
|
Segment mKey;
|
||||||
|
|||||||
@ -25,6 +25,8 @@ void RequestParser::reset()
|
|||||||
mStatus = Normal;
|
mStatus = Normal;
|
||||||
mState = Idle;
|
mState = Idle;
|
||||||
mInline = false;
|
mInline = false;
|
||||||
|
mEscape = false;
|
||||||
|
mQuote = '\0';
|
||||||
mArgNum = 0;
|
mArgNum = 0;
|
||||||
mArgCnt = 0;
|
mArgCnt = 0;
|
||||||
mArgLen = 0;
|
mArgLen = 0;
|
||||||
@ -92,9 +94,11 @@ RequestParser::Status RequestParser::parse(Buffer* buf, int& pos, bool split)
|
|||||||
mState = InlineBegin;
|
mState = InlineBegin;
|
||||||
mInline = true;
|
mInline = true;
|
||||||
}
|
}
|
||||||
|
/* NO break */
|
||||||
case InlineBegin:
|
case InlineBegin:
|
||||||
if (ch == '\r') {
|
if (ch == '\n') {
|
||||||
error = __LINE__;
|
mState = Idle;
|
||||||
|
//error = __LINE__;
|
||||||
} else if (!isspace(ch)) {
|
} else if (!isspace(ch)) {
|
||||||
mReq.begin().buf = buf;
|
mReq.begin().buf = buf;
|
||||||
mReq.begin().pos = pos;
|
mReq.begin().pos = pos;
|
||||||
@ -107,7 +111,13 @@ RequestParser::Status RequestParser::parse(Buffer* buf, int& pos, bool split)
|
|||||||
if (isspace(ch)) {
|
if (isspace(ch)) {
|
||||||
mCmd[mArgLen < Const::MaxCmdLen ? mArgLen : Const::MaxCmdLen - 1] = '\0';
|
mCmd[mArgLen < Const::MaxCmdLen ? mArgLen : Const::MaxCmdLen - 1] = '\0';
|
||||||
parseCmd();
|
parseCmd();
|
||||||
mState = ch == '\r' ? InlineLF : InlineArg;
|
mArgCnt = 1;
|
||||||
|
if (ch == '\n') {
|
||||||
|
mArgNum = 1;
|
||||||
|
mState = Finished;
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
mState = InlineArgBegin;
|
||||||
} else {
|
} else {
|
||||||
if (mArgLen < Const::MaxCmdLen) {
|
if (mArgLen < Const::MaxCmdLen) {
|
||||||
mCmd[mArgLen] = tolower(ch);
|
mCmd[mArgLen] = tolower(ch);
|
||||||
@ -115,15 +125,64 @@ RequestParser::Status RequestParser::parse(Buffer* buf, int& pos, bool split)
|
|||||||
++mArgLen;
|
++mArgLen;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case InlineArg:
|
case InlineArgBegin:
|
||||||
if (ch == '\r') {
|
|
||||||
mState = InlineLF;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case InlineLF:
|
|
||||||
if (ch == '\n') {
|
if (ch == '\n') {
|
||||||
|
mArgNum = mArgCnt;
|
||||||
mState = Finished;
|
mState = Finished;
|
||||||
goto Done;
|
goto Done;
|
||||||
|
} else if (isspace(ch)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mArgCnt == 1) {
|
||||||
|
mKey.begin().buf = buf;
|
||||||
|
mKey.begin().pos = pos;
|
||||||
|
}
|
||||||
|
mState = InlineArg;
|
||||||
|
/* NO break */
|
||||||
|
case InlineArg:
|
||||||
|
if (mEscape) {
|
||||||
|
mEscape = false;
|
||||||
|
} else if (mQuote) {
|
||||||
|
if (ch == mQuote) {
|
||||||
|
mState = InlineArgEnd;
|
||||||
|
} else if (ch == '\\') {
|
||||||
|
mEscape = true;
|
||||||
|
} else if (ch == '\n') {
|
||||||
|
error = __LINE__;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isspace(ch)) {
|
||||||
|
if (mArgCnt == 1) {
|
||||||
|
mKey.end().buf = buf;
|
||||||
|
mKey.end().pos = pos;
|
||||||
|
}
|
||||||
|
++mArgCnt;
|
||||||
|
if (ch == '\n') {
|
||||||
|
mArgNum = mArgCnt;
|
||||||
|
mState = Finished;
|
||||||
|
goto Done;
|
||||||
|
} else {
|
||||||
|
mState = InlineArgBegin;
|
||||||
|
}
|
||||||
|
} else if (ch == '\'' || ch == '"') {
|
||||||
|
mQuote = ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case InlineArgEnd:
|
||||||
|
if (isspace(ch)) {
|
||||||
|
if (mArgCnt == 1) {
|
||||||
|
mKey.end().buf = buf;
|
||||||
|
mKey.end().pos = pos;
|
||||||
|
}
|
||||||
|
++mArgCnt;
|
||||||
|
if (ch == '\n') {
|
||||||
|
mArgNum = mArgCnt;
|
||||||
|
mState = Finished;
|
||||||
|
goto Done;
|
||||||
|
} else {
|
||||||
|
mState = InlineArgBegin;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
error = __LINE__;
|
error = __LINE__;
|
||||||
}
|
}
|
||||||
@ -405,7 +464,13 @@ void RequestParser::parseCmd()
|
|||||||
mType = c->type;
|
mType = c->type;
|
||||||
mCommand = c;
|
mCommand = c;
|
||||||
if (mInline) {
|
if (mInline) {
|
||||||
if (mType != Command::Ping) {
|
switch (mType) {
|
||||||
|
case Command::Ping:
|
||||||
|
case Command::Echo:
|
||||||
|
case Command::Auth:
|
||||||
|
case Command::Select:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
mStatus = CmdError;
|
mStatus = CmdError;
|
||||||
logNotice("unsupport command %s in inline command protocol", c->name);
|
logNotice("unsupport command %s in inline command protocol", c->name);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -19,8 +19,9 @@ public:
|
|||||||
Idle, // * or inline command
|
Idle, // * or inline command
|
||||||
InlineBegin,
|
InlineBegin,
|
||||||
InlineCmd,
|
InlineCmd,
|
||||||
InlineLF,
|
InlineArgBegin,
|
||||||
InlineArg,
|
InlineArg,
|
||||||
|
InlineArgEnd,
|
||||||
ArgNum, // 2
|
ArgNum, // 2
|
||||||
ArgNumLF, // \r\n
|
ArgNumLF, // \r\n
|
||||||
CmdTag,
|
CmdTag,
|
||||||
@ -63,6 +64,8 @@ public:
|
|||||||
~RequestParser();
|
~RequestParser();
|
||||||
Status parse(Buffer* buf, int& pos, bool split);
|
Status parse(Buffer* buf, int& pos, bool split);
|
||||||
void reset();
|
void reset();
|
||||||
|
template<int Size>
|
||||||
|
static bool decodeInlineArg(SString<Size>& dst, const String& src);
|
||||||
bool isIdle() const
|
bool isIdle() const
|
||||||
{
|
{
|
||||||
return mState == Idle;
|
return mState == Idle;
|
||||||
@ -116,6 +119,8 @@ private:
|
|||||||
Status mStatus;
|
Status mStatus;
|
||||||
State mState;
|
State mState;
|
||||||
bool mInline;
|
bool mInline;
|
||||||
|
bool mEscape;
|
||||||
|
char mQuote;
|
||||||
int mArgNum;
|
int mArgNum;
|
||||||
int mArgCnt;
|
int mArgCnt;
|
||||||
int mArgLen;
|
int mArgLen;
|
||||||
@ -123,4 +128,48 @@ private:
|
|||||||
int mByteCnt;
|
int mByteCnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<int Size>
|
||||||
|
bool RequestParser::decodeInlineArg(SString<Size>& dst, const String& src)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
bool escape = false;
|
||||||
|
char quote = '\0';
|
||||||
|
const char* p = src.data();
|
||||||
|
for (int i = 0; i < src.length(); ++i, ++p) {
|
||||||
|
char c = *p;
|
||||||
|
if (escape) {
|
||||||
|
if (quote == '"') {
|
||||||
|
switch (c) {
|
||||||
|
case 'n': c = '\n'; break;
|
||||||
|
case 'r': c = '\r'; break;
|
||||||
|
case 't': c = '\t'; break;
|
||||||
|
case 'b': c = '\b'; break;
|
||||||
|
case 'a': c = '\a'; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!dst.append('\\')) {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
escape = false;
|
||||||
|
} else if (quote) {
|
||||||
|
if (c == '\\') {
|
||||||
|
escape = true;
|
||||||
|
continue;
|
||||||
|
} else if (c == quote) {
|
||||||
|
quote = '\0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (c == '"' || c == '\'') {
|
||||||
|
quote = c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!dst.append(c)) {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user