1
2
3
4
5 package web
6
7 import (
8 "errors"
9 "net/url"
10 "path/filepath"
11 "strings"
12 )
13
14
15
16
17 var errNotAbsolute = errors.New("path is not absolute")
18
19 func urlToFilePath(u *url.URL) (string, error) {
20 if u.Scheme != "file" {
21 return "", errors.New("non-file URL")
22 }
23
24 checkAbs := func(path string) (string, error) {
25 if !filepath.IsAbs(path) {
26 return "", errNotAbsolute
27 }
28 return path, nil
29 }
30
31 if u.Path == "" {
32 if u.Host != "" || u.Opaque == "" {
33 return "", errors.New("file URL missing path")
34 }
35 return checkAbs(filepath.FromSlash(u.Opaque))
36 }
37
38 path, err := convertFileURLPath(u.Host, u.Path)
39 if err != nil {
40 return path, err
41 }
42 return checkAbs(path)
43 }
44
45 func urlFromFilePath(path string) (*url.URL, error) {
46 if !filepath.IsAbs(path) {
47 return nil, errNotAbsolute
48 }
49
50
51
52 if vol := filepath.VolumeName(path); vol != "" {
53 if strings.HasPrefix(vol, `\\`) {
54 path = filepath.ToSlash(path[2:])
55 i := strings.IndexByte(path, '/')
56
57 if i < 0 {
58
59
60
61
62 return &url.URL{
63 Scheme: "file",
64 Host: path,
65 Path: "/",
66 }, nil
67 }
68
69
70
71
72 return &url.URL{
73 Scheme: "file",
74 Host: path[:i],
75 Path: filepath.ToSlash(path[i:]),
76 }, nil
77 }
78
79
80
81
82 return &url.URL{
83 Scheme: "file",
84 Path: "/" + filepath.ToSlash(path),
85 }, nil
86 }
87
88
89
90
91 return &url.URL{
92 Scheme: "file",
93 Path: filepath.ToSlash(path),
94 }, nil
95 }
96
View as plain text