From 7802fa5b7e297b370e6c0221d8549ec436b729d4 Mon Sep 17 00:00:00 2001 From: Joe Nelson Date: Sun, 7 Sep 2014 09:38:30 -0700 Subject: [PATCH] Respond with 200 or 206 in ranged responses --- dbapi.cabal | 2 +- src/Dbapi.hs | 14 ++- test/Feature/RangeSpec.hs | 15 ++- test/Feature/StructureSpec.hs | 3 +- test/SpecHelper.hs | 11 +++ test/fixtures/schema.sql | 166 ++++++++++++++++++++++++++++++---- 6 files changed, 183 insertions(+), 28 deletions(-) diff --git a/dbapi.cabal b/dbapi.cabal index 0ddd649e9..1a7a6c662 100644 --- a/dbapi.cabal +++ b/dbapi.cabal @@ -61,7 +61,7 @@ Test-Suite spec Main-Is: Main.hs Other-Modules: Dbapi, Spec, SpecHelper Build-Depends: base, hspec2 - , hspec-wai + , hspec-wai >= 0.4.0 , HDBC, HDBC-postgresql , warp, wai >= 3.0.1 && < 3.0.2 , HTTP, convertible diff --git a/src/Dbapi.hs b/src/Dbapi.hs index ce052dda9..2c4f69fbb 100644 --- a/src/Dbapi.hs +++ b/src/Dbapi.hs @@ -96,17 +96,23 @@ app conn req respond = do respondWithRangedResult :: RangedResult -> Response respondWithRangedResult rr = - responseLBS status206 [ + responseLBS status [ jsonContentType, ("Content-Range", if rrTotal rr == 0 then "*/0" - else (BS.pack . show . rrFrom ) rr <> "-" - <> (BS.pack . show . rrTo ) rr <> "/" - <> (BS.pack . show . rrTotal) rr + else (BS.pack $ show from) <> "-" + <> (BS.pack $ show to) <> "/" + <> (BS.pack $ show total) ) ] (rrBody rr) + where + from = rrFrom rr + to = rrTo rr + total = rrTotal rr + status = if (1 + to - from) < total then status206 else status200 + requestedVersion :: RequestHeaders -> Maybe Int requestedVersion hdrs = case verStr of diff --git a/test/Feature/RangeSpec.hs b/test/Feature/RangeSpec.hs index b357575f3..aa43c70d7 100644 --- a/test/Feature/RangeSpec.hs +++ b/test/Feature/RangeSpec.hs @@ -1,15 +1,22 @@ -{-# LANGUAGE OverloadedStrings, QuasiQuotes #-} +{-# LANGUAGE OverloadedStrings #-} module Feature.RangeSpec where import Test.Hspec import Test.Hspec.Wai +import Network.HTTP.Types import SpecHelper spec :: Spec -spec = around appWithFixture $ do - describe "GET /view" $ +spec = around appWithFixture $ + describe "GET /items" $ do context "without range headers" $ context "with response under server size limit" $ it "returns whole range with status 200" $ - get "/auto_incrementing_pk" `shouldRespondWith` 206 + get "/items" `shouldRespondWith` 200 + context "with range headers" $ + context "of acceptable range" $ + it "succeeds with partial content" $ + request methodGet "/items" + (rangeHdrs $ ByteRangeFromTo 0 1) "" + `shouldRespondWith` 206 diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index abc88b274..0ebbee684 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -17,6 +17,7 @@ spec = around appWithFixture $ do [json| [ {"schema":"1","name":"auto_incrementing_pk","insertable":true} , {"schema":"1","name":"compound_pk","insertable":true} + , {"schema":"1","name":"items","insertable":true} , {"schema":"1","name":"menagerie","insertable":true} , {"schema":"1","name":"no_pk","insertable":true} , {"schema":"1","name":"simple_pk","insertable":true} @@ -26,7 +27,7 @@ spec = around appWithFixture $ do describe "Table info" $ it "is available with OPTIONS verb" $ -- {{{ big json object - request methodOptions "/auto_incrementing_pk" "" `shouldRespondWith` [json| + request methodOptions "/auto_incrementing_pk" [] "" `shouldRespondWith` [json| { "pkey":["id"], "columns":{ diff --git a/test/SpecHelper.hs b/test/SpecHelper.hs index 69d07b3c5..29f571ca7 100644 --- a/test/SpecHelper.hs +++ b/test/SpecHelper.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE OverloadedStrings #-} module SpecHelper where import Network.Wai @@ -8,6 +9,10 @@ import Database.HDBC.PostgreSQL import Control.Exception.Base (bracket) +import Network.HTTP.Types.Header +import Data.CaseInsensitive (CI(..)) +import qualified Data.ByteString.Char8 as BS + import Dbapi (app, AppConfig(..)) cfg :: AppConfig @@ -35,3 +40,9 @@ appWithFixture action = withDatabaseConnection $ \c -> do runRaw c "begin;" action $ app c rollback c + +rangeHdrs :: ByteRange -> [Header] +rangeHdrs r = [rangeUnit, (hRange, renderByteRange r)] + +rangeUnit :: Header +rangeUnit = ("Range-Unit" :: CI BS.ByteString, "items") diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index 961c1af2f..1353c8896 100644 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -4,7 +4,7 @@ -- Dumped from database version 9.3.4 -- Dumped by pg_dump version 9.3.1 --- Started on 2014-08-27 12:59:06 PDT +-- Started on 2014-08-31 10:00:41 PDT SET statement_timeout = 0; SET lock_timeout = 0; @@ -14,7 +14,7 @@ SET check_function_bodies = false; SET client_min_messages = warning; -- --- TOC entry 6 (class 2615 OID 230856) +-- TOC entry 6 (class 2615 OID 231254) -- Name: 1; Type: SCHEMA; Schema: -; Owner: - -- @@ -22,7 +22,7 @@ CREATE SCHEMA "1"; -- --- TOC entry 176 (class 3079 OID 12018) +-- TOC entry 178 (class 3079 OID 12018) -- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: - -- @@ -30,8 +30,8 @@ CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; -- --- TOC entry 2231 (class 0 OID 0) --- Dependencies: 176 +-- TOC entry 2248 (class 0 OID 0) +-- Dependencies: 178 -- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: - -- @@ -45,7 +45,7 @@ SET default_tablespace = ''; SET default_with_oids = false; -- --- TOC entry 170 (class 1259 OID 230857) +-- TOC entry 170 (class 1259 OID 231255) -- Name: auto_incrementing_pk; Type: TABLE; Schema: 1; Owner: -; Tablespace: -- @@ -58,7 +58,7 @@ CREATE TABLE auto_incrementing_pk ( -- --- TOC entry 171 (class 1259 OID 230864) +-- TOC entry 171 (class 1259 OID 231262) -- Name: auto_incrementing_pk_id_seq; Type: SEQUENCE; Schema: 1; Owner: - -- @@ -71,7 +71,7 @@ CREATE SEQUENCE auto_incrementing_pk_id_seq -- --- TOC entry 2232 (class 0 OID 0) +-- TOC entry 2249 (class 0 OID 0) -- Dependencies: 171 -- Name: auto_incrementing_pk_id_seq; Type: SEQUENCE OWNED BY; Schema: 1; Owner: - -- @@ -80,7 +80,7 @@ ALTER SEQUENCE auto_incrementing_pk_id_seq OWNED BY auto_incrementing_pk.id; -- --- TOC entry 172 (class 1259 OID 230866) +-- TOC entry 172 (class 1259 OID 231264) -- Name: compound_pk; Type: TABLE; Schema: 1; Owner: -; Tablespace: -- @@ -92,7 +92,39 @@ CREATE TABLE compound_pk ( -- --- TOC entry 173 (class 1259 OID 230869) +-- TOC entry 173 (class 1259 OID 231267) +-- Name: items; Type: TABLE; Schema: 1; Owner: -; Tablespace: +-- + +CREATE TABLE items ( + id bigint NOT NULL +); + + +-- +-- TOC entry 174 (class 1259 OID 231270) +-- Name: items_id_seq; Type: SEQUENCE; Schema: 1; Owner: - +-- + +CREATE SEQUENCE items_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- TOC entry 2250 (class 0 OID 0) +-- Dependencies: 174 +-- Name: items_id_seq; Type: SEQUENCE OWNED BY; Schema: 1; Owner: - +-- + +ALTER SEQUENCE items_id_seq OWNED BY items.id; + + +-- +-- TOC entry 175 (class 1259 OID 231272) -- Name: menagerie; Type: TABLE; Schema: 1; Owner: -; Tablespace: -- @@ -107,7 +139,7 @@ CREATE TABLE menagerie ( -- --- TOC entry 175 (class 1259 OID 230891) +-- TOC entry 176 (class 1259 OID 231278) -- Name: no_pk; Type: TABLE; Schema: 1; Owner: -; Tablespace: -- @@ -118,7 +150,7 @@ CREATE TABLE no_pk ( -- --- TOC entry 174 (class 1259 OID 230875) +-- TOC entry 177 (class 1259 OID 231284) -- Name: simple_pk; Type: TABLE; Schema: 1; Owner: -; Tablespace: -- @@ -129,7 +161,7 @@ CREATE TABLE simple_pk ( -- --- TOC entry 2110 (class 2604 OID 230881) +-- TOC entry 2116 (class 2604 OID 231290) -- Name: id; Type: DEFAULT; Schema: 1; Owner: - -- @@ -137,7 +169,96 @@ ALTER TABLE ONLY auto_incrementing_pk ALTER COLUMN id SET DEFAULT nextval('auto_ -- --- TOC entry 2112 (class 2606 OID 230883) +-- TOC entry 2117 (class 2604 OID 231291) +-- Name: id; Type: DEFAULT; Schema: 1; Owner: - +-- + +ALTER TABLE ONLY items ALTER COLUMN id SET DEFAULT nextval('items_id_seq'::regclass); + + +-- +-- TOC entry 2235 (class 0 OID 231255) +-- Dependencies: 170 +-- Data for Name: auto_incrementing_pk; Type: TABLE DATA; Schema: 1; Owner: - +-- + + + +-- +-- TOC entry 2251 (class 0 OID 0) +-- Dependencies: 171 +-- Name: auto_incrementing_pk_id_seq; Type: SEQUENCE SET; Schema: 1; Owner: - +-- + +SELECT pg_catalog.setval('auto_incrementing_pk_id_seq', 1, true); + + +-- +-- TOC entry 2237 (class 0 OID 231264) +-- Dependencies: 172 +-- Data for Name: compound_pk; Type: TABLE DATA; Schema: 1; Owner: - +-- + + + +-- +-- TOC entry 2238 (class 0 OID 231267) +-- Dependencies: 173 +-- Data for Name: items; Type: TABLE DATA; Schema: 1; Owner: - +-- + +INSERT INTO items (id) VALUES (1); +INSERT INTO items (id) VALUES (2); +INSERT INTO items (id) VALUES (3); +INSERT INTO items (id) VALUES (4); +INSERT INTO items (id) VALUES (5); +INSERT INTO items (id) VALUES (6); +INSERT INTO items (id) VALUES (7); +INSERT INTO items (id) VALUES (8); +INSERT INTO items (id) VALUES (9); +INSERT INTO items (id) VALUES (10); +INSERT INTO items (id) VALUES (11); +INSERT INTO items (id) VALUES (12); +INSERT INTO items (id) VALUES (13); +INSERT INTO items (id) VALUES (14); +INSERT INTO items (id) VALUES (15); + + +-- +-- TOC entry 2252 (class 0 OID 0) +-- Dependencies: 174 +-- Name: items_id_seq; Type: SEQUENCE SET; Schema: 1; Owner: - +-- + +SELECT pg_catalog.setval('items_id_seq', 15, true); + + +-- +-- TOC entry 2240 (class 0 OID 231272) +-- Dependencies: 175 +-- Data for Name: menagerie; Type: TABLE DATA; Schema: 1; Owner: - +-- + + + +-- +-- TOC entry 2241 (class 0 OID 231278) +-- Dependencies: 176 +-- Data for Name: no_pk; Type: TABLE DATA; Schema: 1; Owner: - +-- + + + +-- +-- TOC entry 2242 (class 0 OID 231284) +-- Dependencies: 177 +-- Data for Name: simple_pk; Type: TABLE DATA; Schema: 1; Owner: - +-- + + + +-- +-- TOC entry 2119 (class 2606 OID 231293) -- Name: auto_incrementing_pk_pkey; Type: CONSTRAINT; Schema: 1; Owner: -; Tablespace: -- @@ -146,7 +267,7 @@ ALTER TABLE ONLY auto_incrementing_pk -- --- TOC entry 2114 (class 2606 OID 230885) +-- TOC entry 2121 (class 2606 OID 231295) -- Name: compound_pk_pkey; Type: CONSTRAINT; Schema: 1; Owner: -; Tablespace: -- @@ -155,7 +276,7 @@ ALTER TABLE ONLY compound_pk -- --- TOC entry 2118 (class 2606 OID 230887) +-- TOC entry 2127 (class 2606 OID 231297) -- Name: contacts_pkey; Type: CONSTRAINT; Schema: 1; Owner: -; Tablespace: -- @@ -164,7 +285,16 @@ ALTER TABLE ONLY simple_pk -- --- TOC entry 2116 (class 2606 OID 230889) +-- TOC entry 2123 (class 2606 OID 231299) +-- Name: items_pkey; Type: CONSTRAINT; Schema: 1; Owner: -; Tablespace: +-- + +ALTER TABLE ONLY items + ADD CONSTRAINT items_pkey PRIMARY KEY (id); + + +-- +-- TOC entry 2125 (class 2606 OID 231301) -- Name: menagerie_pkey; Type: CONSTRAINT; Schema: 1; Owner: -; Tablespace: -- @@ -172,7 +302,7 @@ ALTER TABLE ONLY menagerie ADD CONSTRAINT menagerie_pkey PRIMARY KEY ("integer"); --- Completed on 2014-08-27 12:59:06 PDT +-- Completed on 2014-08-31 10:00:41 PDT -- -- PostgreSQL database dump complete