129 lines
3.1 KiB
Go
129 lines
3.1 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
"io"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"log"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
func uploadHandler(config Conf) http.Handler {
|
||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
if r.Method != "POST" {
|
||
|
http.Error(w, "method not supported", http.StatusMethodNotAllowed)
|
||
|
return
|
||
|
}
|
||
|
archType := r.URL.Query().Get("arch")
|
||
|
if archType == "" {
|
||
|
archType = "all"
|
||
|
}
|
||
|
distroName := r.URL.Query().Get("distro")
|
||
|
if distroName == "" {
|
||
|
distroName = "stable"
|
||
|
}
|
||
|
key := r.URL.Query().Get("key")
|
||
|
if key == "" || key != config.Key {
|
||
|
http.Error(w, "unauthorized", 403)
|
||
|
return
|
||
|
}
|
||
|
reader, err := r.MultipartReader()
|
||
|
if err != nil {
|
||
|
httpErrorf(w, "error creating multipart reader: %s", err)
|
||
|
return
|
||
|
}
|
||
|
for {
|
||
|
part, err := reader.NextPart()
|
||
|
if err == io.EOF {
|
||
|
break
|
||
|
}
|
||
|
if part.FileName() == "" {
|
||
|
continue
|
||
|
}
|
||
|
newPath := config.PoolPackagePath(distroName, archType, part.FileName())
|
||
|
|
||
|
if _, err := os.Stat(newPath); err != nil {
|
||
|
if os.IsNotExist(err) {
|
||
|
if err := os.MkdirAll(newPath, 0755); err != nil {
|
||
|
httpErrorf(w, "error creating path: %s", err)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dst, err := os.Create(filepath.Join(newPath, part.FileName()))
|
||
|
if err != nil {
|
||
|
httpErrorf(w, "error creating deb file: %s", err)
|
||
|
return
|
||
|
}
|
||
|
defer dst.Close()
|
||
|
|
||
|
if _, err := io.Copy(dst, part); err != nil {
|
||
|
httpErrorf(w, "error writing deb file: %s", err)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
mutex.Lock()
|
||
|
defer mutex.Unlock()
|
||
|
|
||
|
log.Println("got lock, updating package list...")
|
||
|
if err := createPackagesGz(config, distroName, archType); err != nil {
|
||
|
httpErrorf(w, "error creating package: %s", err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
err = createRelease(config, distroName, archType)
|
||
|
|
||
|
if err != nil {
|
||
|
httpErrorf(w, "error creating package: %s", err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
w.WriteHeader(http.StatusOK)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func deleteHandler(config Conf) http.Handler {
|
||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
if r.Method != "DELETE" {
|
||
|
http.Error(w, "method not supported", http.StatusMethodNotAllowed)
|
||
|
return
|
||
|
}
|
||
|
var toDelete DeleteObj
|
||
|
if err := json.NewDecoder(r.Body).Decode(&toDelete); err != nil {
|
||
|
httpErrorf(w, "failed to decode json: %s", err)
|
||
|
return
|
||
|
}
|
||
|
debPath := filepath.Join(config.ArchPath(toDelete.DistroName, toDelete.Arch), toDelete.Filename)
|
||
|
if err := os.Remove(debPath); err != nil {
|
||
|
httpErrorf(w, "failed to delete: %s", err)
|
||
|
return
|
||
|
}
|
||
|
key := r.URL.Query().Get("key")
|
||
|
if key == "" || key != config.Key {
|
||
|
http.Error(w, "unauthorized", http.StatusForbidden)
|
||
|
return
|
||
|
}
|
||
|
mutex.Lock()
|
||
|
defer mutex.Unlock()
|
||
|
|
||
|
log.Println("got lock, updating package list...")
|
||
|
if err := createPackagesGz(config, toDelete.DistroName, toDelete.Arch); err != nil {
|
||
|
httpErrorf(w, "failed to delete package: %s", err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if err := createRelease(config, toDelete.DistroName, toDelete.Arch); err != nil {
|
||
|
httpErrorf(w, "failed to delete package: %s", err)
|
||
|
return
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
func httpErrorf(w http.ResponseWriter, format string, a ...interface{}) {
|
||
|
err := fmt.Errorf(format, a...)
|
||
|
log.Println(err)
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
}
|