Stack connection failure

I am on arch linux and I installed stack through ghcup. However, running stack always results in a connection failure.

stack update --verbose
Version 2.9.1, Git revision 409d56031b4240221d656db09b2ba476fe6bb5b1 x86_64 hpack-0.35.0
2022-12-28 10:20:54.442871: [debug] Checking for project config at: /home/mechap/stack.yaml
2022-12-28 10:20:54.443596: [debug] Checking for project config at: /home/stack.yaml
2022-12-28 10:20:54.443634: [debug] Checking for project config at: /stack.yaml
2022-12-28 10:20:54.443661: [debug] No project config file found, using defaults.
2022-12-28 10:20:54.454144: [debug] (SQL) SELECT COUNT(*) FROM "last_performed" WHERE ("action"=?) AND ("timestamp">=?); [PersistInt64 1,PersistUTCTime 2022-12-27 09:20:54.453673226 UTC]
2022-12-28 10:20:54.456163: [info] Selected mirror https://hackage.haskell.org/
2022-12-28 10:20:54.456258: [info] Downloading root
2022-12-28 10:20:59.463542: [error] HttpExceptionRequest Request {
  host                 = "hackage.haskell.org"
  port                 = 443
  secure               = True
  requestHeaders       = [("Accept-Encoding",""),("User-Agent","Haskell pantry package")]
  path                 = "/root.json"
  queryString          = ""
  method               = "GET"
  proxy                = Nothing
  rawBody              = False
  redirectCount        = 10
  responseTimeout      = ResponseTimeoutDefault
  requestVersion       = HTTP/1.1
  proxySecureMode      = ProxySecureWithConnect
}
 (ConnectionFailure Network.Socket.getAddrInfo (called with preferred socket type/protocol: AddrInfo {addrFlags = [AI_ADDRCONFIG], addrFamily = AF_UNSPEC, addrSocketType = Stream, addrProtocol = 0, addrAddress = 0.0.0.0:0, addrCanonName = Nothing}, host name: Just "hackage.haskell.org", service name: Just "443"): does not exist (Try again))

While

curl -I https://hackage.haskell.org:443/root.json
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 4216
Server: nginx/1.18.0 (Ubuntu)
Content-Type: application/json
Cache-Control: public, no-transform, max-age=60
Content-MD5: MKHLRXfk9A1kOc9X0OA7Jg==
ETag: "30a1cb4577e4f40d6439cf57d0e03b26"
Accept-Ranges: bytes
Date: Wed, 28 Dec 2022 09:24:43 GMT
Via: 1.1 varnish
Age: 0
X-Served-By: cache-cdg20728-CDG
X-Cache: HIT
X-Cache-Hits: 1
X-Timer: S1672219483.965029,VS0,VE459
Vary: Accept-Encoding

Is your network behind a proxy? Perhaps stack is not configured to use it…

1 Like

Stack’s online documentation says this about HTTP proxies: Install/upgrade - The Haskell Tool Stack.

(EDIT #1: However, now I look at the parser of the contents of the environment variable at Network.HTTP.Client.TLS.parseSocksSettings, I think that online documentation may not be accurate complete:

parseSocksSettings :: [(String, String)] -- ^ original environment
                   -> Map.Map T.Text String -- ^ lower-cased keys
                   -> T.Text -- ^ env name
                   -> Maybe NC.SockSettings
parseSocksSettings env lenv n = do
  str <- lookup (T.unpack n) env <|> Map.lookup n lenv
  let allowedScheme x = x == "socks5:" || x == "socks5h:"
  uri <- U.parseURI str

  guard $ allowedScheme $ U.uriScheme uri
  guard $ null (U.uriPath uri) || U.uriPath uri == "/"
  guard $ null $ U.uriQuery uri
  guard $ null $ U.uriFragment uri

  auth <- U.uriAuthority uri
  port' <-
      case U.uriPort auth of
          "" -> Nothing -- should we use some default?
          ':':rest ->
              case decimal $ T.pack rest of
                  Right (p, "") -> Just p
                  _ -> Nothing
          _ -> Nothing

  Just $ NC.SockSettingsSimple (U.uriRegName auth) port'

I think, from guard $ allowedScheme $ U.uriScheme uri, that requires a URI that starts with a scheme “socks5:” or “socks5h:”.

EDIT #2: There is also Network.HTTP.Proxy.envHelper https://hackage.haskell.org/package/http-client-0.7.11/docs/src/Network.HTTP.Proxy.html#envHelper, that requires a URI that starts with scheme “http:” and tries again with "http://" ++ str if that does not work.)

The underlying library that Stack depends on respects environment variables http_proxy and https_proxy at Network.HTTP.Client.TLS.newTlsManagerWith: https://hackage.haskell.org/package/http-client-tls-0.3.6.1/docs/src/Network.HTTP.Client.TLS.html#newTlsManagerWith.

stack should really use curl instead of a haskell http library for fetching. It’s the most portable way. Parsing incoming headers is a bit awkward, but also possible.

1 Like

I am not, I didn’t define proxy environment variables that mpilgrem mentionned.

If you can use something other than Stack to build Haskell code, perhaps we could explore what happens with a minimum test program? Something like:

{-# LANGUAGE QuasiQuotes #-}
module Main (main) where

-- from base package
import Control.Monad ( void )
-- from rio-prettyprint package
import RIO.PrettyPrint.Simple ( runSimplePrettyApp )
-- from http-client package
import Network.HTTP.Client ( parseRequest )
-- from http-download package
import Network.HTTP.Download ( download )
-- from path package
import Path ( (</>), parseAbsDir, relfile )
-- from directory package
import System.Directory ( getCurrentDirectory )

main :: IO ()
main = do
  req <- parseRequest "https://hackage.haskell.org/root.json"
  cwd <- getCurrentDirectory
  absCwd <- parseAbsDir cwd
  let absDestFile = absCwd </> [relfile|temp.json|]
  void $ runSimplePrettyApp 80 mempty $
    download req absDestFile