2022-01-08 20:47:08 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"heckel.io/ntfy/util"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"path"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2022-01-10 18:38:51 +00:00
|
|
|
peakAttachmentTimeout = 2500 * time.Millisecond
|
|
|
|
peakAttachmentReadBytes = 128
|
2022-01-08 20:47:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2022-01-10 18:38:51 +00:00
|
|
|
buf := make([]byte, peakAttachmentReadBytes)
|
|
|
|
io.ReadFull(resp.Body, buf) // Best effort: We don't care about the error
|
|
|
|
mimeType, ext := util.DetectContentType(buf, m.Attachment.URL)
|
2022-01-08 20:47:08 +00:00
|
|
|
m.Attachment.Type = resp.Header.Get("Content-Type")
|
2022-01-10 18:38:51 +00:00
|
|
|
if m.Attachment.Type == "" {
|
|
|
|
m.Attachment.Type = mimeType
|
2022-01-08 20:47:08 +00:00
|
|
|
}
|
|
|
|
if m.Attachment.Name == "" {
|
|
|
|
u, err := url.Parse(m.Attachment.URL)
|
|
|
|
if err != nil {
|
2022-01-10 18:38:51 +00:00
|
|
|
m.Attachment.Name = fmt.Sprintf("attachment%s", ext)
|
2022-01-08 20:47:08 +00:00
|
|
|
} else {
|
|
|
|
m.Attachment.Name = path.Base(u.Path)
|
|
|
|
if m.Attachment.Name == "." || m.Attachment.Name == "/" {
|
2022-01-10 18:38:51 +00:00
|
|
|
m.Attachment.Name = fmt.Sprintf("attachment%s", ext)
|
2022-01-08 20:47:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|