bool Session::processRequest(StringPiece request) { assert(command_.empty()); assert(!noreply_); assert(policy_ == Item::kInvalid); assert(!currItem_); assert(bytesToDiscard_ == 0); ++requestsProcessed_; // check 'noreply' at end of request line if (request.size() >= 8) { StringPiece end(request.end() - 8, 8); if (end == " noreply") { noreply_ = true; request.remove_suffix(8); } } SpaceSeparator sep; Tokenizer tok(request.begin(), request.end(), sep); Tokenizer::iterator beg = tok.begin(); if (beg == tok.end()) { reply("ERROR\r\n"); return true; } (*beg).CopyToString(&command_); ++beg; if (command_ == "set" || command_ == "add" || command_ == "replace" || command_ == "append" || command_ == "prepend" || command_ == "cas") { // this normally returns false return doUpdate(beg, tok.end()); } else if (command_ == "get" || command_ == "gets") { bool cas = command_ == "gets"; // FIXME: send multiple chunks with write complete callback. while (beg != tok.end()) { StringPiece key = *beg; bool good = key.size() <= kLongestKeySize; if (!good) { reply("CLIENT_ERROR bad command line format\r\n"); return true; } needle_->resetKey(key); ConstItemPtr item = owner_->getItem(needle_); ++beg; if (item) { item->output(&outputBuf_, cas); } } outputBuf_.append("END\r\n"); if (conn_->outputBuffer()->writableBytes() > 65536 + outputBuf_.readableBytes()) { LOG_DEBUG << "shrink output buffer from " << conn_->outputBuffer()->internalCapacity(); conn_->outputBuffer()->shrink(65536 + outputBuf_.readableBytes()); } conn_->send(&outputBuf_); } else if (command_ == "delete") { doDelete(beg, tok.end()); } else if (command_ == "version") { #ifdef HAVE_TCMALLOC reply("VERSION 0.01 muduo with tcmalloc\r\n"); #else reply("VERSION 0.01 muduo\r\n"); #endif } #ifdef HAVE_TCMALLOC else if (command_ == "memstat") { char buf[1024 * 64]; MallocExtension::instance()->GetStats(buf, sizeof buf); reply(buf); } #endif else if (command_ == "quit") { conn_->shutdown(); } else if (command_ == "shutdown") { // "ERROR: shutdown not enabled" conn_->shutdown(); owner_->stop(); } else { reply("ERROR\r\n"); LOG_INFO << "Unknown command: " << command_; } return true; }