Happstack + network package issue on the Mac

We have run into an issue that it seems other people have already found but has apparently not been resolved, yet. It manifests as with the error "HTTP request failed with: Unsupported socket". The problem is described in two places with different workarounds. http://code.google.com/p/happstack/issues/detail?id=88 http://groups.google.com/group/HAppS/msg/0c9a0d0fd7c6aff0 One workaround is to rewrite part of the network package, and the other is to downgrade the package. It could be the case that the rewrite came from the older version, though I'm not sure. I'm curious if it is possible to fix this, either in Happstack or the network package, once and for all. The workarounds are rather painful when so many things depend on the network package. Thanks, Sean

Sean Leather
We have run into an issue that it seems other people have already found but has apparently not been resolved, yet. It manifests as with the error "HTTP request failed with: Unsupported socket". The problem is described in two places with different workarounds.
http://code.google.com/p/happstack/issues/detail?id=88 http://groups.google.com/group/HAppS/msg/0c9a0d0fd7c6aff0
One workaround is to rewrite part of the network package, and the other is to downgrade the package. It could be the case that the rewrite came from the older version, though I'm not sure.
I'm curious if it is possible to fix this, either in Happstack or the network package, once and for all. The workarounds are rather painful when so many things depend on the network package.
The following patch to happstack works for me:
G.
--
Gregory Collins

On Thu, Oct 8, 2009 at 16:35, Gregory Collins wrote:
Sean Leather
writes: We have run into an issue that it seems other people have already found but has apparently not been resolved, yet. It manifests as with the error "HTTP request failed with: Unsupported socket". The problem is described in two places with different workarounds.
http://code.google.com/p/happstack/issues/detail?id=88 http://groups.google.com/group/HAppS/msg/0c9a0d0fd7c6aff0
One workaround is to rewrite part of the network package, and the other is to downgrade the package. It could be the case that the rewrite came from the older version, though I'm not sure.
I'm curious if it is possible to fix this, either in Happstack or the network package, once and for all. The workarounds are rather painful when so many things depend on the network package.
The following patch to happstack works for me:
This worked for us as well. Thanks, Gregory. Do you know if it's possible to permanently patch happstack-server? I'm guessing the TH in the patch is used to support multiple versions of the network package. Can we just change the minimum supported version? Sean

Sean Leather
On Thu, Oct 8, 2009 at 16:35, Gregory Collins wrote:
Sean Leather
writes: > We have run into an issue that it seems other people have already > found but has apparently not been resolved, yet. It manifests as with > the error "HTTP request failed with: Unsupported socket". The problem > is described in two places with different workarounds. > > http://code.google.com/p/happstack/issues/detail?id=88 > http://groups.google.com/group/HAppS/msg/0c9a0d0fd7c6aff0 > > One workaround is to rewrite part of the network package, and the > other is to downgrade the package. It could be the case that the > rewrite came from the older version, though I'm not sure. > > I'm curious if it is possible to fix this, either in Happstack or the > network package, once and for all. The workarounds are rather painful > when so many things depend on the network package.
The following patch to happstack works for me:
This worked for us as well. Thanks, Gregory.
Do you know if it's possible to permanently patch happstack-server? I'm guessing the TH in the patch is used to support multiple versions of the network package. Can we just change the minimum supported version?
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. I'm not sure
but I think IPv6 template Haskell stuff is there not to support old
versions of network, but to support platforms where IPv6 may not be
available.
G
--
Gregory Collins

Gregory Collins wrote:
Sean Leather
writes: On Thu, Oct 8, 2009 at 16:35, Gregory Collins wrote:
Sean Leather
writes:
Do you know if it's possible to permanently patch happstack-server? I'm guessing the TH in the patch is used to support multiple versions of the network package. Can we just change the minimum supported version?
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. I'm not sure but I think IPv6 template Haskell stuff is there not to support old versions of network, but to support platforms where IPv6 may not be available.
I don't recall whether there was some objection to this suggestion previously, but assuming IPv6 support is available might work on more platforms. Then special action would only need to be taken on platforms that lack IPv6. Anton

On Fri, Oct 9, 2009 at 7:25 AM, Gregory Collins
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.

Bryan O'Sullivan wrote:
On Fri, Oct 9, 2009 at 7:25 AM, Gregory Collins
mailto:greg@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... Anton

"Bryan O'Sullivan"
On Fri, Oct 9, 2009 at 7:25 AM, Gregory Collins
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.
No, against Happstack. The offending code:
------------------------------------------------------------------------------
-- 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 |] )
...
-- | alternative implementation of accept to work around EAI_AGAIN errors
acceptLite :: S.Socket -> IO (Handle, S.HostName, S.PortNumber)
acceptLite sock = do
(sock', addr) <- S.accept sock
h <- S.socketToHandle sock' ReadWriteMode
(N.PortNumber p) <- N.socketPort sock'
let peer = $(if supportsIPv6
then
return $ CaseE (VarE (mkName "addr"))
[Match
(ConP (mkName "S.SockAddrInet")
[WildP,VarP (mkName "ha")])
(NormalB (AppE (VarE (mkName "showHostAddress"))
(VarE (mkName "ha")))) []
,Match (ConP (mkName "S.SockAddrInet6") [WildP,WildP,VarP (mkName "ha"),WildP])
(NormalB (AppE (VarE (mkName "showHostAddress6")) (VarE (mkName "ha")))) []
,Match WildP (NormalB (AppE (VarE (mkName "error")) (LitE (StringL "Unsupported socket")))) []]
-- the above mess is the equivalent of this:
{-[| case addr of
(S.SockAddrInet _ ha) -> showHostAddress ha
(S.SockAddrInet6 _ _ ha _) -> showHostAddress6 ha
_ -> error "Unsupported socket"
|]-}
else
[| case addr of
(S.SockAddrInet _ ha) -> showHostAddress ha
_ -> error "Unsupported socket"
|])
return (h, peer, p)
------------------------------------------------------------------------------
Frankly I think this approach is dubious at best.
G
--
Gregory Collins

On Fri, 2009-10-09 at 12:22 -0700, Bryan O'Sullivan wrote:
On Fri, Oct 9, 2009 at 7:25 AM, Gregory Collins
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.
From what Gregory and Anton have said, it sounds like the SockAddr6, HostAddress6 constructors should always be available, but that using them with the socket functions should fail at runtime on platforms with no IPv6 support, or when IPv6 support is turned off for some reason.
That would probably make it rather easier to have portable programs that can optionally use IPv6. Having to use TH to test at compile time if a constructor is or is not exported from another package is more than a little unpleasant. Duncan

On Sat, Oct 10, 2009 at 15:13, Duncan Coutts wrote:
From what Gregory and Anton have said, it sounds like the SockAddr6, HostAddress6 constructors should always be available, but that using them with the socket functions should fail at runtime on platforms with no IPv6 support, or when IPv6 support is turned off for some reason.
That would probably make it rather easier to have portable programs that can optionally use IPv6. Having to use TH to test at compile time if a constructor is or is not exported from another package is more than a little unpleasant.
+1 Sean
participants (5)
-
Anton van Straaten
-
Bryan O'Sullivan
-
Duncan Coutts
-
Gregory Collins
-
Sean Leather