/*
GoCheese -- Python private package repository and caching proxy
-Copyright (C) 2019-2021 Sergey Matveev <stargrave@stargrave.org>
- 2019-2021 Elena Balakhonova <balakhonova_e@riseup.net>
+Copyright (C) 2019-2023 Sergey Matveev <stargrave@stargrave.org>
+ 2019-2023 Elena Balakhonova <balakhonova_e@riseup.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
"crypto/sha256"
"encoding/hex"
"io"
- "io/ioutil"
"log"
"net/http"
"os"
}
pkgName := strings.ToLower(NormalizationRe.ReplaceAllString(pkgNames[0], "-"))
dirPath := filepath.Join(Root, pkgName)
- gpgSigsExpected := make(map[string]struct{})
now := time.Now().UTC()
var digestSHA256Expected []byte
for _, file := range r.MultipartForm.File["content"] {
filename := file.Filename
- gpgSigsExpected[filename+GPGSigExt] = struct{}{}
log.Println(r.RemoteAddr, "put", filename, "by", username)
path := filepath.Join(dirPath, filename)
if _, err = os.Stat(path); err == nil {
return
}
src, err := file.Open()
- defer src.Close()
if err != nil {
log.Println("error", r.RemoteAddr, filename, err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
+ defer src.Close()
dst, err := TempFile(dirPath)
if err != nil {
log.Println("error", r.RemoteAddr, filename, err)
digestSHA256 := hasherSHA256.Sum(nil)
digestBLAKE2b256 := hasherBLAKE2b256.Sum(nil)
if digestSHA256Expected != nil {
- if bytes.Compare(digestSHA256Expected, digestSHA256) == 0 {
+ if bytes.Equal(digestSHA256Expected, digestSHA256) {
log.Println(r.RemoteAddr, filename, "good SHA256 checksum received")
} else {
log.Println(r.RemoteAddr, filename, "bad SHA256 checksum received")
}
}
if digestBLAKE2b256Expected != nil {
- if bytes.Compare(digestBLAKE2b256Expected, digestBLAKE2b256) == 0 {
+ if bytes.Equal(digestBLAKE2b256Expected, digestBLAKE2b256) {
log.Println(r.RemoteAddr, filename, "good BLAKE2b-256 checksum received")
} else {
log.Println(r.RemoteAddr, filename, "bad BLAKE2b-256 checksum received")
- http.Error(w, "bad blake2_256 checksum", http.StatusBadRequest)
+ http.Error(w, "bad blake2b_256 checksum", http.StatusBadRequest)
os.Remove(dst.Name())
return
}
return
}
}
- for _, file := range r.MultipartForm.File["gpg_signature"] {
- filename := file.Filename
- if _, exists := gpgSigsExpected[filename]; !exists {
- log.Println(r.RemoteAddr, filename, "unexpected GPG signature filename")
- http.Error(w, "unexpected GPG signature filename", http.StatusBadRequest)
- return
- }
- delete(gpgSigsExpected, filename)
- log.Println(r.RemoteAddr, "put", filename, "by", username)
- path := filepath.Join(dirPath, filename)
- if _, err = os.Stat(path); err == nil {
- log.Println(r.RemoteAddr, filename, "already exists")
- http.Error(w, "already exists", http.StatusBadRequest)
- return
- }
- src, err := file.Open()
- if err != nil {
- log.Println("error", r.RemoteAddr, filename, err)
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- sig, err := ioutil.ReadAll(src)
- src.Close()
- if err != nil {
- log.Println("error", r.RemoteAddr, filename, err)
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- if err = WriteFileSync(dirPath, path, sig, now); err != nil {
- log.Println("error", r.RemoteAddr, path, err)
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- }
var buf bytes.Buffer
wr := recfile.NewWriter(&buf)
- for formField, recField := range map[string]string{
- "name": MetadataFieldName,
- "version": MetadataFieldVersion,
- "platform": MetadataFieldPlatform,
- "supported_platform": MetadataFieldSupportedPlatform,
- "summary": MetadataFieldSummary,
- "description": MetadataFieldDescription,
- "description_content_type": MetadataFieldDescriptionContentType,
- "keywords": MetadataFieldKeywords,
- "home_page": MetadataFieldHomePage,
- "author": MetadataFieldAuthor,
- "author_email": MetadataFieldAuthorEmail,
- "maintainer": MetadataFieldMaintainer,
- "maintainer_email": MetadataFieldMaintainerEmail,
- "license": MetadataFieldLicense,
- "classifiers": MetadataFieldClassifier,
- "requires_dist": MetadataFieldRequiresDist,
- "requires_python": MetadataFieldRequiresPython,
- "requires_external": MetadataFieldRequiresExternal,
- "project_url": MetadataFieldProjectURL,
- "provides_extra": MetadataFieldProvidesExtra,
- } {
+ for _, m := range MDFormToRecField {
+ formField, recField := m[0], m[1]
if vs, exists := r.MultipartForm.Value[formField]; exists {
for _, v := range vs {
lines := strings.Split(v, "\n")
if len(lines) > 1 {
- _, err = wr.WriteFieldMultiline(
- metadataFieldToRecField(recField),
- lines,
- )
+ _, err = wr.WriteFieldMultiline(recField, lines)
} else {
_, err = wr.WriteFields(recfile.Field{
- Name: metadataFieldToRecField(recField),
+ Name: recField,
Value: lines[0],
})
}
if err != nil {
- log.Fatalln(err)
+ log.Fatal(err)
}
}
}
}
- path := filepath.Join(dirPath, MetadataFile)
+ path := filepath.Join(dirPath, MDFile)
if err = WriteFileSync(dirPath, path, buf.Bytes(), now); err != nil {
log.Println("error", r.RemoteAddr, path, err)
http.Error(w, err.Error(), http.StatusInternalServerError)