mirror of
https://tvoygit.ru/Djam/r11_urpm-repo.git
synced 2025-02-23 10:12:46 +00:00
add file exists
This commit is contained in:
parent
140721e7fc
commit
a93af62172
1 changed files with 111 additions and 9 deletions
120
main.go
120
main.go
|
@ -1,15 +1,23 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/kardianos/service"
|
||||
"log"
|
||||
)
|
||||
|
||||
var srv service.Service
|
||||
var logger *log.Logger
|
||||
|
||||
func main() {
|
||||
viper.SetConfigName("config")
|
||||
|
@ -17,25 +25,21 @@ func main() {
|
|||
if err := viper.ReadInConfig(); err != nil {
|
||||
log.Fatalf("Error reading config file, %s", err)
|
||||
}
|
||||
|
||||
initLogger()
|
||||
|
||||
repo := NewRepository()
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Use(middleware.Logger)
|
||||
router.Use(authMiddleware)
|
||||
router.Post("/{arch}", repo.UploadHandler)
|
||||
|
||||
svcConfig := &service.Config{
|
||||
Name: "urpm-repo",
|
||||
DisplayName: "URPM Repository Service",
|
||||
Description: "Service for managing URPM packages",
|
||||
}
|
||||
|
||||
s, err := service.New(&serviceProgram{repo, router}, svcConfig)
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
|
||||
if len(os.Args) > 1 {
|
||||
if os.Args[1] == "install" {
|
||||
if err := s.Install(); err != nil {
|
||||
|
@ -49,15 +53,14 @@ func main() {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Run(); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
type serviceProgram struct {
|
||||
repo *Repository
|
||||
router *chi.Mux
|
||||
repo *Repository
|
||||
router *chi.Mux
|
||||
}
|
||||
|
||||
func (p *serviceProgram) Start(s service.Service) error {
|
||||
|
@ -73,4 +76,103 @@ func (p *serviceProgram) Start(s service.Service) error {
|
|||
func (p *serviceProgram) Stop(s service.Service) error {
|
||||
logger.Info("Stopping URPM Repository Service...")
|
||||
return nil
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
repoPath string
|
||||
}
|
||||
|
||||
func NewRepository() *Repository {
|
||||
return &Repository{
|
||||
repoPath: viper.GetString("repository.path"),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Repository) UploadHandler(w http.ResponseWriter, r *http.Request) {
|
||||
arch := chi.URLParam(r, "arch")
|
||||
file, header, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Вычисляем контрольную сумму загруженного файла
|
||||
hash := sha256.New()
|
||||
if _, err := io.Copy(hash, file); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
checksum := hex.EncodeToString(hash.Sum(nil))
|
||||
|
||||
// Проверяем, существует ли файл с такой контрольной суммой
|
||||
if r.fileExistsWithChecksum(arch, header.Filename, checksum) {
|
||||
logger.Info("File already exists with the same checksum, skipping upload.")
|
||||
w.WriteHeader(http.StatusConflict)
|
||||
fmt.Fprintf(w, "File already exists with the same checksum.")
|
||||
return
|
||||
}
|
||||
|
||||
// Возвращаемся к началу файла для записи
|
||||
file.Seek(0, 0)
|
||||
|
||||
// Сохраняем файл в репозиторий
|
||||
dstPath := fmt.Sprintf("%s/%s/%s", r.repoPath, arch, header.Filename)
|
||||
if err := os.MkdirAll(fmt.Sprintf("%s/%s", r.repoPath, arch), os.ModePerm); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
out, err := os.Create(dstPath)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
if _, err := io.Copy(out, file); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info("File uploaded successfully.")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, "File uploaded successfully.")
|
||||
}
|
||||
|
||||
func (r *Repository) fileExistsWithChecksum(arch, filename, checksum string) bool {
|
||||
filePath := fmt.Sprintf("%s/%s/%s", r.repoPath, arch, filename)
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
logger.Error(err)
|
||||
return false
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
hash := sha256.New()
|
||||
if _, err := io.Copy(hash, file); err != nil {
|
||||
logger.Error(err)
|
||||
return false
|
||||
}
|
||||
existingChecksum := hex.EncodeToString(hash.Sum(nil))
|
||||
|
||||
return existingChecksum == checksum
|
||||
}
|
||||
|
||||
func authMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
authToken := r.Header.Get("Authorization")
|
||||
expectedToken := viper.GetString("auth.token")
|
||||
if authToken != fmt.Sprintf("Bearer %s", expectedToken) {
|
||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func initLogger() {
|
||||
logger = log.New(os.Stdout, "", log.LstdFlags)
|
||||
}
|
Loading…
Add table
Reference in a new issue