Skip to content

Commit

Permalink
Merge pull request #172 from polycube-network/pr/add_url_enconding
Browse files Browse the repository at this point in the history
add url enconding
  • Loading branch information
frisso committed Jul 11, 2019
2 parents 811976d + 6a86e3d commit 6e4dbcc
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 10 deletions.
13 changes: 7 additions & 6 deletions src/polycubectl/cliargs/cliargs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"strconv"
"strings"
"net/url"

"os"
"bufio"
Expand Down Expand Up @@ -304,22 +305,22 @@ func ParseCLIArgs(args []string) (*CLIArgs, error) {
}

func (cli *CLIArgs) buildURL() string {
var url string
var url_str string

for _, str := range cli.PathArgs {
url += str + "/"
url_str += url.PathEscape(str) + "/"
}

if cli.IsHelp {
// TODO: is this check really needed?
if len(url) > 0 {
url = url[:len(url)-1] + cli.getHelpQueryParam()
if len(url_str) > 0 {
url_str = url_str[:len(url_str)-1] + cli.getHelpQueryParam()
} else {
url = cli.getHelpQueryParam()
url_str = cli.getHelpQueryParam()
}
}

return url
return url_str
}

func (cli *CLIArgs) buildBody() []byte {
Expand Down
22 changes: 21 additions & 1 deletion src/polycubectl/completion/polycubectl.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@ parse_yaml() {

BASE_URL_="http://localhost:9000/polycube/v1/"

# https://stackoverflow.com/a/10660730
rawurlencode() {
local string="${1}"
local strlen=${#string}
local encoded=""
local pos c o

for (( pos=0 ; pos<strlen ; pos++ )); do
c=${string:$pos:1}
case "$c" in
[-_.~a-zA-Z0-9] ) o="${c}" ;;
* ) printf -v o '%%%02x' "'$c"
esac
encoded+="${o}"
done
echo "${encoded}" # You can either set a return variable (FASTER)
#REPLY="${encoded}" #+or echo the result (EASIER)... or both... :p
#return "${encoded}"
}

_polycubectl_completions() {
if [ -a "$HOME/.config/polycube/polycubectl_config.yaml" ]
then
Expand Down Expand Up @@ -78,7 +98,7 @@ _polycubectl_completions() {
fi

#echo $X
URL0+=$X
URL0+=$(rawurlencode $X)
URL0+='/'
done

Expand Down
9 changes: 7 additions & 2 deletions src/polycubed/src/server/Resources/Endpoint/ListResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "PathParamField.h"
#include "Service.h"
#include "rest_server.h"
#include "utils/utils.h"

#include "../Data/Lib/ListResource.h"

Expand Down Expand Up @@ -113,8 +114,10 @@ std::vector<Response> ListResource::RequestValidate(
void ListResource::Keys(const Pistache::Rest::Request &request,
ListKeyValues &parsed) const {
for (const auto &k : keys_) {
std::string param_ = request.param(':' + k.Name()).as<std::string>();
std::string param = utils::decode_url(param_);
parsed.push_back(
{k.Name(), k.Type(), request.param(':' + k.Name()).as<std::string>()});
{k.Name(), k.Type(), param});
}
dynamic_cast<const ParentResource *const>(parent_)->Keys(request, parsed);
}
Expand All @@ -123,8 +126,10 @@ void ListResource::GetListKeys(const Pistache::Rest::Request &request,
ListKeyValues &parsed) const {
for (const auto &k : keys_) {
if (request.hasParam(':' + k.Name())) {
std::string param_ = request.param(':' + k.Name()).as<std::string>();
std::string param = utils::decode_url(param_);
parsed.push_back(
{k.Name(), k.Type(), request.param(':' + k.Name()).as<std::string>()});
{k.Name(), k.Type(), param});
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <memory>
#include <vector>

#include "utils/utils.h"

#include "../../Validators/EmptyValidator.h"
#include "../../Validators/ValueValidator.h"

Expand All @@ -41,7 +43,7 @@ const std::string &PathParamField::Name() const {
ErrorTag PathParamField::Validate(const Pistache::Rest::Request &value) const {
if (!value.hasParam(name_))
return kMissingElement;
const auto &param = value.param(name_).as<std::string>();
const auto &param = utils::decode_url(value.param(name_).as<std::string>());
for (const auto &validator : validators_) {
if (!validator->Validate(param))
return ErrorTag::kBadElement;
Expand Down
101 changes: 101 additions & 0 deletions src/polycubed/src/utils/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,107 @@ std::map<std::string, json> strip_port_tcubes(json &jcube) {
return cubes;
}

// taken from pistache
inline size_t to_utf8(int code, char *buff) {
if (code < 0x0080) {
buff[0] = (code & 0x7F);
return 1;
} else if (code < 0x0800) {
buff[0] = (0xC0 | ((code >> 6) & 0x1F));
buff[1] = (0x80 | (code & 0x3F));
return 2;
} else if (code < 0xD800) {
buff[0] = (0xE0 | ((code >> 12) & 0xF));
buff[1] = (0x80 | ((code >> 6) & 0x3F));
buff[2] = (0x80 | (code & 0x3F));
return 3;
} else if (code < 0xE000) { // D800 - DFFF is invalid...
return 0;
} else if (code < 0x10000) {
buff[0] = (0xE0 | ((code >> 12) & 0xF));
buff[1] = (0x80 | ((code >> 6) & 0x3F));
buff[2] = (0x80 | (code & 0x3F));
return 3;
} else if (code < 0x110000) {
buff[0] = (0xF0 | ((code >> 18) & 0x7));
buff[1] = (0x80 | ((code >> 12) & 0x3F));
buff[2] = (0x80 | ((code >> 6) & 0x3F));
buff[3] = (0x80 | (code & 0x3F));
return 4;
}

// NOTREACHED
return 0;
}

inline bool is_hex(char c, int &v) {
if (0x20 <= c && isdigit(c)) {
v = c - '0';
return true;
} else if ('A' <= c && c <= 'F') {
v = c - 'A' + 10;
return true;
} else if ('a' <= c && c <= 'f') {
v = c - 'a' + 10;
return true;
}
return false;
}

inline bool from_hex_to_i(const std::string &s, int i, int cnt, int &val) {
val = 0;
for (; cnt; i++, cnt--) {
if (!s[i]) {
return false;
}
int v = 0;
if (is_hex(s[i], v)) {
val = val * 16 + v;
} else {
return false;
}
}
return true;
}

std::string decode_url(const std::string &s) {
std::string result;

for (int i = 0; s[i]; i++) {
if (s[i] == '%') {
if (s[i + 1] && s[i + 1] == 'u') {
int val = 0;
if (from_hex_to_i(s, i + 2, 4, val)) {
// 4 digits Unicode codes
char buff[4];
size_t len = to_utf8(val, buff);
if (len > 0) {
result.append(buff, len);
}
i += 5; // 'u0000'
} else {
result += s[i];
}
} else {
int val = 0;
if (from_hex_to_i(s, i + 1, 2, val)) {
// 2 digits hex codes
result += val;
i += 2; // '00'
} else {
result += s[i];
}
}
} else if (s[i] == '+') {
result += ' ';
} else {
result += s[i];
}
}

return result;
}

} // namespace utils
} // namespace polycubed
} // namespace polycube
1 change: 1 addition & 0 deletions src/polycubed/src/utils/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace utils {
bool check_kernel_version(const std::string &version);
std::map<std::string, std::string> strip_port_peers(json &cubes);
std::map<std::string, json> strip_port_tcubes(json &jcube);
std::string decode_url(const std::string &url);

} // namespace utils
} // namespace polycubed
Expand Down

0 comments on commit 6e4dbcc

Please sign in to comment.