purescript-contrib/purescript-affjax

Process hangs if request follows a redirection (node.js)

Opened this issue · 5 comments

Seems to be caused by the underlying lib xhr2.

main =
  launchAff $
  do res <- get "http://news.ycombinator.com"
     liftEff $ log res.response

This waits about 45 seconds after printing. Getting https://news.ycombinator.com works fine.

I already reported it to upstream but wanted to give you a heads up.

@osener Thanks for reporting!

xhr2 doesn't look very active. I guess the most popular Node lib is https://github.com/request/request, what do you think - how difficult would be a transition to that?

garyb commented

Well, it has a completely different interface so it's not ideal - reimplementing the interface on top of it probably wouldn't be that hard, but it would mean that the library would include a load of unnecessary code when used in the browser - currently there's only this.

I think this is an issue with Affjax, not the xhr2 module.

I executed this script on Node and in browser (without require statement), and both seemed to follow the redirect from "http://news.ycombinator.com" to "https://news.ycombinator.com".

var XMLHttpRequest = require("xhr2");
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", function () { console.log(this); });
oReq.open("GET", "http://news.ycombinator.com");
oReq.send();

But running purs repl with this performs poorly, as described by OP:

import Prelude
import Control.Monad.Eff
import Unsafe.Coerce 
import Control.Monad.Eff.Exception
import Control.Monad.Eff.Console
import Control.Monad.Eff.Class
import Control.Monad.Aff
import Network.HTTP.Affjax
void $ launchAff $ (get "http://news.ycombinator.com" :: Affjax _ String) >>= \res -> liftEff $ log $ show res.status <> " " <> show res.headers <> " " <> show res.response

I was using the previous Aff implementation, btw, v3.

Update: this issue still seems to exist. Here's the updated code for the REPL:

import Prelude
import Effect
import Effect.Aff
import Effect.Class
import Data.Bifunctor (lmap)
import Affjax
import Affjax.ResponseFormat 
launchAff_ $ get string "http://news.ycombinator.com" >>= \res -> liftEffect $ log $ show res.status <> " " <> show res.headers <> " " <> show (lmap printResponseFormatError res.body)

And here's code for Milkis if anyone is curious:

import Prelude
import Effect.Aff
import Milkis as M
import Milkis.Impl.Node (nodeFetch)
import Effect.Class.Console (log, logShow)
fetch = M.fetch nodeFetch
launchAff_ $ fetch (M.URL "http://news.ycombinator.com") M.defaultFetchOptions >>= M.text >>= log