toyohime/internal/internal.go
kare.nuorteva 1f1974ba93 Rename package files
git-svn-id: file:///srv/svn/repo/toyohime/trunk@42 922d331f-388e-da47-97a9-ad700dc0b8b9
2017-04-24 17:57:15 +00:00

132 lines
3.1 KiB
Go

package internal // import "kkn.fi/cmd/vanity/internal"
import (
"fmt"
"net/http"
"strings"
)
type (
// VCS is the Version Control System used by the Go project.
VCS struct {
// System defines which version control system is used.
// Usually git or hg.
System string
// VCSURL is the HTTPS URL for project's version control system.
// Usually github.com or bitbucket.org address.
URL string
}
// Package defines Go package that has vanity import defined by Path,
// VCS system type and VCS URL.
Package struct {
// Name is the name of the Go package.
Name string
// VCS is version control system used by the project.
VCS *VCS
}
// Server is the actual HTTP server for Go vanity domains.
Server struct {
// Domain is the vanity domain.
Domain string
// Packages contains settings for vanity packages.
Packages []*Package
}
)
func (p Package) name() string {
path := p.Name
c := strings.Index(path, "/")
if c == -1 {
return path
}
path = path[c+1:]
c = strings.Index(path, "/")
if c == -1 {
return path
}
return path[:c]
}
// NewVCS creates a new VCS base on system and url.
func NewVCS(system, url string) *VCS {
v := &VCS{
System: system,
URL: url,
}
return v
}
// NewPackage returns a new Package given a path and VCS.
func NewPackage(path string, vcs *VCS) *Package {
p := &Package{
Name: path,
VCS: vcs,
}
return p
}
// NewServer returns a new Vanity Server given domain name and
// vanity package configuration.
func NewServer(domain string, config []*Package) *Server {
s := &Server{
Domain: domain,
Packages: config,
}
return s
}
// goMetaContent creates a value from the <meta/> tag content attribute.
func (v VCS) goMetaContent() string {
return fmt.Sprintf("%v %v", v.System, v.URL)
}
// goDocURL returns the HTTP URL to godoc.org.
func (p Package) goDocURL() string {
return fmt.Sprintf("https://godoc.org/%v", p.Name)
}
// goImportLink creates the link used in HTML <meta/> tag
// where domain is the domain name of the server.
func (p Package) goImportLink(domain string) string {
path := p.name()
return fmt.Sprintf("%v/%v %v", domain, path, p.VCS.goMetaContent())
}
// goImportMeta creates the <meta/> HTML tag containing name and content attributes.
func (p Package) goImportMeta(domain string) string {
link := p.goImportLink(domain)
return fmt.Sprintf(`<meta name="go-import" content="%s">`, link)
}
func (s Server) find(path string) *Package {
for _, p := range s.Packages {
if p.Name == s.Domain+path {
return p
}
}
return nil
}
// ServeHTTP is an HTTP Handler for Go vanity domain.
func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "text/html; charset=utf-8")
if r.Method != http.MethodGet {
status := http.StatusMethodNotAllowed
http.Error(w, http.StatusText(status), status)
return
}
pack := s.find(r.URL.Path)
if pack == nil {
http.NotFound(w, r)
return
}
if r.FormValue("go-get") != "1" {
url := pack.goDocURL()
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
return
}
fmt.Fprint(w, pack.goImportMeta(s.Domain))
}