Add a defer function to ensure the temporary file is closed and removed after the download is complete. Update the io.Copy to ignore errors to prevent panic in case of write failures.
106 lines
2.5 KiB
Go
106 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"ipa/IPAGo/models"
|
|
"ipa/IPAGo/wrapper"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/danielgtaylor/huma/v2"
|
|
"github.com/danielgtaylor/huma/v2/adapters/humago"
|
|
)
|
|
|
|
const (
|
|
version = "1.0.1"
|
|
)
|
|
|
|
func main() {
|
|
port := flag.Int("port", 8888, "Port to listen on")
|
|
flag.Parse()
|
|
|
|
mux := http.NewServeMux()
|
|
config := huma.DefaultConfig("IPAGo", version)
|
|
config.CreateHooks = nil
|
|
api := humago.New(mux, config)
|
|
|
|
huma.Get(
|
|
api, "/auth/login",
|
|
func(ctx context.Context, input *models.AuthInput) (*models.AuthOutput, error) {
|
|
output := &models.AuthOutput{}
|
|
output.Body.Success = wrapper.Auth(input.User, input.Pswd, input.Code)
|
|
return output, nil
|
|
})
|
|
|
|
huma.Get(
|
|
api, "/auth/info",
|
|
func(ctx context.Context, input *models.AuthInfoInput) (*models.AuthInfoOutput, error) {
|
|
output := &models.AuthInfoOutput{}
|
|
output.Body.Success = wrapper.AuthInfo(input.User, input.Pswd)
|
|
return output, nil
|
|
})
|
|
|
|
huma.Get(
|
|
api, "/search",
|
|
func(ctx context.Context, input *models.SearchInput) (*models.SearchOutput, error) {
|
|
output := &models.SearchOutput{}
|
|
output.Body.Apps = []wrapper.App{}
|
|
output.Body.Success = false
|
|
|
|
if input.Limit == 0 {
|
|
input.Limit = 1
|
|
}
|
|
if input.Query == "" {
|
|
return output, nil
|
|
}
|
|
|
|
apps, err := wrapper.Search(input.Query, input.Limit)
|
|
if err != nil {
|
|
return output, nil
|
|
}
|
|
|
|
output.Body.Success = true
|
|
output.Body.Apps = apps
|
|
return output, nil
|
|
})
|
|
|
|
huma.Get(
|
|
api, "/download",
|
|
func(ctx context.Context, input *models.DownloadInput) (*models.DownloadOutput, error) {
|
|
outputPath := filepath.Join(os.TempDir(), fmt.Sprintf("%s.ipa", time.Now().Format("20060102150405")))
|
|
output := &models.DownloadOutput{}
|
|
if input.BundleID == "" {
|
|
return nil, errors.New("bundleID is empty")
|
|
}
|
|
success := wrapper.Download(input.BundleID, outputPath)
|
|
if !success {
|
|
return nil, errors.New("failed to download")
|
|
}
|
|
output.ContentDisposition = fmt.Sprintf("attachment; filename=%s", filepath.Base(outputPath))
|
|
output.ContentType = "application/octet-stream"
|
|
output.Body = func(hctx huma.Context) {
|
|
file, err := os.Open(outputPath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer func() {
|
|
file.Close()
|
|
os.Remove(outputPath)
|
|
fmt.Println("File removed after download")
|
|
}()
|
|
_, _ = io.Copy(hctx.BodyWriter(), file)
|
|
}
|
|
return output, nil
|
|
})
|
|
|
|
addr := fmt.Sprintf(":%d", *port)
|
|
fmt.Printf("Server is running on %s\n", addr)
|
|
http.ListenAndServe(addr, mux)
|
|
}
|