Wrap net/url to fix URI handling#6357
Conversation
Is this much faster than |
| false, // 0x20 | ||
| false, // 0x21 | ||
| false, // 0x22 | ||
| false, // 0x23 |
There was a problem hiding this comment.
Printable characters on a lookup table (like #) would be much more helpful than the hex code
toaster
left a comment
There was a problem hiding this comment.
As discussed in Slack, I would prefer to use the stdlib’s URL instead of re-inventing the wheel here.
I’d also like to get another opinion on this topic.
For the actual implementation:
- You should explicitly test all the bytes and maybe a couple of unicode characters.
Optional:
- I suggest to use a
shouldEscape[c]instead of thedontEscape[c]approach. - You might simplify the generator implementation.
| func filePathEscape(path string) string { | ||
| length := len(path) | ||
| for _, c := range []byte(path) { | ||
| if !dontEscape[c] { |
There was a problem hiding this comment.
I think an inverted list would be easier to read here and not worse later:
if escape[c] { … }
…
if escape[c] { /* escape */ } else { … }| assert.Equal(t, "/home/user/file.txt", filePathEscape("/home/user/file.txt")) | ||
| assert.Equal(t, "/home/user/file%231.txt", filePathEscape("/home/user/file#1.txt")) | ||
| } |
There was a problem hiding this comment.
This test is not sufficient. You can remove characters from the list to escape without breaking the test.
| dontEscape['$'] = true | ||
| dontEscape['&'] = true | ||
| dontEscape['+'] = true | ||
| dontEscape['-'] = true | ||
| dontEscape['.'] = true | ||
| dontEscape[':'] = true | ||
| dontEscape['='] = true | ||
| dontEscape['@'] = true | ||
| dontEscape['_'] = true | ||
| dontEscape['~'] = true | ||
|
|
||
| dontEscape['\\'] = true | ||
| dontEscape['/'] = true |
There was a problem hiding this comment.
for _, rune in range "$&+-.:=@_~\\/" {
dontEscape[rune] = true
}
[snip] Just for reference, I looked into this, and we were using I'll try and see how far I get before spending more time on the details of the current PR, but the feedback is good and appreciated and will be applied if it turns out it's still needed. |
The (probable (since I've done this before)) speed-up probably won't make a real-world difference in a Fyne app and is more a side-effect than the goal, and the comment was to explain why this particular implementation (static lookup table, no function call overhead). I'm now looking if we could wrap |
toaster
left a comment
There was a problem hiding this comment.
Cool, just some minor things:
- consider
type uri url.URL(constructed viauri{…}) - use direct prop access
| type uri struct { | ||
| scheme string | ||
| authority string | ||
| path string | ||
| query string | ||
| fragment string | ||
| url.URL | ||
| } |
There was a problem hiding this comment.
Public fields of url.URL conflict with the accessor names/API unfortunately.
|
|
||
| func (u *uri) Extension() string { | ||
| return path.Ext(u.path) | ||
| return path.Ext(u.URL.Path) |
There was a problem hiding this comment.
Whether you actually embed or simply do type uri url.URL does not matter, this is accessible as u.Path in both cases.
This applies to all other u.URL.*.
There was a problem hiding this comment.
I've changed the few that don't actually need it, but this one does due to the Path method/field conflict.
…(possible?) problems
…m about (possible?) problems" This reverts commit 42952fe.
…evert test to previous behaviour
… says 'must remove ...'
There was a problem hiding this comment.
- someone else should check the decisions regarding
urnand Windows file URI inParseURI - check whether uri#String() can simply be removed
- add exceptional cases to
getUserHosttest - improve comprehensibility of hostname regexp by extracting host component pattern into a constant, i.e., by giving it a name
| {"foo@bar", "foo", "bar"}, | ||
| {"@bar", "", "bar"}, | ||
| {"foo:bar@baz", "foo:bar", "baz"}, | ||
| {"foo:bar@", "foo:bar", ""}, |
There was a problem hiding this comment.
You should add exceptional cases here, too, e.g. foo:bar:baz@nowhere.
There was a problem hiding this comment.
Generally, I don’t like the idea of testing unexported functions because you do not guarantee the exported functions working as expected this way.
| "fyne.io/fyne/v2" | ||
| ) | ||
|
|
||
| var rxHostName = regexp.MustCompile(`^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$`) |
There was a problem hiding this comment.
I think, you should extract the host name component part into a constant:
const hostNameComponentPattern = "[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?"
var rxHostName = regexp.MustCompile("^" + hostNameComponentPattern + `(?:\.` + hostNameComponentPattern + ")*$")| } | ||
| return s.String() | ||
| return u.URL.String() | ||
| } |
There was a problem hiding this comment.
Isn’t this method superfluous now?
I think removing it would provide u.URL.String() directly to uri.
|
Great feedback, thanks! All addressed.
Yes, please! |
|
If urn is called out as a special case I think it needs tests covering that... |
… for query and fragment
Description:
Handle URIs with the standard library. URNs are supported by detecting the scheme and passing through the path.
Checklist: