module Network.GRPC.Server.Session ( ServerSession(..) , ServerInbound , ServerOutbound , Headers(..) -- * Exceptions , CallSetupFailure(..) ) where import Control.Exception import Data.Proxy import Data.Void import Network.GRPC.Server.Context import Network.GRPC.Spec import Network.GRPC.Spec.Serialization import Network.GRPC.Util.Session {------------------------------------------------------------------------------- Definition -------------------------------------------------------------------------------} data ServerSession rpc = ServerSession { serverSessionContext :: ServerContext } {------------------------------------------------------------------------------- Instances -------------------------------------------------------------------------------} data ServerInbound rpc data ServerOutbound rpc instance IsRPC rpc => DataFlow (ServerInbound rpc) where data Headers (ServerInbound rpc) = InboundHeaders { inbHeaders :: RequestHeaders' HandledSynthesized , inbCompression :: Compression } deriving (Show) type Message (ServerInbound rpc) = (InboundMeta, Input rpc) type Trailers (ServerInbound rpc) = NoMetadata -- gRPC does not support request trailers type NoMessages (ServerInbound rpc) = Void instance IsRPC rpc => DataFlow (ServerOutbound rpc) where data Headers (ServerOutbound rpc) = OutboundHeaders { outHeaders :: ResponseHeaders , outCompression :: Compression } deriving (Show) type Message (ServerOutbound rpc) = (OutboundMeta, Output rpc) type Trailers (ServerOutbound rpc) = ProperTrailers type NoMessages (ServerOutbound rpc) = TrailersOnly instance SupportsServerRpc rpc => IsSession (ServerSession rpc) where type Inbound (ServerSession rpc) = ServerInbound rpc type Outbound (ServerSession rpc) = ServerOutbound rpc parseInboundTrailers _ = \_ -> return NoMetadata buildOutboundTrailers _ = buildProperTrailers parseMsg _ = parseInput (Proxy @rpc) . inbCompression buildMsg _ = buildOutput (Proxy @rpc) . outCompression {------------------------------------------------------------------------------- Exceptions -------------------------------------------------------------------------------} -- | We failed to setup the call from the client data CallSetupFailure = -- | Client sent resource headers that were not conform the gRPC spec CallSetupInvalidResourceHeaders InvalidResourceHeaders -- | Invalid request headers -- -- 'CallSetupInvalidResourceHeaders' refers to an invalid method (anything -- other than POST) or an invalid path; 'CallSetupInvalidRequestHeaders' -- means we could not parse the HTTP headers according to the gRPC spec. | CallSetupInvalidRequestHeaders (InvalidHeaders HandledSynthesized) -- | Client chose unsupported compression algorithm -- -- This is indicative of a misbehaving peer: a client should not use a -- compression algorithm unless they have evidence that the server supports -- it. The server cannot process such a request, as it has no way of -- decompression messages sent by the client. | CallSetupUnsupportedCompression CompressionId -- | No registered handler for the specified path -- -- Note on terminology: HTTP has \"methods\" such as POST, GET, etc; gRPC -- supports only POST, and when another HTTP method is chosen, this will -- result in 'CallSetupInvalidResourceHeaders'. However, gRPC itself also -- has the concept of a "method" (a method, or gRPC call, supported by a -- particular service); it's these methods that -- 'CallSetupUnimplementedMethod' is referring to. | CallSetupUnimplementedMethod Path -- | An exception arose while we tried to look up the handler -- -- This can arise when the list of handlers /itself/ is @undefined@. | CallSetupHandlerLookupException SomeException deriving stock instance Show CallSetupFailure deriving anyclass instance Exception CallSetupFailure