gRPC-haskell/grpc-haskell.cabal
intractable e1091b9c0d
grpc-haskell{-core} -> 0.2.0: Fix MetadataMap duplicate-key ordering (#132)
* Put LD_LIBRARY_PATH set back into Linux `nix-shell`

...as we need it for `ghci` workflows inside the shell(s).

* Add (failing) test case to check MetadataMap ordering

* Remove SortedList value-component from MetadataMap

...which fixes the failing test case introduced by `85a2d13`.

This is a potentially breaking change that warrants a library rev bump.

I'm not sure what the original reason was for the sorted list component of
`MetadataMap` (i.e., header values), but that implementation choice makes it so
that determining the "last provided" header value associated with a duplicate
key cannot be recovered. That is, it is in violation of this requirement from
the [spec](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md):

```
Custom-Metadata header order is not guaranteed to be preserved except for values
with duplicate header names.
```

I'm guessing that the original motivation might have been to ensure that the Eq
instance was not sensitive to ordering of values for duplicate keys.

I think we can drop the existing `Eq` assumption about order-insensitive values
for duplicate keys (there is order sensitivity after all), and if we end up
discovering a common use case for an order-insensitive equality on values, we
should address that via a utility function (instead via the type's `Eq`
instance).

So, this commit changes the value component of the `MetadataMap` type to be a
list of `ByteString` values instead of `SortedList ByteString`, and removes the
`sorted-list` package as a dependency, as it has no other uses in the library.

Note that this commit is not claiming we are now spec-compliant w.r.t. header
treatment after this change. In particular (and at least),

1. We do not yet support base64-encoded binary data via the special `-bin` key
suffix.

2. As far as I am aware, we do not (yet) interpret comma-separated header values
the same as duplicate header keys for each of those values.

3. As far as I am aware, we do not (yet) do any validation of header names nor
whitespace handling as per the request grammar from the spec.

* Extend Arbitrary MetadataMap to explicitly encode key duplication

Duplicate keys were allowed by the previous implementation, but this commit
makes key duplication more explicit and more frequent.

* Add metadata map ordering QC prop

* Drop qualified use of @?= since it's so common in this module

* Extend checkMetadataOrdering to check instance Eq MetadataMap

...and use the appropriate bracketing wrapper.

* Relocate MetadataMap type to its own module

* Add some helper functions for MetadataMap lookup; documentation

* Extend testMetadataOrdering w/ use of lookup{All,Last}

* Bump grpc-haskell{,-core} -> 0.2.0
2021-06-30 20:32:33 -05:00

239 lines
6 KiB
Text

name: grpc-haskell
version: 0.2.0
synopsis: Haskell implementation of gRPC layered on shared C library.
homepage: https://github.com/awakenetworks/gRPC-haskell
license: Apache-2.0
license-file: LICENSE
author: Awake Networks
maintainer: opensource@awakenetworks.com
copyright: Copyright 2016 Awake Networks
category: Network
build-type: Simple
cabal-version: >=1.10
extra-source-files: tests/*.hs
tests/*.proto
tests/*.py
tests/*.sh
Flag Debug
Description: Adds debug logging.
Manual: True
Default: False
flag with-examples
description: Also build example executables.
manual: True
default: False
library
build-depends:
base >=4.8 && <5.0
, bytestring ==0.10.*
, proto3-suite >=0.4.1
, proto3-wire >=1.2.0
, grpc-haskell-core >=0.2.0
, async >=2.1 && <2.3
, managed >= 1.0.5
exposed-modules:
Network.GRPC.HighLevel
Network.GRPC.HighLevel.Generated
Network.GRPC.HighLevel.Server
Network.GRPC.HighLevel.Server.Unregistered
Network.GRPC.HighLevel.Client
default-language: Haskell2010
ghc-options: -Wall -Werror -fwarn-incomplete-patterns -fno-warn-unused-do-bind
hs-source-dirs: src
default-extensions: CPP
CC-Options: -std=c99
if flag(debug)
CPP-Options: -DDEBUG
CC-Options: -DGRPC_HASKELL_DEBUG -std=c99
executable hellos-server
if flag(with-examples)
build-depends:
base >=4.8 && <5.0
, async
, bytestring == 0.10.*
, containers >=0.5 && <0.7
, grpc-haskell
, grpc-haskell-core >=0.2.0
, proto3-suite
, proto3-wire
, text
, transformers
else
buildable: False
default-language: Haskell2010
ghc-options: -Wall -Werror -g -threaded -rtsopts -with-rtsopts=-N -O2
hs-source-dirs: examples/hellos/hellos-server
main-is: Main.hs
executable hellos-client
if flag(with-examples)
build-depends:
base >=4.8 && <5.0
, async
, bytestring == 0.10.*
, containers >=0.5 && <0.7
, grpc-haskell
, grpc-haskell-core >=0.2.0
, proto3-suite
, proto3-wire
, text
, transformers
else
buildable: False
default-language: Haskell2010
ghc-options: -Wall -Werror -g -threaded -rtsopts -with-rtsopts=-N -O2
hs-source-dirs: examples/hellos/hellos-client
main-is: Main.hs
executable echo-server
if flag(with-examples)
build-depends:
base >=4.8 && <5.0
, async
, bytestring == 0.10.*
, containers >=0.5 && <0.7
, deepseq
, grpc-haskell
, grpc-haskell-core >=0.2.0
, optparse-generic
, proto3-suite
, proto3-wire
, text
, vector
other-modules:
Echo
else
buildable: False
default-language: Haskell2010
ghc-options: -Wall -Werror -g -threaded -rtsopts -with-rtsopts=-N -O2
hs-source-dirs: examples/echo/echo-hs
main-is: EchoServer.hs
executable arithmetic-server
if flag(with-examples)
build-depends:
base >=4.8 && <5.0
, async
, bytestring == 0.10.*
, containers >=0.5 && <0.7
, deepseq
, grpc-haskell
, grpc-haskell-core >=0.2.0
, optparse-generic
, proto3-suite
, proto3-wire
, text
, vector
other-modules:
Arithmetic
else
buildable: False
default-language: Haskell2010
ghc-options: -Wall -Werror -g -threaded -rtsopts -with-rtsopts=-N -O2
hs-source-dirs: examples/tutorial/
main-is: ArithmeticServer.hs
executable arithmetic-client
if flag(with-examples)
build-depends:
base >=4.8 && <5.0
, async
, bytestring == 0.10.*
, containers >=0.5 && <0.7
, deepseq
, grpc-haskell
, grpc-haskell-core >=0.2.0
, optparse-generic
, proto3-suite
, proto3-wire
, text
, vector
other-modules:
Arithmetic
else
buildable: False
default-language: Haskell2010
ghc-options: -Wall -Werror -g -threaded -rtsopts -with-rtsopts=-N -O2
hs-source-dirs: examples/tutorial/
main-is: ArithmeticClient.hs
executable echo-client
if flag(with-examples)
build-depends:
base >=4.8 && <5.0
, async
, bytestring == 0.10.*
, containers >=0.5 && <0.7
, deepseq
, grpc-haskell
, grpc-haskell-core >=0.2.0
, optparse-generic
, proto3-suite
, proto3-wire
, text
, random
, vector
other-modules:
Echo
else
buildable: False
default-language: Haskell2010
ghc-options: -Wall -Werror -g -threaded -rtsopts -with-rtsopts=-N -O2
hs-source-dirs: examples/echo/echo-hs
main-is: EchoClient.hs
test-suite tests
build-depends:
base >=4.8 && <5.0
, bytestring ==0.10.*
, unix
, time
, async
, tasty >= 0.11
, tasty-hunit >= 0.9
, tasty-quickcheck >= 0.8.4
, containers >=0.5 && <0.7
, managed >= 1.0.0 && < 1.1
, pipes >=4.1 && <=4.4
, proto3-suite
, transformers
, safe
, clock >=0.6.0 && <0.8.0
, turtle >= 1.2.0
, text
, QuickCheck >=2.10 && <3.0
other-modules:
GeneratedTests
default-language: Haskell2010
ghc-options: -Wall -Werror -fwarn-incomplete-patterns -fno-warn-unused-do-bind -g -threaded -rtsopts
hs-source-dirs: tests
main-is: Properties.hs
type: exitcode-stdio-1.0
default-extensions: CPP
if flag(debug)
CPP-Options: -DDEBUG
CC-Options: -DGRPC_HASKELL_DEBUG
benchmark bench
type: exitcode-stdio-1.0
build-depends:
base >=4.8 && <5.0
, grpc-haskell
, async ==2.1.*
, criterion ==1.1.*
, proto3-suite
, bytestring ==0.10.*
, random >=1.0.0
hs-source-dirs: bench
main-is: Bench.hs
ghc-options: -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
if flag(debug)
CPP-Options: -DDEBUG
CC-Options: -DGRPC_HASKELL_DEBUG
default-language: Haskell2010