Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eq instance of Connection #98

Open
henrylaxen opened this issue Apr 9, 2015 · 7 comments
Open

Eq instance of Connection #98

henrylaxen opened this issue Apr 9, 2015 · 7 comments
Labels

Comments

@henrylaxen
Copy link

Dear Jasper,

I don't know if it is possible, but I think it would be really nice to have an Eq instance of Connection. That way I could have [Connection] and be able to move them to different lists based on some test. I'm working around it now by wrapping Connection and using Data.Supply to generate my own Eq instance. Just something to think about in your copious spare time ;-)

@skatenerd
Copy link

An Ord instance would be nice too. It's nice to use a Set to track the connections so you can easily add/remove.

@mitchellwrosen
Copy link
Contributor

This can't currently be done in a way that doesn't break backwards compatibility (i.e. introduce some custom monad to track the unique supply), because Connection can't simply derive Eq.

You could use some global-supply hack such as

import Control.Concurrent.MVar
import Control.Concurrent.Supply (Supply)
import qualified Control.Concurrent.Supply as Supply

globalSupply :: MVar Supply
globalSupply = unsafePerformIO (Supply.newSupply >>= newMVar)
{-# NOINLINE globalSupply #-}

freshId :: IO Int
freshId = modifyMVar supply (\s -> 
    let (n, s') = Supply.freshId s
    in pure (s', n))

data Connection = Connection
    { ...
    , connectionId :: Int
    }

@jaspervdj
Copy link
Owner

Socket actually provides an Eq instance so it might be able to piggyback on top of that.

Alternatively, we can use the 4-tuple (source IP, source port, destination IP, destination port) to uniquely identify the connection as well, but we'd also need to store that info in the Connection datatype. This would be my preferred solution.

@fschr
Copy link

fschr commented May 12, 2016

Just to be clear, does this mean that with the current state of WebSockets, we're just supposed to trust connections? Is there anyway to uniquely identify users right now?

@jaspervdj
Copy link
Owner

The correct way to do this is to have the server pass the socket 4-tuples to the websockets library, and then make these available in PendingConnection/Connection. However, some of the Haskell HTTP servers do not support that, so I didn't go through with that implementation for now.

I don't really know what you mean by "trust the connections" though. Users should be identified by implementing proper authentication either over HTTPS or through WebSocket messages.

@skatenerd
Copy link

I guess one pattern is to provide a nonce-style token to the user via http, and then identify the websocket connection based on what token they send over.

@jaspervdj
Copy link
Owner

Well, usually WebSocket apps are part of larger HTTP apps, which already have some sort of authentication system in place using cookies/headers.

Since a WebSocket connection starts out like a normal HTTP request, a great pattern is to use your existing HTTP authentication layer to check the cookies before turning it into a WebSocket connection. This is possible with both the Snap and Yesod backends, and I've personally used this pattern successfully in the past.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants