diff --git a/backend/app/notify/telegram.go b/backend/app/notify/telegram.go
index 61a9d159..5e13e738 100644
--- a/backend/app/notify/telegram.go
+++ b/backend/app/notify/telegram.go
@@ -42,7 +42,10 @@ func NewTelegram(token string, channelID string, timeout time.Duration, api stri
}
log.Printf("[DEBUG] create new telegram notifier for cham %s, timeout=%s, api=%s", channelID, res.timeout, res.timeout)
- err := repeater.NewDefault(5, time.Millisecond*250).Do(func() error {
+ ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
+ defer cancel()
+
+ err := repeater.NewDefault(5, time.Millisecond*250).Do(ctx, func() error {
client := http.Client{Timeout: telegramTimeOut}
resp, err := client.Get(fmt.Sprintf("%s%s/getMe", res.apiPrefix, token))
if err != nil {
diff --git a/backend/app/rest/proxy/image.go b/backend/app/rest/proxy/image.go
index 17160658..5ad0b805 100644
--- a/backend/app/rest/proxy/image.go
+++ b/backend/app/rest/proxy/image.go
@@ -1,6 +1,7 @@
package proxy
import (
+ "context"
"encoding/base64"
"io"
"net/http"
@@ -22,6 +23,7 @@ type Image struct {
RemarkURL string
RoutePath string
Enabled bool
+ Timeout time.Duration
}
// Convert all img src links without https to proxied links
@@ -51,11 +53,23 @@ func (p Image) Routes() chi.Router {
return
}
+ timeout := 60 * time.Second // default
+ if p.Timeout > 0 {
+ timeout = p.Timeout
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), timeout)
+ defer cancel()
+
client := http.Client{Timeout: 30 * time.Second}
var resp *http.Response
- err = repeater.NewDefault(5, time.Second).Do(func() error {
+ err = repeater.NewDefault(5, time.Second).Do(ctx, func() error {
var e error
- resp, e = client.Get(string(src))
+ req, e := http.NewRequest("GET", string(src), nil)
+ if e != nil {
+ return errors.Wrapf(e, "failed to make request for %s", r.URL.Query().Get("src"))
+ }
+ resp, e = client.Do(req.WithContext(ctx))
return e
})
if err != nil {
diff --git a/backend/app/rest/proxy/image_test.go b/backend/app/rest/proxy/image_test.go
index b7b90098..dc8eae0c 100644
--- a/backend/app/rest/proxy/image_test.go
+++ b/backend/app/rest/proxy/image_test.go
@@ -3,9 +3,12 @@ package proxy
import (
"encoding/base64"
"fmt"
+ "io/ioutil"
"net/http"
"net/http/httptest"
+ "strings"
"testing"
+ "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -87,6 +90,25 @@ func TestImage_Routes(t *testing.T) {
assert.Equal(t, 400, resp.StatusCode)
}
+func TestImage_RoutesTimedOut(t *testing.T) {
+ img := Image{Enabled: true, RemarkURL: "https://demo.remark42.com", RoutePath: "/api/v1/proxy", Timeout: 50 * time.Millisecond}
+ router := img.Routes()
+
+ httpSrv := imgHTTPServer(t)
+ defer httpSrv.Close()
+ ts := httptest.NewServer(router)
+ defer ts.Close()
+
+ encodedImgURL := base64.URLEncoding.EncodeToString([]byte(httpSrv.URL + "/image/img-slow.png"))
+ resp, err := http.Get(ts.URL + "/?src=" + encodedImgURL)
+ require.Nil(t, err)
+ assert.Equal(t, 400, resp.StatusCode)
+ b, err := ioutil.ReadAll(resp.Body)
+ require.Nil(t, err)
+ t.Log(string(b))
+ assert.True(t, strings.Contains(string(b), "deadline exceeded"))
+}
+
func TestPicture_Convert(t *testing.T) {
img := Image{Enabled: true, RoutePath: "/img"}
r := img.Convert(`
xyz
`)
@@ -113,6 +135,11 @@ func imgHTTPServer(t *testing.T) *httptest.Server {
w.Write([]byte(fmt.Sprintf("%123s", "X")))
return
}
+ if r.URL.Path == "/image/img-slow.png" {
+ time.Sleep(500 * time.Millisecond)
+ w.WriteHeader(500)
+ return
+ }
t.Log("http img request - not found", r.URL)
w.WriteHeader(404)
}))