NET-A-PORTER/scala-uri

Support File URIs

Closed this issue · 2 comments

Hi,

I'm trying to use scala-uri in Gatling, to replace a "quick-and-dirty" hack on URIs to support spaces in filenames.
But I'm unfortunately unable to construct valid file URIs, as scala-uri always add a leading-slash, thinking the URI is relative :

scala> import java.io.File, java.net.URI, com.netaporter.uri._, com.netaporter.uri.dsl._
import java.io.File
import java.net.URI
import com.netaporter.uri._
import com.netaporter.uri.dsl._

scala> new File(sys.props("user.home"))
res0: java.io.File = /Users/pdalpra

scala> res0.toURI
res1: java.net.URI = file:/Users/pdalpra/

scala> Uri(res1)
res2: com.netaporter.uri.Uri = /file:/Users/pdalpra/

Would it be possible to support file URIs ?

More details about the problem with File URIs :

scala-uri can actually manage to work with them, but this requires of juggling with hostnames. Unlike other schemes, file: URIs accepts that the hostname can be omitted, and infer that it is localhost. java.net.URI accepts that, but scala-uri doesn't and the hostname must be set so that the URI is not considered relative.
But java.io.File does not apparently like the idea that the file could be anywhere else than on the local filesystem and throws an exception if the URI passed to the constructor has a hostname in it.

In order to have an Uri that can be converted to a java.net.URI which will be fed to a java.io.File, the host must be removed beforehand :

scala> val File : Uri = "file://localhost"
File: com.netaporter.uri.Uri = file://localhost

scala> File / "Users" / "pdalpra"
res0: com.netaporter.uri.Uri = file://localhost/Users/pdalpra

scala> new File(res0.toURI)
java.lang.IllegalArgumentException: URI has an authority component
    at java.io.File.<init>(File.java:423)
    ...

scala> new File(res0.withHost("").toURI)
res1: java.io.File = /Users/pdalpra // OK

IMO, a support for File URIs would only need to :

  • Take account that a missing hostname is valid for the file scheme, or set it to localhost automatically
  • If the scheme is file, then Uri's toString should exclude the hostname, since Uri's toURI relies on toString.

@pdalpra Sorry for not getting back to you on this

I don't think including localhost has any impact on how scala-uri behaves. The reason you are seeing different behaviour, is just that in your first comment you have a single slash after the file scheme (file:/Users/pdalpra/) and in the second example you have a double slash (file://localhost).

Looking at the RFC 1738, I believe two slashes is correct and scala-uri is doing the right thing.

Let me know if you think otherwise!