[Haskell-cafe] Happstack + network package issue on the Mac

Anton van Straaten anton at appsolutions.com
Fri Oct 9 16:17:02 EDT 2009

Bryan O'Sullivan wrote:
> On Fri, Oct 9, 2009 at 7:25 AM, Gregory Collins <greg at gregorycollins.net 
> <mailto:greg at gregorycollins.net>> wrote:
>     There's been an open ticket for months; personally I think this is a job
>     for the C preprocessor, but nobody's written a patch yet.
> Is there an open ticket against the network package? Can someone write a 
> simple standalone repro for me that doesn't require happstack (i.e. only 
> depends on network)? I have access to a Mac and Johan and I co-maintain 
> the network package, so in principle this shouldn't be hard to fix, 
> given enough details and pointers.

I have the impression that the problem is at least partly with TH on the 
Mac, and there may not even be any relevant bug in the network package. 
   It's possible that the network package could provide some additional 
support to help Happstack solve this another way, though.

The main problem that Happstack faces here is to avoid referencing the
SockAddrInet6 constructor if it doesn't exist, i.e. if the network 
package was compiled without IPv6 support.

If Happstack had some reliable/portable way of accessing 
IPV6_SOCKET_SUPPORT, a C #define used by the network package, this could 
easily be done with the C preprocessor.  I don't think Cabal is up to 
that task, though.  Happstack would probably have to use its own 
configure script (it doesn't have one right now) to determine IPv6 
status for itself, and hope that it matches what the network package 
found when it was compiled.

The current solution in Happstack is to use TH to detect IPv6 support in 
the network package, by testing for the existence of the SockAddrInet6 
constructor, as follows (reformatted slightly for email):

-- find out at compile time if the SockAddr6 / HostAddress6 constructors
-- are available
supportsIPv6 :: Bool
supportsIPv6 = $(let c = "Network.Socket.SockAddrInet6"
                      d = ''SockAddr in
                  do TyConI (DataD _ _ _ cs _) <- reify d
                     if isJust (find (\(NormalC n _) -> show n == c) cs)
                        then [| True |]
                        else [| False |] )

If I had access to a Mac, the first thing I'd do is check what 
supportsIPv6 is getting set to, and whether it changes depending on the 
version of the network package being used.

However, some comments many months back seemed to indicate that 
supportsIPv6 might be getting set correctly, and that the problem was 
happening later.  In that case, it would be in 
Happstack/Server/HTTP/Socket.hs, which contains this test:

   let peer = $(if supportsIPv6

If supportsIPv6 is False, or somehow incorrectly treated as False, then 
the error message being reported could happen if the provided socket is 
actually IPv6.

Alternatively, if the True branch is taken, then a TH-encoded case 
expression is used to match the SockAddr value, without having to 
reference the SockAddrInet6 constructor directly in code.  But if this 
the part that executes, then for some mysterious reason, it is failing, 
only on the Mac, to match the appropriate constructor.  That sounds like 
a fascinating bug!  I hope someone with a Mac will track it down and let 
us know what was happening...


More information about the Haskell-Cafe mailing list