Files
moteva/server/internal/infrastructure/objectstorage/url.go
T
root 44406b72db Initial commit: img-infinite-canvas AI design workbench MVP
Moteva-style AI design workbench replica. Home prompt creates a project;
the project page provides an infinite canvas with node drag, zoom/pan,
a design chat panel, history replay, image asset upload, and project
save/regenerate.

- Backend: go-zero, DDD layering, sqlc/pgx, optional PostgreSQL; memory
  or Redis cache; asynq job queue; MinIO/S3/R2/OSS object storage;
  sky-valley/pi agent runtime adapter.
- Frontend: Next.js App Router + Vite artifact build, TypeScript, i18n,
  shadcn/ui components, auth (OTP/Turnstile/Google/WeChat).
- Deploy: Docker Compose and k3s manifests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 23:15:37 +08:00

46 lines
1.1 KiB
Go

package objectstorage
import (
"net/url"
"strings"
)
func objectKeyFromPublicURL(publicBase string, value string) (string, bool) {
value = strings.TrimSpace(value)
publicBase = strings.TrimRight(strings.TrimSpace(publicBase), "/")
if value == "" || publicBase == "" {
return "", false
}
if strings.HasPrefix(value, publicBase+"/") {
return unescapeObjectKey(strings.TrimPrefix(strings.Split(value, "?")[0], publicBase+"/"))
}
parsedValue, err := url.Parse(value)
if err != nil {
return "", false
}
parsedBase, err := url.Parse(publicBase)
if err != nil {
return "", false
}
basePath := strings.TrimRight(parsedBase.EscapedPath(), "/")
valuePath := parsedValue.EscapedPath()
if basePath == "" || !strings.HasPrefix(valuePath, basePath+"/") {
return "", false
}
return unescapeObjectKey(strings.TrimPrefix(valuePath, basePath+"/"))
}
func unescapeObjectKey(value string) (string, bool) {
value = strings.TrimLeft(strings.TrimSpace(value), "/")
if value == "" {
return "", false
}
objectKey, err := url.PathUnescape(value)
if err != nil {
return "", false
}
return objectKey, objectKey != ""
}