fix: URL-encode query params in client and pass --meta to server on save
- URL-encode all query parameter keys and values in get_json_with_query
and post_stream. Previously raw JSON like {"project":"alpha"} was
sent unencoded, causing 'invalid uri character' errors.
- Pass settings.meta (key=value pairs) from client save to server as
metadata. Previously always passed empty HashMap, so --meta was
silently ignored in client save mode.
This commit is contained in:
@@ -15,6 +15,24 @@ pub struct ItemInfo {
|
||||
pub metadata: HashMap<String, String>,
|
||||
}
|
||||
|
||||
/// Percent-encode a value for use in a URL query string.
|
||||
fn url_encode(s: &str) -> String {
|
||||
let mut result = String::with_capacity(s.len() * 3);
|
||||
for byte in s.bytes() {
|
||||
match byte {
|
||||
b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
|
||||
result.push(byte as char);
|
||||
}
|
||||
_ => {
|
||||
result.push('%');
|
||||
result.push(char::from_digit((byte >> 4) as u32, 16).unwrap());
|
||||
result.push(char::from_digit((byte & 0xF) as u32, 16).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub struct KeepClient {
|
||||
base_url: String,
|
||||
agent: ureq::Agent,
|
||||
@@ -113,7 +131,7 @@ impl KeepClient {
|
||||
if i > 0 {
|
||||
url.push('&');
|
||||
}
|
||||
url.push_str(&format!("{key}={value}"));
|
||||
url.push_str(&format!("{}={}", url_encode(key), url_encode(value)));
|
||||
}
|
||||
}
|
||||
let mut req = self.agent.get(&url);
|
||||
@@ -166,7 +184,7 @@ impl KeepClient {
|
||||
if i > 0 {
|
||||
url.push('&');
|
||||
}
|
||||
url.push_str(&format!("{key}={value}"));
|
||||
url.push_str(&format!("{}={}", url_encode(key), url_encode(value)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +225,11 @@ fn main() -> Result<(), Error> {
|
||||
|
||||
return match mode {
|
||||
KeepModes::Save => {
|
||||
let metadata = std::collections::HashMap::new();
|
||||
let metadata: std::collections::HashMap<String, String> = settings
|
||||
.meta
|
||||
.iter()
|
||||
.filter_map(|(k, v)| v.as_ref().map(|val| (k.clone(), val.clone())))
|
||||
.collect();
|
||||
keep::modes::client::save::mode(&client, &mut cmd, &settings, tags, metadata)
|
||||
}
|
||||
KeepModes::Get => keep::modes::client::get::mode(
|
||||
|
||||
Reference in New Issue
Block a user