зеркало из https://github.com/golang/pkgsite.git
internal/fetch: implement parse url for fetch service
The fetch service accepts HTTP requests at http(s)://<fetchURL>/<module>@<version>. ParseNameAndVersion is implemented, which validates the module name and version for requests to this endpoint. Change-Id: Iacf7f4ae8dfef54a024172807d8bc9ff01749c84 Reviewed-on: https://team-review.git.corp.google.com/c/422997 Reviewed-by: Channing Kimble-Brown <ckimblebrown@google.com> Reviewed-by: Andrew Bonventre <andybons@google.com>
This commit is contained in:
Родитель
518ce0a7d6
Коммит
ae504474f3
|
@ -9,6 +9,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
@ -20,6 +21,25 @@ import (
|
|||
|
||||
var errReadmeNotFound = errors.New("fetch: zip file does not contain a README")
|
||||
|
||||
// ParseNameAndVersion returns the module and version specified by u. u is
|
||||
// assumed to be a valid url following the structure http(s)://<fetchURL>/<module>@<version>.
|
||||
func ParseNameAndVersion(u *url.URL) (string, string, error) {
|
||||
parts := strings.Split(strings.TrimPrefix(u.Path, "/"), "/@v/")
|
||||
if len(parts) != 2 {
|
||||
return "", "", fmt.Errorf("invalid path: %q", u)
|
||||
}
|
||||
|
||||
// TODO(julieqiu): Check module name is valid using
|
||||
// https://github.com/golang/go/blob/c97e576/src/cmd/go/internal/module/module.go#L123
|
||||
// Check version is valid using
|
||||
// https://github.com/golang/go/blob/c97e576/src/cmd/go/internal/modload/query.go#L183
|
||||
if parts[0] == "" || parts[1] == "" {
|
||||
return "", "", fmt.Errorf("invalid path: %q", u)
|
||||
}
|
||||
|
||||
return parts[0], parts[1], nil
|
||||
}
|
||||
|
||||
// isReadme checks if file is the README. It is case insensitive.
|
||||
func isReadme(file string) bool {
|
||||
base := filepath.Base(file)
|
||||
|
|
|
@ -9,10 +9,72 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseNameAndVersion(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
module string
|
||||
version string
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "ValidFetchURL",
|
||||
url: "https://proxy.com/module/@v/v1.0.0",
|
||||
module: "module",
|
||||
version: "v1.0.0",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
name: "InvalidFetchURL",
|
||||
url: "https://proxy.com/",
|
||||
err: errors.New(`invalid path: "https://proxy.com/"`),
|
||||
},
|
||||
{
|
||||
name: "InvalidFetchURLNoModule",
|
||||
url: "https://proxy.com/@v/version",
|
||||
err: errors.New(`invalid path: "https://proxy.com/@v/version"`),
|
||||
},
|
||||
{
|
||||
name: "InvalidFetchURLNoVersion",
|
||||
url: "https://proxy.com/module/@v/",
|
||||
err: errors.New(`invalid path: "https://proxy.com/module/@v/"`),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
u, err := url.Parse(tc.url)
|
||||
if err != nil {
|
||||
t.Errorf("url.Parse(%q): %v", tc.url, err)
|
||||
}
|
||||
|
||||
m, v, err := ParseNameAndVersion(u)
|
||||
if tc.err != nil {
|
||||
if err == nil {
|
||||
t.Fatalf("ParseNameAndVersion(%v) error = (%v); want = (%v)", u, err, tc.err)
|
||||
}
|
||||
if tc.err.Error() != err.Error() {
|
||||
t.Fatalf("ParseNameAndVersion(%v) error = (%v); want = (%v)", u, err, tc.err)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
} else if err != nil {
|
||||
t.Fatalf("ParseNameAndVersion(%v) error = (%v); want = (%v)", u, err, tc.err)
|
||||
}
|
||||
|
||||
if tc.module != m || tc.version != v {
|
||||
t.Fatalf("ParseNameAndVersion(%v): %q, %q, %v; want = %q, %q, %v",
|
||||
u, m, v, err, tc.module, tc.version, tc.err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsReadme(t *testing.T) {
|
||||
for input, want := range map[string]bool{
|
||||
"rEaDme": true,
|
||||
|
|
Загрузка…
Ссылка в новой задаче