some cleanup

master
Jordan Orelli 3 years ago
parent 0087101de9
commit 01cd3216c5

@ -0,0 +1,34 @@
package main
import (
"net/http"
)
type apiError int
func (e apiError) Error() string {
return http.StatusText(int(e))
}
type errorNode struct {
err error
parent error
}
func (e errorNode) Error() string {
return e.err.Error()
}
func (e errorNode) Unwrap() error {
return e.parent
}
func joinErrors(e, e2 error) error {
if e == nil {
return e2
}
if e2 == nil {
return e
}
return errorNode{err: e, parent: e2}
}

@ -3,7 +3,9 @@ package main
import ( import (
"context" "context"
"embed" "embed"
"errors"
"fmt" "fmt"
"io/fs"
"net" "net"
"net/http" "net/http"
"os" "os"
@ -183,6 +185,7 @@ func (h handler) locate(modpath string) ([]os.DirEntry, error) {
} }
func writeError(w http.ResponseWriter, err error) { func writeError(w http.ResponseWriter, err error) {
// this sucks and is wrong
if os.IsNotExist(err) { if os.IsNotExist(err) {
log_info.Printf("404 %v", err) log_info.Printf("404 %v", err)
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
@ -190,34 +193,39 @@ func writeError(w http.ResponseWriter, err error) {
return return
} }
var status apiError
if errors.As(err, &status) {
w.WriteHeader(int(status))
log_error.Printf("%d %v", status, err)
fmt.Fprintf(w, err.Error())
return
}
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "internal server error") fmt.Fprintf(w, "internal server error")
log_error.Printf("500 %v", err) log_error.Printf("500 %v", err)
return return
} }
// latest serves the @latest endpoint // getVersions gets the list of versions available for a module
func (h handler) latest(modpath string, w http.ResponseWriter, r *http.Request) { func (h handler) getVersions(modpath string) ([]string, error) {
}
// list serves the $base/$module/@v/list endpoint
func (h handler) list(modpath string, w http.ResponseWriter, r *http.Request) {
log_info.Printf("list: %s", modpath)
dirpath, _ := filepath.Split(modpath) dirpath, _ := filepath.Split(modpath)
log_info.Printf("dirpath: %s", dirpath)
localDir := filepath.Join(h.root, "modules", dirpath) localDir := filepath.Join(h.root, "modules", dirpath)
log_info.Printf("localDir: %s", localDir)
files, err := os.ReadDir(localDir) files, err := os.ReadDir(localDir)
if err != nil { if err != nil {
writeError(w, err) if errors.Is(err, fs.ErrNotExist) {
return return nil, apiError(http.StatusNotFound)
}
if errors.Is(err, fs.ErrPermission) {
return nil, apiError(http.StatusForbidden)
}
return nil, joinErrors(err, apiError(http.StatusInternalServerError))
} }
allVersions := make([]string, 0, len(files)) allVersions := make([]string, 0, len(files))
for _, f := range files { for _, f := range files {
name := f.Name() name := f.Name()
if filepath.Ext(name) != ".zip" { if filepath.Ext(name) != ".zip" {
log_info.Printf("not a zip: %s", name)
continue continue
} }
parts := strings.Split(name, "@") parts := strings.Split(name, "@")
@ -230,13 +238,27 @@ func (h handler) list(modpath string, w http.ResponseWriter, r *http.Request) {
allVersions = append(allVersions, parts[1]) allVersions = append(allVersions, parts[1])
} }
semver.Sort(allVersions)
if len(allVersions) == 0 { if len(allVersions) == 0 {
w.WriteHeader(http.StatusNotFound) return nil, apiError(http.StatusNotFound)
fmt.Fprint(w, "not found") }
semver.Sort(allVersions)
return allVersions, nil
}
// latest serves the @latest endpoint
func (h handler) latest(modpath string, w http.ResponseWriter, r *http.Request) {
}
// list serves the $base/$module/@v/list endpoint
func (h handler) list(modpath string, w http.ResponseWriter, r *http.Request) {
versions, err := h.getVersions(modpath)
if err != nil {
writeError(w, err)
return return
} }
for _, version := range allVersions {
for _, version := range versions {
fmt.Fprint(w, version) fmt.Fprint(w, version)
} }
} }

Loading…
Cancel
Save