sproxy ::
     ByteString
  -> Database
  -> HM.HashMap Text OAuth2Client
  -> [(Pattern, BackendConf, BE.Manager)]
  -> W.Application
sproxy key db oa2 backends =
  logException $ \req resp -> do
    Log.debug $ "sproxy <<< " ++ showReq req
    case requestDomain req of
      Nothing -> badRequest "missing host" req resp
      Just domain ->
        case find (\(p, _, _) -> match p (unpack domain)) backends of
          Nothing -> notFound "backend" req resp
          Just (_, be, mgr) -> do
            let cookieName = pack $ beCookieName be
                cookieDomain = pack <$> beCookieDomain be
            case W.pathInfo req of
              ["robots.txt"] -> get robots req resp
              (".sproxy":proxy) ->
                case proxy of
                  ["logout"] ->
                    get (logout key cookieName cookieDomain) req resp
                  ["oauth2", provider] ->
                    case HM.lookup provider oa2 of
                      Nothing -> notFound "OAuth2 provider" req resp
                      Just oa2c ->
                        get (oauth2callback key db (provider, oa2c) be) req resp
                  ["access"] -> do
                    now <- Just <$> epochTime
                    case extractCookie key now cookieName req of
                      Nothing -> authenticationRequired key oa2 req resp
                      Just (authCookie, _) ->
                        post (checkAccess db authCookie) req resp
                  _ -> notFound "proxy" req resp
              _ -> do
                now <- Just <$> epochTime
                case extractCookie key now cookieName req of
                  Nothing -> authenticationRequired key oa2 req resp
                  Just cs@(authCookie, _) ->
                    authorize db cs req >>= \case
                      Nothing -> forbidden authCookie req resp
                      Just req' -> forward mgr req' resp
sproxy ::
     ByteString
  -> Database
  -> HM.HashMap Text OAuth2Client
  -> [(Pattern, BackendConf, BE.Manager)]
  -> W.Application
sproxy key db oa2 backends =
  logException $ \req resp -> do
    Log.debug $ "sproxy <<< " ++ showReq req
    case requestDomain req of
      Nothing -> badRequest "missing host" req resp
      Just domain ->
        case find (\(p, _, _) -> match p (unpack domain)) backends of
          Nothing -> notFound "backend" req resp
          Just (_, be, mgr) -> do
            let cookieName = pack $ beCookieName be
                cookieDomain = pack <$> beCookieDomain be
            case W.pathInfo req of
              ["robots.txt"] -> get robots req resp
              (".sproxy":proxy) ->
                case proxy of
                  ["logout"] ->
                    get (logout key cookieName cookieDomain) req resp
                  ["oauth2", provider] ->
                    case HM.lookup provider oa2 of
                      Nothing -> notFound "OAuth2 provider" req resp
                      Just oa2c ->
                        get (oauth2callback key db (provider, oa2c) be) req resp
                  ["access"] -> do
                    now <- Just <$> epochTime
                    case extractCookie key now cookieName req of
                      Nothing -> authenticationRequired key oa2 req resp
                      Just (authCookie, _) ->
                        post (checkAccess db authCookie) req resp
                  _ -> notFound "proxy" req resp
              _ -> do
                now <- Just <$> epochTime
                case extractCookie key now cookieName req of
                  Nothing -> authenticationRequired key oa2 req resp
                  Just cs@(authCookie, _) ->
                    authorize db cs req >>= \case
                      Nothing -> forbidden authCookie req resp
                      Just req' -> forward mgr req' resp
sproxy key db oa2 backends =
  logException $ \req resp -> do
    Log.debug $ "sproxy <<< " ++ showReq req
    case requestDomain req of
      Nothing -> badRequest "missing host" req resp
      Just domain ->
        case find (\(p, _, _) -> match p (unpack domain)) backends of
          Nothing -> notFound "backend" req resp
          Just (_, be, mgr) -> do
            let cookieName = pack $ beCookieName be
                cookieDomain = pack <$> beCookieDomain be
            case W.pathInfo req of
              ["robots.txt"] -> get robots req resp
              (".sproxy":proxy) ->
                case proxy of
                  ["logout"] ->
                    get (logout key cookieName cookieDomain) req resp
                  ["oauth2", provider] ->
                    case HM.lookup provider oa2 of
                      Nothing -> notFound "OAuth2 provider" req resp
                      Just oa2c ->
                        get (oauth2callback key db (provider, oa2c) be) req resp
                  ["access"] -> do
                    now <- Just <$> epochTime
                    case extractCookie key now cookieName req of
                      Nothing -> authenticationRequired key oa2 req resp
                      Just (authCookie, _) ->
                        post (checkAccess db authCookie) req resp
                  _ -> notFound "proxy" req resp
              _ -> do
                now <- Just <$> epochTime
                case extractCookie key now cookieName req of
                  Nothing -> authenticationRequired key oa2 req resp
                  Just cs@(authCookie, _) ->
                    authorize db cs req >>= \case
                      Nothing -> forbidden authCookie req resp
                      Just req' -> forward mgr req' resp