Properly handle different attachment use cases
This commit is contained in:
parent
cefe276ce5
commit
44a9509cd6
7 changed files with 202 additions and 75 deletions
68
server/util.go
Normal file
68
server/util.go
Normal file
|
@ -0,0 +1,68 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"heckel.io/ntfy/util"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
peakAttachmentTimeout = 2500 * time.Millisecond
|
||||
peakAttachmeantReadBytes = 128
|
||||
)
|
||||
|
||||
func maybePeakAttachmentURL(m *message) error {
|
||||
return maybePeakAttachmentURLInternal(m, peakAttachmentTimeout)
|
||||
}
|
||||
|
||||
func maybePeakAttachmentURLInternal(m *message, timeout time.Duration) error {
|
||||
if m.Attachment == nil || m.Attachment.URL == "" {
|
||||
return nil
|
||||
}
|
||||
client := http.Client{
|
||||
Timeout: timeout,
|
||||
Transport: &http.Transport{
|
||||
DisableCompression: true, // Disable "Accept-Encoding: gzip", otherwise we won't get the Content-Length
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
},
|
||||
}
|
||||
req, err := http.NewRequest(http.MethodGet, m.Attachment.URL, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("User-Agent", "ntfy")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return errHTTPBadRequestAttachmentURLPeakGeneral
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||
return errHTTPBadRequestAttachmentURLPeakNon2xx
|
||||
}
|
||||
if size, err := strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 64); err == nil {
|
||||
m.Attachment.Size = size
|
||||
}
|
||||
m.Attachment.Type = resp.Header.Get("Content-Type")
|
||||
if m.Attachment.Type == "" || m.Attachment.Type == "application/octet-stream" {
|
||||
buf := make([]byte, peakAttachmeantReadBytes)
|
||||
io.ReadFull(resp.Body, buf) // Best effort: We don't care about the error
|
||||
m.Attachment.Type = http.DetectContentType(buf)
|
||||
}
|
||||
if m.Attachment.Name == "" {
|
||||
u, err := url.Parse(m.Attachment.URL)
|
||||
if err != nil {
|
||||
m.Attachment.Name = fmt.Sprintf("attachment%s", util.ExtensionByType(m.Attachment.Type))
|
||||
} else {
|
||||
m.Attachment.Name = path.Base(u.Path)
|
||||
if m.Attachment.Name == "." || m.Attachment.Name == "/" {
|
||||
m.Attachment.Name = fmt.Sprintf("attachment%s", util.ExtensionByType(m.Attachment.Type))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue