From 862ec3f7bc27213da3faf67d21c89b95ee5d5071 Mon Sep 17 00:00:00 2001 From: Joakim Olsson Date: Thu, 16 Apr 2026 08:52:38 +0000 Subject: [PATCH] feat: add PresignInlineURL method for inline content display (#97) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add `PresignInlineURL(ctx, key, contentType)` method that generates presigned URLs with `Content-Disposition: inline` and optional `Content-Type` override - Browsers will render content (e.g. PDFs) directly in iframes instead of triggering download dialogs - Existing `PresignURL` remains unchanged ## Context The document-service uses presigned S3 URLs to display PDFs in iframes. Without `Content-Disposition: inline`, the browser triggers a download dialog instead of rendering the PDF. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: https://gitea.unbound.se/unboundsoftware/storage/pulls/97 --- s3.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/s3.go b/s3.go index 0a3a266..e7abdb8 100644 --- a/s3.go +++ b/s3.go @@ -105,6 +105,25 @@ func (s *S3) PresignURL(ctx context.Context, key string) (string, error) { return req.URL, nil } +// PresignInlineURL generates a presigned URL that tells the browser to display +// the content inline rather than triggering a download. The URL is valid for +// 15 minutes. +func (s *S3) PresignInlineURL(ctx context.Context, key string, contentType string) (string, error) { + input := &s3.GetObjectInput{ + Bucket: aws.String(s.bucket), + Key: aws.String(key), + ResponseContentDisposition: aws.String("inline"), + } + if contentType != "" { + input.ResponseContentType = aws.String(contentType) + } + req, err := s.presigner.PresignGetObject(ctx, input, s3.WithPresignExpires(15*time.Minute)) + if err != nil { + return "", err + } + return req.URL, nil +} + // New creates a new S3 storage instance using the upload manager // This loads AWS config from the default locations and is suitable for most use cases func New(bucket string) (*S3, error) {