11package api
22
33import (
4+ "context"
5+ "errors"
46 "fmt"
57 "log/slog"
68 "net/http"
@@ -64,20 +66,26 @@ func HandleGetRender(browser *service.BrowserService) http.Handler {
6466 }
6567 options = append (options , service .WithViewport (width , height ))
6668 if timeout := r .URL .Query ().Get ("timeout" ); timeout != "" {
69+ var dur time.Duration
6770 if regexpOnlyNumbers .MatchString (timeout ) {
6871 seconds , err := strconv .Atoi (timeout )
6972 if err != nil {
7073 http .Error (w , fmt .Sprintf ("invalid 'timeout' query parameter: %v" , err ), http .StatusBadRequest )
7174 return
7275 }
73- options = append ( options , service . WithTimeout ( time .Duration (seconds )* time .Second ))
76+ dur = time .Duration (seconds ) * time .Second
7477 } else {
75- timeout , err := time .ParseDuration (timeout )
78+ var err error
79+ dur , err = time .ParseDuration (timeout )
7680 if err != nil {
7781 http .Error (w , fmt .Sprintf ("invalid 'timeout' query parameter: %v" , err ), http .StatusBadRequest )
7882 return
7983 }
80- options = append (options , service .WithTimeout (timeout ))
84+ }
85+ if dur > 0 {
86+ timeoutCtx , cancelTimeout := context .WithTimeout (ctx , dur )
87+ defer cancelTimeout ()
88+ ctx = timeoutCtx
8189 }
8290 }
8391 if scaleFactor := r .URL .Query ().Get ("deviceScaleFactor" ); scaleFactor != "" {
@@ -105,6 +113,7 @@ func HandleGetRender(browser *service.BrowserService) http.Handler {
105113 options = append (options , service .WithCookie ("renderKey" , renderKey , domain ))
106114 }
107115 encoding := r .URL .Query ().Get ("encoding" )
116+ var printer service.Printer
108117 switch encoding {
109118 case "" , "pdf" :
110119 var printerOpts []service.PDFPrinterOption
@@ -141,7 +150,12 @@ func HandleGetRender(browser *service.BrowserService) http.Handler {
141150 printerOpts = append (printerOpts , service .WithPageRanges (pageRanges ))
142151 }
143152
144- options = append (options , service .WithPDFPrinter (printerOpts ... ))
153+ var err error
154+ printer , err = service .NewPDFPrinter (printerOpts ... )
155+ if err != nil {
156+ http .Error (w , fmt .Sprintf ("invalid request: %v" , err ), http .StatusBadRequest )
157+ return
158+ }
145159
146160 if pdfLandscape := r .URL .Query ().Get ("pdfLandscape" ); pdfLandscape != "" {
147161 options = append (options , service .WithLandscape (pdfLandscape == "true" ))
@@ -152,7 +166,13 @@ func HandleGetRender(browser *service.BrowserService) http.Handler {
152166 printerOpts = append (printerOpts , service .WithFullHeight (true ))
153167 options = append (options , service .WithViewport (width , 1080 )) // add some height to make scrolling faster
154168 }
155- options = append (options , service .WithPNGPrinter (printerOpts ... ))
169+
170+ var err error
171+ printer , err = service .NewPNGPrinter (printerOpts ... )
172+ if err != nil {
173+ http .Error (w , fmt .Sprintf ("invalid request: %v" , err ), http .StatusBadRequest )
174+ return
175+ }
156176 default :
157177 http .Error (w , fmt .Sprintf ("invalid 'encoding' query parameter: %q" , encoding ), http .StatusBadRequest )
158178 return
@@ -162,9 +182,17 @@ func HandleGetRender(browser *service.BrowserService) http.Handler {
162182 }
163183
164184 start := time .Now ()
165- body , contentType , err := browser .Render (ctx , rawTargetURL , options ... )
185+ body , contentType , err := browser .Render (ctx , rawTargetURL , printer , options ... )
166186 if err != nil {
167187 MetricRenderDuration .WithLabelValues ("error" ).Observe (time .Since (start ).Seconds ())
188+ if errors .Is (err , context .DeadlineExceeded ) ||
189+ errors .Is (err , context .Canceled ) {
190+ http .Error (w , "Request timed out" , http .StatusRequestTimeout )
191+ return
192+ } else if errors .Is (err , service .ErrInvalidBrowserOption ) {
193+ http .Error (w , fmt .Sprintf ("invalid request: %v" , err ), http .StatusBadRequest )
194+ return
195+ }
168196 slog .ErrorContext (ctx , "failed to render" , "error" , err )
169197 http .Error (w , "Failed to render" , http .StatusInternalServerError )
170198 return
0 commit comments