Angesichts eines freigegebenen HTTP-Manager scheint es, wenn die requestBody
vom Typ requestBodySource
ist und wenn falsche Länge für den Anfragetext angegeben wird, dann nachfolgende Anfragen auf demselben HTTP Mist Manager für etwa 20 Sekunden. Es scheint etwas über die Interaktion von Shared State und GivesPopper
zu sein, das dieses Problem verursacht. Hier ist ein Beispielcode, der es reproduziert - wir verwenden requestb.in für den Upload falscher Länge und versuchen dann, eine andere gültige URL auf requestb.in zu lesen.Beschädigte HTTP-Manager-Status beim Senden falsche Länge für Stream
{-# LANGUAGE OverloadedStrings #-}
import Data.Conduit.Binary (sourceFile)
import Network.HTTP.Conduit
import Network.HTTP.Types
import qualified Data.ByteString.Lazy as LBS
import System.IO
import Control.Monad.Trans.Resource (runResourceT)
import Control.Concurrent.Async (async,waitCatch)
import Control.Exception (displayException)
main :: IO()
main = do
{- Set up a ResourceT region with an available HTTP manager. -}
httpmgr <- newManager tlsManagerSettings
httpmgr2 <- newManager tlsManagerSettings
let file ="out" -- some byte contents with length > 1
lenb <- System.IO.withFile file ReadMode hFileSize
let inbytes = sourceFile file
initReq <- parseUrl "http://requestb.in/saxbx3sa"
putreq <- async $ runResourceT $ do
let req = initReq { method = "POST",
-- let us send wrong length in requestBodySource
requestBody = (requestBodySource (fromIntegral $ lenb - 1) inbytes)}
resp <- httpLbs req httpmgr
return (statusCode . responseStatus $ resp)
putreqRes <- waitCatch putreq
case putreqRes of
Left e -> print $ displayException $ e
Right r -> print $ r
getreq <- async $ runResourceT $ do
-- Let us do a GET on a different resource to see if it works
initReq <- parseUrl "http://requestb.in/1l15sz21"
let req = initReq { method = "GET"}
resp <- httpLbs req httpmgr
return (statusCode . responseStatus $ resp)
getreqRes <- waitCatch getreq
case getreqRes of
Left e -> print $ displayException $ e
Right r -> print $ r
Ausgang - erster schlechter Upload geht als HTTP 200
durch und nachfolgenden GET
Anfrage verursacht sofort HTTP 400
Fehler:
*Main> main
200
"StatusCodeException (Status {statusCode = 400, statusMessage = \"Bad Request\"})
[(\"Date\",\"Wed, 29 Jun 2016 11:54:59 GMT\"),(\"Content-Type\",\"text/html\"),
(\"Content-Length\",\"177\"),(\"Connection\",\"close\"),(\"Server\",\"-nginx\"),
(\"CF-RAY\",\"-\"),(\"X-Response-Body-Start\",\"<html>\\r\\n<head><title>400 Bad
Request</title></head>\\r\\n<body bgcolor=\\\"white\\\">\\r\\n<center><h1>400 Bad
Request</h1></center>\\r\\n<hr><center>cloudflare-
nginx</center>\\r\\n</body>\\r\\n</html>\\r\\n\"),(\"X-Request-URL\",\"GET
http://requestb.in:80/saxbx3sa\")] (CJ {expose = []})"
einen anderen HTTP-Manager wird stattdessen für GET
Anfrage HTTP 200
zurückzukehren. Also, Shared-Status im HTTP-Manager scheint hier das Problem zu sein.
Hat jemand anderes es beobachtet? Ich ging durch github Probleme für HTTP Manager
, aber habe nicht gesehen, dass dies gemeldet wurde. Bei falscher Streaming-Länge sollte das Verhalten nicht dazu führen, den HTTP-Manager zu beschädigen, wie es hier scheint.
Ich habe auch eine Quelldatei für requestBodySource simuliert, bei der die Länge korrekt ist, aber die Quelle aufgrund eines simulierten Fehlers in der Mitte abbricht (um Netzwerkprobleme zu simulieren). In diesem Fall gibt es keine Fehler. Es scheint also nur einen Fall zu geben, in dem das Senden einer falschen Länge ohne Fehler dazu führt, dass eine Art gemeinsamer Status hier beschädigt wird, der innerhalb von 25 Sekunden freigegeben wird.
Wenn jemand irgendwelche Einsichten darüber hat, was hier vor sich geht, wird es sehr hilfreich sein. Ich habe einen Workaround zur Durchsetzung der richtigen Streaming-Länge. Ich werde jedoch gerne verstehen, was vor sich geht, damit ich in der Produktion nicht in diese Situation geraten kann.
Wahrscheinlich würde bessere Hilfe beim Öffnen eines 'http-Conduit'-Problems bekommen – jberryman
Sicher, geöffnet ... zum Zeitpunkt des Postings war ich nicht sicher, ob es ein Bug oder eine falsche Verwendung der Streaming-Funktion auf meinem war Teil. – Sal