Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,147 @@
|
||||
// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
import net.urllib
|
||||
|
||||
fn test_str() {
|
||||
url := urllib.parse('https://en.wikipedia.org/wiki/Brazil_(1985_film)') or {
|
||||
panic('unable to parse URL')
|
||||
}
|
||||
assert url.str() == 'https://en.wikipedia.org/wiki/Brazil_(1985_film)'
|
||||
}
|
||||
|
||||
fn test_escape_unescape() {
|
||||
mut original := 'те ст: т\\%'
|
||||
mut escaped := urllib.query_escape(original)
|
||||
assert escaped == '%D1%82%D0%B5+%D1%81%D1%82%3A+%D1%82%5C%25'
|
||||
mut unescaped := urllib.query_unescape(escaped)!
|
||||
assert unescaped == original
|
||||
|
||||
original = 'Hellö Wörld@vlang'
|
||||
escaped = urllib.query_escape(original)
|
||||
assert escaped == 'Hell%C3%B6+W%C3%B6rld%40vlang'
|
||||
unescaped = urllib.query_unescape(escaped)!
|
||||
assert unescaped == original
|
||||
}
|
||||
|
||||
fn test_parse_query() {
|
||||
q1 := urllib.parse_query('format=%22%25l%3A+%25c+%25t%22')!
|
||||
q2 := urllib.parse_query('format="%l:+%c+%t"')!
|
||||
// dump(q1)
|
||||
// dump(q2)
|
||||
assert q1.get('format')? == '"%l: %c %t"'
|
||||
assert q2.get('format')? == '"%l: %c %t"'
|
||||
}
|
||||
|
||||
fn test_parse_query_orders() {
|
||||
query_one :=
|
||||
urllib.parse_query('https://someapi.com/endpoint?gamma=zalibaba&tau=1&alpha=alibaba&signature=alibaba123')!
|
||||
qvalues := query_one.values()
|
||||
assert qvalues == ['zalibaba', '1', 'alibaba', 'alibaba123']
|
||||
}
|
||||
|
||||
fn test_parse_missing_host() {
|
||||
// issue #10311
|
||||
url := urllib.parse('http:///')!
|
||||
assert url.str() == 'http://///'
|
||||
}
|
||||
|
||||
// testing the case where the key as a null value
|
||||
// e.g ?key=
|
||||
fn test_parse_none_value() {
|
||||
query_one := urllib.parse_query('gamma=zalibaba&tau=1&alpha=alibaba&signature=')!
|
||||
qvalues := query_one.values()
|
||||
qvalues_map := query_one.to_map()
|
||||
assert qvalues == ['zalibaba', '1', 'alibaba']
|
||||
assert qvalues_map == {
|
||||
'gamma': ['zalibaba']
|
||||
'tau': ['1']
|
||||
'alpha': ['alibaba']
|
||||
'signature': ['']
|
||||
}
|
||||
}
|
||||
|
||||
// testing the case where the query as empity value
|
||||
// e.g https://www.vlang.dev?alibaba
|
||||
fn test_parse_empty_query_one() {
|
||||
query_str := 'alibaba'
|
||||
query_one := urllib.parse_query(query_str)!
|
||||
qvalues := query_one.values()
|
||||
qvalues_map := query_one.to_map()
|
||||
query_encode := query_one.encode()
|
||||
assert qvalues == []
|
||||
assert qvalues_map == {
|
||||
'alibaba': ['']
|
||||
}
|
||||
assert query_str == query_encode
|
||||
}
|
||||
|
||||
// testing the case where the query as empty value
|
||||
// e.g https://www.vlang.dev?
|
||||
fn test_parse_empty_query_two() {
|
||||
query_str := ''
|
||||
query_one := urllib.parse_query(query_str)!
|
||||
qvalues := query_one.values()
|
||||
qvalues_map := query_one.to_map()
|
||||
query_encode := query_one.encode()
|
||||
assert qvalues == []
|
||||
assert qvalues_map == {}
|
||||
assert query_str == query_encode
|
||||
}
|
||||
|
||||
fn test_parse() {
|
||||
urls := [
|
||||
'jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true',
|
||||
'ftp://ftp.is.co.za/rfc/rfc1808.txt',
|
||||
'http://www.ietf.org/rfc/rfc2396.txt#header1',
|
||||
'ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two',
|
||||
'mailto:John.Doe@example.com',
|
||||
'news:comp.infosystems.www.servers.unix',
|
||||
'tel:+1-816-555-1212',
|
||||
'telnet://192.0.2.16:80/',
|
||||
'urn:oasis:names:specification:docbook:dtd:xml:4.1.2',
|
||||
'foo://example.com:8042/over/there?name=ferret#nose',
|
||||
'ftp://2001:0db8:85a3:0000:0000:8a2e:0370:7334/path/file.txt',
|
||||
'ws://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:4000',
|
||||
'/2000k/hls/mixed.m3u8',
|
||||
'2000k/hls/mixed.m3u8',
|
||||
'./2000k:hls/mixed.m3u8',
|
||||
]
|
||||
for url in urls {
|
||||
urllib.parse(url)!
|
||||
}
|
||||
|
||||
test_url := 'https://joe:pass@www.mydomain.com:8080/som/url?param1=test1¶m2=test2&foo=bar#testfragment'
|
||||
u := urllib.parse(test_url)!
|
||||
if user := u.user {
|
||||
assert u.scheme == 'https' && u.hostname() == 'www.mydomain.com' && u.port() == '8080'
|
||||
&& u.path == '/som/url' && u.fragment == 'testfragment' && user.username == 'joe'
|
||||
&& user.password == 'pass'
|
||||
}
|
||||
|
||||
v :=
|
||||
urllib.parse('https://vip.ffzy-online4.com/20230205/6094_d2720761/index.m3u8')!.resolve_reference(urllib.parse('2000k/hls/mixed.m3u8')!)!
|
||||
assert v.str() == 'https://vip.ffzy-online4.com/20230205/6094_d2720761/2000k/hls/mixed.m3u8'
|
||||
}
|
||||
|
||||
fn test_parse_authority() {
|
||||
test_urls := {
|
||||
'ftp://webmaster@www.google.com/': ['webmaster', '']
|
||||
'http://j@ne:password@google.com': ['j@ne', 'password']
|
||||
'http://jane:p@ssword@google.com/p@th?q=@go': ['jane', 'p@ssword']
|
||||
}
|
||||
|
||||
for url, expected in test_urls {
|
||||
u := urllib.parse(url)!
|
||||
if user := u.user {
|
||||
assert user.username == expected[0]
|
||||
assert user.password == expected[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_parse_slashes() {
|
||||
assert urllib.parse('/')!.str() == '/'
|
||||
assert urllib.parse('//')!.str() == '//'
|
||||
assert urllib.parse('///')!.str() == '///'
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
module urllib
|
||||
|
||||
pub struct QueryValue {
|
||||
pub mut:
|
||||
key string
|
||||
value string
|
||||
}
|
||||
|
||||
pub struct Values {
|
||||
pub mut:
|
||||
data []QueryValue
|
||||
len int
|
||||
}
|
||||
|
||||
// new_values returns a new Values struct for creating
|
||||
// urlencoded query string parameters. it can also be to
|
||||
// post form data with application/x-www-form-urlencoded.
|
||||
// values.encode() will return the encoded data
|
||||
pub fn new_values() Values {
|
||||
return Values{
|
||||
data: []QueryValue{}
|
||||
}
|
||||
}
|
||||
|
||||
// get gets the first value associated with the given key.
|
||||
// If there are no values associated with the key, get returns
|
||||
// none.
|
||||
pub fn (v &Values) get(key string) ?string {
|
||||
if v.data.len == 0 {
|
||||
return none
|
||||
}
|
||||
for qvalue in v.data {
|
||||
if qvalue.key == key {
|
||||
return qvalue.value
|
||||
}
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
// get_all gets the all the values associated with the given key.
|
||||
// If there are no values associated with the key, get returns
|
||||
// a empty []string.
|
||||
pub fn (v &Values) get_all(key string) []string {
|
||||
if v.data.len == 0 {
|
||||
return []
|
||||
}
|
||||
mut values := []string{}
|
||||
for qvalue in v.data {
|
||||
if qvalue.key == key {
|
||||
values << qvalue.value
|
||||
}
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// set sets the key to value. It replaces any existing
|
||||
// values, or create a new bucket with the new key if it is missed.
|
||||
pub fn (mut v Values) set(key string, value string) {
|
||||
// A query string can contains several
|
||||
// duplicate, so we need to make sure that we
|
||||
// cover all the edge case.
|
||||
mut found := false
|
||||
for mut qvalue in v.data {
|
||||
if qvalue.key == key {
|
||||
found = true
|
||||
qvalue.value = value
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
v.add(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
// add adds the value to key. It appends to any existing
|
||||
// values associated with key.
|
||||
pub fn (mut v Values) add(key string, value string) {
|
||||
v.data << QueryValue{
|
||||
key: key
|
||||
value: value
|
||||
}
|
||||
v.len = v.data.len
|
||||
}
|
||||
|
||||
// del deletes the values associated with key.
|
||||
pub fn (mut v Values) del(key string) {
|
||||
for idx, qvalue in v.data {
|
||||
if qvalue.key == key {
|
||||
v.data.delete(idx)
|
||||
}
|
||||
}
|
||||
v.len = v.data.len
|
||||
}
|
||||
|
||||
// return the list of values in the query string
|
||||
pub fn (v Values) values() []string {
|
||||
mut values := []string{}
|
||||
for qvalue in v.data {
|
||||
if qvalue.value != '' {
|
||||
values << qvalue.value
|
||||
}
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// return a map <key []value> of the query string
|
||||
pub fn (v Values) to_map() map[string][]string {
|
||||
mut result := map[string][]string{}
|
||||
|
||||
for qvalue in v.data {
|
||||
if qvalue.key in result {
|
||||
result[qvalue.key] << qvalue.value
|
||||
} else {
|
||||
result[qvalue.key] = [qvalue.value]
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
module urllib
|
||||
|
||||
fn test_add_and_get_key_val() {
|
||||
mut values := Values{}
|
||||
values.add('key', 'value')
|
||||
present_val := values.get('key') or { '' }
|
||||
absent_val := values.get('key1') or { '' }
|
||||
assert present_val == 'value'
|
||||
assert absent_val == ''
|
||||
}
|
||||
|
||||
fn test_get_all_with_key() {
|
||||
mut values := Values{}
|
||||
values.add('key', 'value1')
|
||||
values.add('key', 'value2')
|
||||
key_values := values.get_all('key')
|
||||
assert key_values == ['value1', 'value2']
|
||||
}
|
||||
|
||||
fn test_set_with_key() {
|
||||
mut values := Values{}
|
||||
values.add('key', 'value1')
|
||||
values.add('key', 'value2')
|
||||
values.add('key1', 'value2')
|
||||
values.set('key1', 'vlang')
|
||||
key_values := values.get_all('key')
|
||||
key2_values := values.get_all('key1')
|
||||
assert key_values == ['value1', 'value2']
|
||||
assert key2_values == ['vlang']
|
||||
}
|
||||
|
||||
fn test_set_missing_key() {
|
||||
mut values := Values{}
|
||||
values.set('err', 'err1')
|
||||
vals := values.get_all('err')
|
||||
assert vals == ['err1']
|
||||
}
|
||||
Reference in new issue
Block a user