Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(http): allow generic schema and to append numbers as query parameters #951

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 38 additions & 20 deletions src/lua/zencode_http.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
--Last modified by Denis Roio
--on Saturday, 27th November 2021
--]]

local _UNRESERVED = "A-Za-z0-9%-._~"
local _GEN_DELIMS = ":/?#%[%]@"
local _SUB_DELIMS = "!$&'()*+,;="
Expand Down Expand Up @@ -126,31 +127,47 @@ local function _is_valid_host (host)
return nil
end

function is_valid_uri(uri)
local parsed = {}
local uri_pattern =
"^(%a[%w+.-]*):" .. -- Scheme
"//([^/?#]*)" .. -- Authority
"([^?#]*)" .. -- Path
"%%?([^#]*)" .. -- Query
"#?(.*)" -- Fragment
parsed.scheme, parsed.authority, parsed.path, parsed.query, parsed.fragment = uri:str():match(uri_pattern)
if parsed.scheme == "" then
error("invalid uri, missing scheme in '" .. uri .. "'", 2)
end
if parsed.authority ~= "" then
local host_error = _is_valid_host(parsed.authority)
if host_error then
error(host_error, 2)
end
end
return parsed
end

When("create url from ''", function(src)
local obj = have(src)
local url = obj:str():lower()
empty'url'
local proto
if url:sub(1,7)=='http://' then proto = 'http://' end
if url:sub(1,8)=='https://' then proto = 'https://' end
zencode_assert(proto, "Invalid http prefix in url: "..obj:str())
local toks = strtok(url, '/') -- second is the host
local res = _is_valid_host(toks[2])
zencode_assert(not res, res)
ACK.url = obj
new_codec('url',{zentype='e',content='url', encoding='string'})
local obj = have(src)
is_valid_uri(obj)
empty'url'
ACK.url = obj
new_codec('url',{zentype='e',content='url', encoding='string'})
end)

local function _append_to_url(ele, dst, encoding_f)
local arg, arg_c = have(ele)
local url, url_c = have(dst)
zencode_assert(arg_c.encoding == 'string' and luatype(arg) ~= 'table',
"Cannot append http request that are not strings: "..ele)
zencode_assert(url_c.content == 'url',
"Cannot append http request to invalid url: "..dst)
if url_c.content ~= 'url' then
error("Cannot append http request to invalid url: "..dst, 2)
end
if luatype(arg) == 'table' then
error("Cannot append table to url: "..dst, 2)
end
local separator = fif( url:str():find('?'), '&', '?' )
local tv = type(arg)
if tv == 'zenroom.time' or tv == 'zenroom.big' then
if tv == 'zenroom.time' or tv == 'zenroom.big' or tv == 'zenroom.float' then
arg = tostring(arg)
elseif tv == 'zenroom.octet' then
arg = arg:str()
Expand Down Expand Up @@ -178,13 +195,14 @@ local function _get_parameters_from_table(table_params, encoding_f)
if(params_c.zentype ~= 'd') then
error("Expected dictionary, found "..params_c.zentype.." for "..table_params, 2)
end
if(params_c.encoding ~= 'string') then
error("Parameters in "..table_params.." must be strings", 2)
if( params_c.encoding ~= 'string' and params_c.encoding ~= 'float' and
params_c.encoding ~= 'integer' and params_c.encoding ~= 'time') then
error("Parameters in "..table_params.." must be of type 'string', 'float', 'integer' or 'time'", 2)
end
local res = ""
for k,v in pairs(params) do
local tv = type(v)
if tv == 'zenroom.time' or tv == 'zenroom.big' then
if tv == 'zenroom.time' or tv == 'zenroom.big' or tv == 'zenroom.float' then
v = tostring(v)
elseif tv == 'zenroom.octet' then
v = v:str()
Expand Down
47 changes: 41 additions & 6 deletions test/zencode/http.bats
Original file line number Diff line number Diff line change
Expand Up @@ -219,26 +219,28 @@ EOF
assert_output '{"empty_get_parameters":"","get_parameters_with_percent_endoing":"client_id=did%3Adyne%3Asandbox.signroom%3APTDvvQn1iWQiVxkfsDnUid8FbieKbHq46Qs8c9CZx67&code=eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJlYWMyMjNmOTMwYmRkNzk1NDdlNzI2ZGRjZTg5ZTlmYTA1NWExZTFjIiwiaWF0IjoxNzA5MDQ4MzkzMjk1LCJpc3MiOiJodHRwczovL3ZhbGlkLmlzc3Vlci51cmwiLCJhdWQiOiJkaWQ6ZHluZTpzYW5kYm94LmdlbmVyaWNpc3N1ZXI6NkNwOG1QVXZKbVFhTXhRUFNuTnloYjc0ZjlHYTRXcWZYQ2tCbmVGZ2lrbTUiLCJleHAiOjE3MDkwNTE5OTN9.TahF8CqDDj5yynvtvkhr-Gt6RjzHSvKMosOhFf5sVmWGohKBPMNFhI8WlBlWj7aRauXB0lsvbQk03lf4eZN-2g&redirectUris=https%3A%2F%2Fdidroom.com%2F&grant_type=authorization_code&code_verifier=JYTDgtxcjiNqa3AvJjfubMX6gx98-wCH7iTydBYAeFg","get_parameters_without_percent_endoing":"client_id=did:dyne:sandbox.signroom:PTDvvQn1iWQiVxkfsDnUid8FbieKbHq46Qs8c9CZx67&code=eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJlYWMyMjNmOTMwYmRkNzk1NDdlNzI2ZGRjZTg5ZTlmYTA1NWExZTFjIiwiaWF0IjoxNzA5MDQ4MzkzMjk1LCJpc3MiOiJodHRwczovL3ZhbGlkLmlzc3Vlci51cmwiLCJhdWQiOiJkaWQ6ZHluZTpzYW5kYm94LmdlbmVyaWNpc3N1ZXI6NkNwOG1QVXZKbVFhTXhRUFNuTnloYjc0ZjlHYTRXcWZYQ2tCbmVGZ2lrbTUiLCJleHAiOjE3MDkwNTE5OTN9.TahF8CqDDj5yynvtvkhr-Gt6RjzHSvKMosOhFf5sVmWGohKBPMNFhI8WlBlWj7aRauXB0lsvbQk03lf4eZN-2g&redirectUris=https://didroom.com/&grant_type=authorization_code&code_verifier=JYTDgtxcjiNqa3AvJjfubMX6gx98-wCH7iTydBYAeFg"}'
}

@test "create a GET parameters from a with big and time" {
cat <<EOF | save_asset append_different_values.data
@test "create a GET parameters from a with big, time and numbers" {
cat <<EOF | save_asset create_get_parameters.data
{
"param1": "value1",
"param2": "1000",
"param3": 2000
"param3": 2000,
"param4": 3000
}
EOF
cat <<EOF | zexe append_different_values.zen append_different_values.data
cat <<EOF | zexe create_get_parameters.zen create_get_parameters.data
Scenario 'http': create a GET request concatenating values on a HTTP url

# the parameters are loaded as string dictionary
Given I have a 'string' named 'param1'
Given I have a 'integer' named 'param2'
Given I have a 'time' named 'param3'
Given I have a 'number' named 'param4'

When I create the 'string dictionary' named 'parameters'
and I copy 'param1' in 'parameters'
and I copy 'param2' in 'parameters'
and I copy 'param3' in 'parameters'
and I copy 'param4' in 'parameters'

# create the get parameters string
When I create the http get parameters from 'parameters'
Expand All @@ -248,7 +250,40 @@ and I rename 'http_get_parameters' to 'get_parameters_with_percent_endoing'

Then print the 'get_parameters_without_percent_endoing'
and print the 'get_parameters_with_percent_endoing'
EOF
save_output 'create_get_parameters.json'
assert_output '{"get_parameters_with_percent_endoing":"param4=3000&param2=1000&param3=2000&param1=value1","get_parameters_without_percent_endoing":"param4=3000&param2=1000&param3=2000&param1=value1"}'
}

@test "append to a url strings, big, time and numbers" {
cat <<EOF | zexe append_different_values.zen create_get_parameters.data
Scenario 'http': create a GET request concatenating values on a HTTP url

Given I have a 'string' named 'param1'
Given I have a 'integer' named 'param2'
Given I have a 'time' named 'param3'
Given I have a 'number' named 'param4'

When I set 'string_url' to 'openid-credential-issuer://www.example.com' as 'string'
and I create the url from 'string_url'
and I copy 'url' to 'another_url'

# no encoding
When I append 'param1' as http request to 'url'
When I append 'param2' as http request to 'url'
When I append 'param3' as http request to 'url'
When I append 'param4' as http request to 'url'

# percent encoding
When I append percent encoding of 'param1' as http request to 'another_url'
When I append percent encoding of 'param2' as http request to 'another_url'
When I append percent encoding of 'param3' as http request to 'another_url'
When I append percent encoding of 'param4' as http request to 'another_url'


Then print the 'url'
and print the 'another_url'
EOF
save_output 'append_different_values.json'
assert_output '{"get_parameters_with_percent_endoing":"param2=1000&param3=2000&param1=value1","get_parameters_without_percent_endoing":"param2=1000&param3=2000&param1=value1"}'
assert_output '{"another_url":"openid-credential-issuer://www.example.com?param1=value1&param2=1000&param3=2000&param4=3000","url":"openid-credential-issuer://www.example.com?param1=value1&param2=1000&param3=2000&param4=3000"}'
}
Loading