move meta imports handler into a separate file

This commit is contained in:
Serge Zaitsev 2018-09-20 12:10:24 +02:00
parent 020b523d4a
commit 0140bf1319
2 changed files with 53 additions and 47 deletions

53
pkg/vcs/meta.go Normal file
View File

@ -0,0 +1,53 @@
package vcs
import (
"context"
"encoding/xml"
"errors"
"net/http"
"strings"
)
// MetaImports resolved module import path for certain hosts using the special <meta> tag.
func MetaImports(ctx context.Context, module string) (string, error) {
if strings.HasPrefix(module, "github.com/") || strings.HasPrefix(module, "bitbucket.org/") {
return module, nil
}
// TODO: use context
res, err := http.Get("https://" + module + "?go-get=1")
if err != nil {
return "", err
}
defer res.Body.Close()
html := struct {
HTML string `xml:"html"`
Head struct {
Meta []struct {
Name string `xml:"name,attr"`
Content string `xml:"content,attr"`
} `xml:"meta"`
} `xml:"head"`
}{}
dec := xml.NewDecoder(res.Body)
dec.Strict = false
dec.AutoClose = xml.HTMLAutoClose
dec.Entity = xml.HTMLEntity
if err := dec.Decode(&html); err != nil {
return "", err
}
for _, meta := range html.Head.Meta {
if meta.Name == "go-import" {
if f := strings.Fields(meta.Content); len(f) == 3 {
if f[0] != module {
return "", errors.New("prefix does not match the module")
}
url := f[2]
if i := strings.Index(url, "://"); i >= 0 {
url = url[i+3:]
}
return url, nil
}
}
}
return "", errors.New("go-import meta tag not found")
}

View File

@ -2,10 +2,7 @@ package vcs
import (
"context"
"encoding/xml"
"errors"
"io"
"net/http"
"regexp"
"strings"
"time"
@ -60,47 +57,3 @@ func Password(username, password string) Auth { return Auth{Username: username,
// Key returns an Auth implementation that uses key file authentication mechanism.
func Key(key string) Auth { return Auth{Key: key} }
// MetaImports resolved module import path for certain hosts using the special <meta> tag.
func MetaImports(ctx context.Context, module string) (string, error) {
if strings.HasPrefix(module, "github.com/") || strings.HasPrefix(module, "bitbucket.org/") {
return module, nil
}
// TODO: use context
res, err := http.Get("https://" + module + "?go-get=1")
if err != nil {
return "", err
}
defer res.Body.Close()
html := struct {
HTML string `xml:"html"`
Head struct {
Meta []struct {
Name string `xml:"name,attr"`
Content string `xml:"content,attr"`
} `xml:"meta"`
} `xml:"head"`
}{}
dec := xml.NewDecoder(res.Body)
dec.Strict = false
dec.AutoClose = xml.HTMLAutoClose
dec.Entity = xml.HTMLEntity
if err := dec.Decode(&html); err != nil {
return "", err
}
for _, meta := range html.Head.Meta {
if meta.Name == "go-import" {
if f := strings.Fields(meta.Content); len(f) == 3 {
if f[0] != module {
return "", errors.New("prefix does not match the module")
}
url := f[2]
if i := strings.Index(url, "://"); i >= 0 {
url = url[i+3:]
}
return url, nil
}
}
}
return "", errors.New("go-import meta tag not found")
}