@@ -105,16 +105,23 @@ func Parse(urlstr string) (*URL, error) {
105
105
switch {
106
106
case ! ok :
107
107
return nil , ErrUnknownDatabaseScheme
108
- case scheme .Driver == "file" && u . Opaque != "" :
108
+ case scheme .Driver == "file" :
109
109
// determine scheme for file
110
- if typ , err := SchemeType (u .Opaque ); err == nil {
111
- return Parse (typ + ":" + buildOpaque (u ))
110
+ s := u .opaqueOrPath ()
111
+ switch {
112
+ case u .Transport != "tcp" , strings .Index (u .OriginalScheme , "+" ) != - 1 :
113
+ return nil , ErrInvalidTransportProtocol
114
+ case s == "" :
115
+ return nil , ErrMissingPath
116
+ }
117
+ if typ , err := SchemeType (s ); err == nil {
118
+ return Parse (typ + "://" + u .buildOpaque ())
112
119
}
113
120
return nil , ErrUnknownFileExtension
114
121
case ! scheme .Opaque && u .Opaque != "" :
115
122
// if scheme does not understand opaque URLs, retry parsing after
116
123
// building fully qualified URL
117
- return Parse (u .OriginalScheme + "://" + buildOpaque (u ))
124
+ return Parse (u .OriginalScheme + "://" + u . buildOpaque ())
118
125
case scheme .Opaque && u .Opaque == "" :
119
126
// force Opaque
120
127
u .Opaque , u .Host , u .Path , u .RawPath = u .Host + u .Path , "" , "" , ""
@@ -234,10 +241,35 @@ func (u *URL) Normalize(sep, empty string, cut int) string {
234
241
return strings .Join (s , sep )
235
242
}
236
243
244
+ // buildOpaque builds a opaque path.
245
+ func (u * URL ) buildOpaque () string {
246
+ var up string
247
+ if u .User != nil {
248
+ up = u .User .String () + "@"
249
+ }
250
+ var q string
251
+ if u .RawQuery != "" {
252
+ q = "?" + u .RawQuery
253
+ }
254
+ var f string
255
+ if u .Fragment != "" {
256
+ f = "#" + u .Fragment
257
+ }
258
+ return up + u .opaqueOrPath () + q + f
259
+ }
260
+
261
+ // opaqueOrPath returns the opaque or path value.
262
+ func (u * URL ) opaqueOrPath () string {
263
+ if u .Opaque != "" {
264
+ return u .Opaque
265
+ }
266
+ return u .Path
267
+ }
268
+
237
269
// SchemeType returns the scheme type for a path.
238
270
func SchemeType (name string ) (string , error ) {
239
271
// try to resolve the path on unix systems
240
- if runtime .GOOS != "windows" /*&& !mode(name).IsRegular()*/ {
272
+ if runtime .GOOS != "windows" {
241
273
if typ , ok := resolveType (name ); ok {
242
274
return typ , nil
243
275
}
@@ -315,21 +347,13 @@ var OpenFile = func(name string) (fs.File, error) {
315
347
return f , nil
316
348
}
317
349
318
- // buildOpaque builds a opaque path from u.
319
- func buildOpaque (u * URL ) string {
320
- var q string
321
- if u .RawQuery != "" {
322
- q = "?" + u .RawQuery
323
- }
324
- var f string
325
- if u .Fragment != "" {
326
- f = "#" + u .Fragment
327
- }
328
- return u .Opaque + q + f
329
- }
330
-
331
350
// resolveType tries to resolve a path to a Unix domain socket or directory.
332
351
func resolveType (s string ) (string , bool ) {
352
+ if i := strings .LastIndex (s , "?" ); i != - 1 {
353
+ if _ , err := Stat (s [:i ]); err == nil {
354
+ s = s [:i ]
355
+ }
356
+ }
333
357
dir := s
334
358
for dir != "" && dir != "/" && dir != "." {
335
359
// chop off :4444 port
0 commit comments