Improve HTTP handling (timeouts etc.)

This commit is contained in:
Jan-Lukas Else 2021-03-31 09:29:52 +02:00
parent f378395d5d
commit 7f8ea2d94b
9 changed files with 64 additions and 17 deletions

View File

@ -8,6 +8,7 @@ import (
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"io"
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
@ -260,17 +261,19 @@ func apGetRemoteActor(iri string) (*asPerson, int, error) {
} }
req.Header.Set("Accept", contentTypeAS) req.Header.Set("Accept", contentTypeAS)
req.Header.Set(userAgent, appUserAgent) req.Header.Set(userAgent, appUserAgent)
resp, err := http.DefaultClient.Do(req) resp, err := appHttpClient.Do(req)
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
defer resp.Body.Close()
if !apRequestIsSuccess(resp.StatusCode) { if !apRequestIsSuccess(resp.StatusCode) {
_, _ = io.Copy(io.Discard, resp.Body)
return nil, resp.StatusCode, nil return nil, resp.StatusCode, nil
} }
actor := &asPerson{} actor := &asPerson{}
err = json.NewDecoder(resp.Body).Decode(actor) err = json.NewDecoder(resp.Body).Decode(actor)
defer resp.Body.Close()
if err != nil { if err != nil {
_, _ = io.Copy(io.Discard, resp.Body)
return nil, 0, err return nil, 0, err
} }
return actor, 0, nil return actor, 0, nil

View File

@ -124,14 +124,16 @@ func apSendSigned(blogIri, to string, activity []byte) error {
return err return err
} }
// Do request // Do request
resp, err := http.DefaultClient.Do(r) resp, err := appHttpClient.Do(r)
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close()
if !apRequestIsSuccess(resp.StatusCode) { if !apRequestIsSuccess(resp.StatusCode) {
body, _ := io.ReadAll(resp.Body) body, _ := io.ReadAll(resp.Body)
_ = resp.Body.Close()
return fmt.Errorf("signed request failed with status %d: %s", resp.StatusCode, string(body)) return fmt.Errorf("signed request failed with status %d: %s", resp.StatusCode, string(body))
} else {
_, _ = io.Copy(io.Discard, resp.Body)
} }
return nil return nil
} }

View File

@ -9,6 +9,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time"
"github.com/caddyserver/certmagic" "github.com/caddyserver/certmagic"
"github.com/dchest/captcha" "github.com/dchest/captcha"
@ -86,7 +87,13 @@ func startServer() (err error) {
} }
err = certmagic.HTTPS(hosts, finalHandler) err = certmagic.HTTPS(hosts, finalHandler)
} else { } else {
err = http.ListenAndServe(localAddress, finalHandler) s := &http.Server{
Addr: localAddress,
Handler: finalHandler,
ReadTimeout: 5 * time.Minute,
WriteTimeout: 5 * time.Minute,
}
err = s.ListenAndServe()
} }
return return
} }

13
httpClient.go Normal file
View File

@ -0,0 +1,13 @@
package main
import (
"net/http"
"time"
)
var appHttpClient = &http.Client{
Timeout: 5 * time.Minute,
Transport: &http.Transport{
DisableKeepAlives: true,
},
}

View File

@ -116,8 +116,13 @@ func uploadToBunny(filename string, f io.Reader, config *configMicropubMedia) (l
} }
req, _ := http.NewRequest(http.MethodPut, fmt.Sprintf("https://storage.bunnycdn.com/%s/%s", url.PathEscape(config.BunnyStorageName), url.PathEscape(filename)), f) req, _ := http.NewRequest(http.MethodPut, fmt.Sprintf("https://storage.bunnycdn.com/%s/%s", url.PathEscape(config.BunnyStorageName), url.PathEscape(filename)), f)
req.Header.Add("AccessKey", config.BunnyStorageKey) req.Header.Add("AccessKey", config.BunnyStorageKey)
resp, err := http.DefaultClient.Do(req) resp, err := appHttpClient.Do(req)
if err != nil || resp.StatusCode != http.StatusCreated { if err != nil {
return "", err
}
defer resp.Body.Close()
_, _ = io.Copy(io.Discard, resp.Body)
if resp.StatusCode != http.StatusCreated {
return "", errors.New("failed to upload file to BunnyCDN") return "", errors.New("failed to upload file to BunnyCDN")
} }
return config.MediaURL + "/" + filename, nil return config.MediaURL + "/" + filename, nil
@ -191,22 +196,26 @@ func shortPixel(url string, config *configMicropubMedia) (location string, err e
if err != nil { if err != nil {
return "", err return "", err
} }
resp, err := http.DefaultClient.Do(req) resp, err := appHttpClient.Do(req)
if err != nil { if err != nil {
return "", err return "", err
} else if resp.StatusCode != http.StatusOK { }
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
_, _ = io.Copy(io.Discard, resp.Body)
return "", fmt.Errorf("failed to compress image, status code %d", resp.StatusCode) return "", fmt.Errorf("failed to compress image, status code %d", resp.StatusCode)
} }
tmpFile, err := os.CreateTemp("", "tiny-*."+fileExtension) tmpFile, err := os.CreateTemp("", "tiny-*."+fileExtension)
if err != nil { if err != nil {
_, _ = io.Copy(io.Discard, resp.Body)
return "", err return "", err
} }
defer func() { defer func() {
_ = resp.Body.Close()
_ = tmpFile.Close() _ = tmpFile.Close()
_ = os.Remove(tmpFile.Name()) _ = os.Remove(tmpFile.Name())
}() }()
if _, err = io.Copy(tmpFile, resp.Body); err != nil { if _, err = io.Copy(tmpFile, resp.Body); err != nil {
_, _ = io.Copy(io.Discard, resp.Body)
return "", err return "", err
} }
fileName, err := getSHA256(tmpFile) fileName, err := getSHA256(tmpFile)

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"io"
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
@ -66,10 +67,13 @@ func sendTelegramMessage(message, mode, token, chat string) error {
} }
tgURL.RawQuery = params.Encode() tgURL.RawQuery = params.Encode()
req, _ := http.NewRequest(http.MethodPost, tgURL.String(), nil) req, _ := http.NewRequest(http.MethodPost, tgURL.String(), nil)
resp, err := http.DefaultClient.Do(req) resp, err := appHttpClient.Do(req)
if err != nil { if err != nil {
return err return err
} else if resp.StatusCode != http.StatusOK { }
defer resp.Body.Close()
_, _ = io.Copy(io.Discard, resp.Body)
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to send Telegram message, status code %d", resp.StatusCode) return fmt.Errorf("failed to send Telegram message, status code %d", resp.StatusCode)
} }
return nil return nil

7
tor.go
View File

@ -77,5 +77,10 @@ func startOnionService(h http.Handler) error {
torAddress = onion.String() torAddress = onion.String()
log.Println("Onion service published on http://" + torAddress) log.Println("Onion service published on http://" + torAddress)
// Serve handler // Serve handler
return http.Serve(onion, h) s := &http.Server{
Handler: h,
ReadTimeout: 5 * time.Minute,
WriteTimeout: 5 * time.Minute,
}
return s.Serve(onion)
} }

View File

@ -62,10 +62,12 @@ func sendWebmention(endpoint, source, target string) (*http.Response, error) {
} }
req.Header.Set(contentType, contentTypeWWWForm) req.Header.Set(contentType, contentTypeWWWForm)
req.Header.Set(userAgent, appUserAgent) req.Header.Set(userAgent, appUserAgent)
res, err := http.DefaultClient.Do(req) res, err := appHttpClient.Do(req)
if err != nil { if err != nil {
return res, err return res, err
} }
defer res.Body.Close()
_, _ = io.Copy(io.Discard, res.Body)
if code := res.StatusCode; code < 200 || 300 <= code { if code := res.StatusCode; code < 200 || 300 <= code {
return res, fmt.Errorf("response error: %v", res.StatusCode) return res, fmt.Errorf("response error: %v", res.StatusCode)
} }
@ -79,16 +81,18 @@ func discoverEndpoint(urlStr string) string {
return "" return ""
} }
req.Header.Set(userAgent, appUserAgent) req.Header.Set(userAgent, appUserAgent)
resp, err := http.DefaultClient.Do(req) resp, err := appHttpClient.Do(req)
if err != nil { if err != nil {
return "" return ""
} }
defer resp.Body.Close()
if code := resp.StatusCode; code < 200 || 300 <= code { if code := resp.StatusCode; code < 200 || 300 <= code {
_, _ = io.Copy(io.Discard, resp.Body)
return "" return ""
} }
defer resp.Body.Close()
endpoint, err := extractEndpoint(resp) endpoint, err := extractEndpoint(resp)
if err != nil || endpoint == "" { if err != nil || endpoint == "" {
_, _ = io.Copy(io.Discard, resp.Body)
return "" return ""
} }
if urls, err := resolveURLReferences(urlStr, endpoint); err == nil && len(urls) > 0 && urls[0] != "" { if urls, err := resolveURLReferences(urlStr, endpoint); err == nil && len(urls) > 0 && urls[0] != "" {

View File

@ -79,7 +79,7 @@ func (m *mention) verifyMention() error {
c, _ := createTokenCookie() c, _ := createTokenCookie()
req.AddCookie(c) req.AddCookie(c)
} }
resp, err := http.DefaultClient.Do(req) resp, err := appHttpClient.Do(req)
if err != nil { if err != nil {
return err return err
} }