Skip to content

Commit

Permalink
feat(http): add function url_decode and http_get_param_str
Browse files Browse the repository at this point in the history
  • Loading branch information
eeff committed May 20, 2022
1 parent 8dbe8bb commit 68c91a9
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
31 changes: 31 additions & 0 deletions plugins/restful/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ static int response(nng_aio *aio, char *content, enum nng_http_status status)
return 0;
}

ssize_t url_decode(const char *s, size_t len, char *buf, size_t size)
{
size_t i = 0, j = 0;
int c = 0, n = 0;
while (i < len && j < size) {
c = s[i++];
if ('+' == c) {
c = ' ';
} else if ('%' == c) {
if (i + 2 > len || !sscanf(s + i, "%2x%n", &c, &n) || 2 != n) {
return -1;
}
i += 2, n = 0;
}
buf[j++] = c;
}
buf[(j < size) ? j : --j] = '\0';
return j;
}

const char *http_get_header(nng_aio *aio, char *name)
{
nng_http_req *req = nng_aio_get_input(aio, 0);
Expand Down Expand Up @@ -153,6 +173,17 @@ const char *http_get_param(nng_aio *aio, const char *name, size_t *len)
return val;
}

ssize_t http_get_param_str(nng_aio *aio, const char *name, char *buf,
size_t size)
{
size_t len = 0;
const char *s = http_get_param(aio, name, &len);
if (NULL == s) {
return -2;
}
return url_decode(s, len, buf, size);
}

int http_get_param_uintmax(nng_aio *aio, const char *name, uintmax_t *param)
{
size_t len = 0;
Expand Down
13 changes: 13 additions & 0 deletions plugins/restful/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
extern "C" {
#endif

// Decode url encoded string.
// Return -1 if decode fails, otherwise return the number of bytes written to
// `buf` excluding the terminating NULL byte. A return value of `size` indicates
// buffer overflow.
ssize_t url_decode(const char *s, size_t len, char *buf, size_t size);

int http_get_body(nng_aio *aio, void **data, size_t *data_size);

// Find query parameter value of the given name.
Expand All @@ -47,6 +53,13 @@ int http_get_body(nng_aio *aio, void **data, size_t *data_size);
// touch len.
const char *http_get_param(nng_aio *aio, const char *name, size_t *len);

// Get query parameter as url decoded string.
// Return -2 if param does not exist, -1 if url decode fail, otherwise return
// the number of bytes written to `buf` excluding the terminating NULL byte. A
// return value of `size` indicates buffer overflow.
ssize_t http_get_param_str(nng_aio *aio, const char *name, char *buf,
size_t size);

// Returns 0 on success.
// On failure returns
// NEU_ERR_ENOENT if no query parameter named `name`.
Expand Down
37 changes: 37 additions & 0 deletions tests/http_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,43 @@ TEST(HTTPTest, http_get_param)
nng_url_free(url);
}

TEST(HTTPTest, http_get_param_str)
{
nng_aio * aio = NULL;
nng_http_req *req = NULL;
nng_url * url = NULL;
ssize_t ret = 0;

char buf[256] = { 0 };
nng_aio_alloc(&aio, NULL, NULL);
nng_url_parse(&url, "http://127.0.0.1");
nng_http_req_alloc(&req, url);
nng_aio_set_input(aio, 0, req);

nng_http_req_set_uri(req, "/?node_id");
ret = http_get_param_str(aio, "group", buf, sizeof(buf));
EXPECT_EQ(ret, -2);

nng_http_req_set_uri(req, "/?group");
ret = http_get_param_str(aio, "group", buf, sizeof(buf));
EXPECT_EQ(ret, 0);
EXPECT_EQ(0, strcmp("", buf));

nng_http_req_set_uri(req, "/?group=%EZ%BB%84");
ret = http_get_param_str(aio, "group", buf, 3);
EXPECT_EQ(ret, -1);
EXPECT_EQ(0, strcmp("", buf));

nng_http_req_set_uri(req, "/?group=%E7%BB%84");
ret = http_get_param_str(aio, "group", buf, 4);
EXPECT_EQ(ret, 3);
EXPECT_EQ(0, strcmp("", buf));

nng_aio_free(aio);
nng_http_req_free(req);
nng_url_free(url);
}

TEST(HTTPTest, http_get_param_node_id)
{
nng_aio * aio = NULL;
Expand Down

0 comments on commit 68c91a9

Please sign in to comment.