on master help sign in
add https recipe, add (future) github links at the end of all recipes
c5f2b9eAlp Mestanogullari
cabal.project+1
@@ -11,6 +11,7 @@ packages: servant/
11 doc/cookbook/jwt-and-basic-auth/
11 doc/cookbook/jwt-and-basic-auth/
12 doc/cookbook/file-upload/
12 doc/cookbook/file-upload/
13 doc/cookbook/structuring-apis/
13 doc/cookbook/structuring-apis/
14+ doc/cookbook/https/
14
15
15allow-newer: servant-js:servant-foreign
16allow-newer: servant-js:servant-foreign
16
17
doc/cookbook/basic-auth/BasicAuth.lhs+2−1
@@ -175,4 +175,5 @@ code and see what happens when you specify credentials that are not in the
175database.
175database.
176
176
177The entire program covered here is available as a literate Haskell file
177The entire program covered here is available as a literate Haskell file
178+[here](https://github.com/haskell-servant/servant/tree/master/doc/cookbook/basic-auth),
178−[here](...), along with a `cabal` project.
179+along with a `cabal` project.
doc/cookbook/db-postgres-pool/PostgresPool.lhs+2−1
@@ -139,4 +139,5 @@ You could alternatively have the handlers live in `ReaderT (Pool Connection)`
139and access the pool using e.g `ask`, but this would be more complicated
139and access the pool using e.g `ask`, but this would be more complicated
140than simply taking the pool as argument.
140than simply taking the pool as argument.
141
141
142−The entire source for this example is available [here](...).
142+The entire source for this example is available as a cabal project
143+[here](https://github.com/haskell-servant/servant/tree/master/doc/cookbook/db-postgres-pool).
doc/cookbook/db-sqlite-simple/DBConnection.lhs+2−1
@@ -96,4 +96,5 @@ main = do
96This program prints `Right ["hello","world"]` the first time it is executed,
96This program prints `Right ["hello","world"]` the first time it is executed,
97`Right ["hello","world","hello","world"]` the second time and so on.
97`Right ["hello","world","hello","world"]` the second time and so on.
98
98
99−The entire source for this example is available [here](...).
99+The entire source for this example is available as a cabal project
100+[here](https://github.com/haskell-servant/servant/tree/master/doc/cookbook/db-sqlite-simple).
doc/cookbook/file-upload/FileUpload.lhs+2−2
@@ -183,5 +183,5 @@ See `CONTRIBUTING.md`
183Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Transfer-Encoding","chunked"),("Date","Fri, 08 Dec 2017 16:50:14 GMT"),("Server","Warp/3.2.13"),("Content-Type","application/json;charset=utf-8")], responseBody = "0", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}
183Response {responseStatus = Status {statusCode = 200, statusMessage = "OK"}, responseVersion = HTTP/1.1, responseHeaders = [("Transfer-Encoding","chunked"),("Date","Fri, 08 Dec 2017 16:50:14 GMT"),("Server","Warp/3.2.13"),("Content-Type","application/json;charset=utf-8")], responseBody = "0", responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}
184```
184```
185
185
186−As usual, the code for this recipe is available in a cabal
186+As usual, the code for this recipe is available in a cabal project
187−project [here]().
187+[here](https://github.com/haskell-servant/servant/tree/master/doc/cookbook/file-upload).
doc/cookbook/https/Https.lhsnew file+62
@@ -0,0 +1,62 @@
1+# Serving web applications over HTTPS
2+
3+This short recipe shows how one can serve a servant application
4+over HTTPS, by simply using `warp-tls` instead of `warp` to provide
5+us a `run` function for running the `Application` that we get by
6+calling `serve`.
7+
8+As usual, we start by clearing our throat of a few language extensions
9+and imports.
10+
11+``` haskell
12+{-# LANGUAGE DataKinds #-}
13+{-# LANGUAGE TypeOperators #-}
14+import Network.Wai
15+import Network.Wai.Handler.Warp
16+import Network.Wai.Handler.WarpTLS
17+import Servant
18+```
19+
20+No need to work with a complicated API here, let's
21+make it as simple as it gets:
22+
23+``` haskell
24+type API = Get '[JSON] Int
25+
26+api :: Proxy API
27+api = Proxy
28+
29+server :: Server API
30+server = return 10
31+
32+app :: Application
33+app = serve api server
34+```
35+
36+It's now time to actually run the `Application`.
37+The [`warp-tls`](https://hackage.haskell.org/package/warp-tls-3.2.4/docs/Network-Wai-Handler-WarpTLS.html)
38+package provides two functions for running an `Application`, called
39+[`runTLS`](https://hackage.haskell.org/package/warp-tls-3.2.4/docs/Network-Wai-Handler-WarpTLS.html#v:runTLS)
40+and [`runTLSSocket`](https://hackage.haskell.org/package/warp-tls-3.2.4/docs/Network-Wai-Handler-WarpTLS.html#v:runTLSSocket).
41+We will be using the first one.
42+
43+It takes two arguments,
44+[the TLS settings](https://hackage.haskell.org/package/warp-tls-3.2.4/docs/Network-Wai-Handler-WarpTLS.html#t:TLSSettings)
45+(certificates, keys, ciphers, etc)
46+and [the warp settings](https://hackage.haskell.org/package/warp-3.2.12/docs/Network-Wai-Handler-Warp-Internal.html#t:Settings)
47+(port, logger, etc).
48+
49+We will be using very simple settings for this example but you are of
50+course invited to read the documentation for those types to find out
51+about all the knobs that you can play with.
52+
53+``` haskell
54+main :: IO ()
55+main = runTLS tlsOpts warpOpts app
56+
57+ where tlsOpts = tlsSettings "cert.pem" "secret-key.pem"
58+ warpOpts = setPort 8080 defaultSettings
59+```
60+
61+This program is available as a cabal project
62+[here](https://github.com/haskell-servant/servant/tree/master/doc/cookbook/https).
doc/cookbook/https/https.cabalnew file+25
@@ -0,0 +1,25 @@
1+name: cookbook-https
2+version: 0.1
3+synopsis: HTTPS cookbook example
4+homepage: http://haskell-servant.readthedocs.org/
5+license: BSD3
6+license-file: ../../../servant/LICENSE
7+author: Servant Contributors
8+maintainer: haskell-servant-maintainers@googlegroups.com
9+build-type: Simple
10+cabal-version: >=1.10
11+
12+executable cookbook-https
13+ if impl(ghc < 7.10.1)
14+ buildable: False
15+ main-is: Https.lhs
16+ build-depends: base == 4.*
17+ , servant
18+ , servant-server
19+ , wai
20+ , warp
21+ , warp-tls
22+ , markdown-unlit >= 0.4
23+ default-language: Haskell2010
24+ ghc-options: -Wall -pgmL markdown-unlit
25+ build-tool-depends: markdown-unlit:markdown-unlit
doc/cookbook/index.rst+2−1
@@ -17,9 +17,10 @@ you name it!
17.. toctree::
17.. toctree::
18 :maxdepth: 1
18 :maxdepth: 1
19
19
20+ structuring-apis/StructuringApis.lhs
21+ https/Https.lhs
20 db-sqlite-simple/DBConnection.lhs
22 db-sqlite-simple/DBConnection.lhs
21 db-postgres-pool/PostgresPool.lhs
23 db-postgres-pool/PostgresPool.lhs
22 basic-auth/BasicAuth.lhs
24 basic-auth/BasicAuth.lhs
23 jwt-and-basic-auth/JWTAndBasicAuth.lhs
25 jwt-and-basic-auth/JWTAndBasicAuth.lhs
24 file-upload/FileUpload.lhs
26 file-upload/FileUpload.lhs
25− structuring-apis/StructuringApis.lhs
doc/cookbook/jwt-and-basic-auth/JWTAndBasicAuth.lhs+3
@@ -247,3 +247,6 @@ curl -v -H 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJkYXQiOnsiYXVPcmdJRCI6M
247…
247…
248< HTTP/1.1 200 OK
248< HTTP/1.1 200 OK
249```
249```
250+
251+This program is available as a cabal project
252+[here](https://github.com/haskell-servant/servant/tree/master/doc/cookbook/jwt-and-basic-auth).
doc/cookbook/structuring-apis/StructuringApis.lhs+3−2
@@ -60,7 +60,7 @@ an effect on the server for such an API, and its type
60in particular. While the server for `FactoringAPI'` would
60in particular. While the server for `FactoringAPI'` would
61be made of a function of type `Int -> Maybe Int -> Handler Int`
61be made of a function of type `Int -> Maybe Int -> Handler Int`
62and a function of type `Int -> Handler Int` glued with `:<|>`,
62and a function of type `Int -> Handler Int` glued with `:<|>`,
63−a server for `Factoring` (without the `'`) reflects the
63+a server for `FactoringAPI` (without the `'`) reflects the
64"factorisation" and therefore, `Server FactoringAPI` is
64"factorisation" and therefore, `Server FactoringAPI` is
65`Int -> (Maybe Int -> Handler Int :<|> Handler Int)`. That is, the
65`Int -> (Maybe Int -> Handler Int :<|> Handler Int)`. That is, the
66server must be a function that takes an `Int` (the `Capture`) and
66server must be a function that takes an `Int` (the `Capture`) and
@@ -191,4 +191,5 @@ main = run 8080 . serve api $
191 factoringServer :<|> userServer :<|> productServer
191 factoringServer :<|> userServer :<|> productServer
192```
192```
193
193
194−This program is available as a cabal project [here]().
194+This program is available as a cabal project
195+[here](https://github.com/haskell-servant/servant/tree/master/doc/cookbook/structuring-apis).
doc/cookbook/structuring-apis/structuring-apis.cabalnew file+24
@@ -0,0 +1,24 @@
1+name: cookbook-structuring-apis
2+version: 0.1
3+synopsis: Example that shows how APIs can be structured
4+homepage: http://haskell-servant.readthedocs.org/
5+license: BSD3
6+license-file: ../../../servant/LICENSE
7+author: Servant Contributors
8+maintainer: haskell-servant-maintainers@googlegroups.com
9+build-type: Simple
10+cabal-version: >=1.10
11+
12+executable cookbook-structuring-apis
13+ if impl(ghc < 7.10.1)
14+ buildable: False
15+ main-is: StructuringApis.lhs
16+ build-depends: base == 4.*
17+ , aeson
18+ , servant
19+ , servant-server
20+ , warp
21+ , markdown-unlit >= 0.4
22+ default-language: Haskell2010
23+ ghc-options: -Wall -pgmL markdown-unlit
24+ build-tool-depends: markdown-unlit:markdown-unlit