How to prevent Rust's Url::parse from auto-encoding and instead throw error?

I am using Url::parse from the url crate

For example:

let input = "http://example.com:8080/?sort=custom&kind=comm        <    >   ents&scope=discover&time=6mo&page=2";

match Url::parse(&input) {
    Ok(u) => println!("Url: {}",u),
    Err(err) => println!("Error: {}",err),
}

I would expect this to trigger the Err arm because the input has spaces and also < and >.

But instead, it auto-encodes it and gives:

http://example.com:8080/?sort=custom&kind=comm%20%20%20%20%20%20%20%20%3C%20%20%20%20%3E%20%20%20ents&scope=discover&time=6mo&page=2

How to prevent this and instead trigger the Err arm?

Upvotes: 0

Views: 46

Answers (1)

Jmb
Jmb

Reputation: 23443

Note that even though spaces and angle brackets in the query constitute validation errors, the URL Standard states that: "A validation error does not mean that the parser terminates."

You can use syntax_violation_callback to report validation errors:

use std::cell::RefCell;
use url::{SyntaxViolation, Url};

fn main() {
    let violations = RefCell::new(Vec::new());
    let input =
        "http://example.com:8080/?sort=custom&kind=comm <ents&scope=discover&time=6mo&page=2";
    let url = Url::options()
        .syntax_violation_callback(Some(&|v| violations.borrow_mut().push(v)))
        .parse(input)
        .unwrap();
    assert_eq!(
        url.as_str(),
        "http://example.com:8080/?sort=custom&kind=comm%20%3Cents&scope=discover&time=6mo&page=2"
    );
    assert_eq!(
        violations.into_inner(),
        vec![
            SyntaxViolation::NonUrlCodePoint,
            SyntaxViolation::NonUrlCodePoint
        ]
    );
}

Playground

Upvotes: 2

Related Questions