Skip to content

Commit

Permalink
chore: address comments
Browse files Browse the repository at this point in the history
The test will fail - blocked on helio PR.

Signed-off-by: Roman Gershman <[email protected]>
  • Loading branch information
romange committed Mar 24, 2024
1 parent b7d996b commit 06442c1
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 15 deletions.
2 changes: 1 addition & 1 deletion helio
1 change: 0 additions & 1 deletion src/facade/reply_capture.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ class CapturingReplyBuilder : public RedisReplyBuilder {
std::vector<Payload> arr;
};

private:
private:
// Send payload directly, bypassing external interface. For efficient passing between two
// captures.
Expand Down
26 changes: 15 additions & 11 deletions src/server/http_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ using facade::CapturingReplyBuilder;

namespace {

bool IsValidReq(flexbuffers::Reference req) {
bool IsVectorOfStrings(flexbuffers::Reference req) {
if (!req.IsVector()) {
return false;
}
Expand All @@ -39,21 +39,25 @@ bool IsValidReq(flexbuffers::Reference req) {

// Escape a string so that it is legal to print it in JSON text.
std::string JsonEscape(string_view input) {
auto hex_digit = [](int c) -> char { return c < 10 ? c + '0' : c - 10 + 'a'; };
auto hex_digit = [](unsigned c) -> char {
DCHECK_LT(c, 0xFu);
return c < 10 ? c + '0' : c - 10 + 'a';
};

string out;
out.reserve(input.size() + 2);
out.push_back('\"');

auto* p = reinterpret_cast<const unsigned char*>(input.begin());
auto* e = reinterpret_cast<const unsigned char*>(input.end());
auto p = input.begin();
auto e = input.end();

while (p < e) {
if (*p == '\\' || *p == '\"') {
uint8_t c = *p;
if (c == '\\' || c == '\"') {
out.push_back('\\');
out.push_back(*p++);
} else if (*p <= 0x1f) {
switch (*p) {
} else if (c <= 0x1f) {
switch (c) {
case '\b':
out.append("\\b");
p++;
Expand All @@ -78,8 +82,8 @@ std::string JsonEscape(string_view input) {
// this condition captures non readable chars with value < 32,
// so size = 1 byte (e.g control chars).
out.append("\\u00");
out.push_back(hex_digit((*p & 0xf0) >> 4));
out.push_back(hex_digit(*p & 0xf));
out.push_back(hex_digit((c & 0xf0) >> 4));
out.push_back(hex_digit(c & 0xf));
p++;
}
} else {
Expand Down Expand Up @@ -131,7 +135,7 @@ struct CaptureVisitor {
absl::StrAppend(&str, "not_implemented");
}

void operator()(const unique_ptr<CapturingReplyBuilder::CollectionPayload>& cp) {
void operator()(unique_ptr<CapturingReplyBuilder::CollectionPayload> cp) {
if (!cp) {
absl::StrAppend(&str, "null");
return;
Expand Down Expand Up @@ -178,7 +182,7 @@ void HttpAPI(const http::QueryArgs& args, HttpRequest&& req, Service* service,
if (success) {
fbb.Finish();
doc = flexbuffers::GetRoot(fbb.GetBuffer());
if (!IsValidReq(doc)) {
if (!IsVectorOfStrings(doc)) {
success = false;
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/server/http_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,17 @@ namespace dfly {
class Service;
using HttpRequest = util::HttpListenerBase::RequestType;

/**
* @brief The main handler function for dispatching commands via HTTP.
*
* @param args - query arguments. currently not used.
* @param req - full http request including the body that should consist of a json array
* representing a Dragonfly command. aka `["set", "foo", "bar"]`
* @param service - a pointer to dfly::Service* object.
* @param http_cntxt - a pointer to the http context object which provide dragonfly context
* information via user_data() and allows to reply with HTTP responses.
*/
void HttpAPI(const util::http::QueryArgs& args, HttpRequest&& req, Service* service,
util::HttpContext* send);
util::HttpContext* http_cntxt);

} // namespace dfly
8 changes: 7 additions & 1 deletion tests/dragonfly/connection_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,9 +755,15 @@ async def test_http(df_server: DflyInstance):
async with session.get(f"http://localhost:{df_server.port}") as resp:
assert resp.status == 200

body = '["set", "foo", "bar", "ex", "100"]'
body = '["set", "foo", "МайяХилли", "ex", "100"]'
async with session.post(f"http://localhost:{df_server.port}/api", data=body) as resp:
assert resp.status == 200
text = await resp.text()
assert text.strip() == '{"result":"OK"}'

body = '["get", "foo"]'
async with session.post(f"http://localhost:{df_server.port}/api", data=body) as resp:
assert resp.status == 200
text = await resp.text()
assert text.strip() == '{"result":"МайяХилли"}'
assert await client.ttl("foo") > 0

0 comments on commit 06442c1

Please sign in to comment.