diff --git a/http-streams.cabal b/http-streams.cabal
--- a/http-streams.cabal
+++ b/http-streams.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >= 1.10
 name:                http-streams
-version:             0.3.1.0
+version:             0.4.0.0
 synopsis:            An HTTP client using io-streams
 description:
  /Overview/
diff --git a/src/Network/Http/Client.hs b/src/Network/Http/Client.hs
--- a/src/Network/Http/Client.hs
+++ b/src/Network/Http/Client.hs
@@ -40,7 +40,7 @@
 \ main = do
 \     c <- 'openConnection' \"www.example.com\" 80
 
-\     q <- 'buildRequest' c $ do
+\     q <- 'buildRequest' $ do
 \         'http' GET \"\/\"
 \         'setAccept' \"text/html\"
 
@@ -159,7 +159,10 @@
     openConnectionSSL,
     baselineContextSSL,
     modifyContextSSL,
-    establishConnection
+    establishConnection,
+
+    -- * Testing support
+    makeConnection
 ) where
 
 import Network.Http.Connection
diff --git a/src/Network/Http/Connection.hs b/src/Network/Http/Connection.hs
--- a/src/Network/Http/Connection.hs
+++ b/src/Network/Http/Connection.hs
@@ -23,6 +23,7 @@
     openConnection,
     openConnectionSSL,
     closeConnection,
+    getHostname,
     sendRequest,
     receiveResponse,
     emptyBody,
@@ -68,34 +69,53 @@
             -- ^ will be used as the Host: header in the HTTP request.
         cClose :: IO (),
             -- ^ called when the connection should be closed.
-        cOut   :: OutputStream ByteString,
+        cOut   :: OutputStream Builder,
         cIn    :: InputStream ByteString
     }
 
 instance Show Connection where
     show c =    {-# SCC "Connection.show" #-}
         concat
-           ["Connection {",
-            "cHost = \"",
+           ["Host: ",
              S.unpack $ cHost c,
-             "\"}"]
+             "\n"]
 
 
 --
--- | Creates a raw Connection object from the given parts.
+-- | Create a raw Connection object from the given parts. This is
+-- primarily of use when teseting, for example:
 --
+-- > fakeConnection :: IO Connection
+-- > fakeConnection = do
+-- >     o  <- Streams.nullOutput
+-- >     i  <- Streams.nullInput
+-- >     c  <- makeConnection "www.example.com" (return()) o i
+-- >     return c
+--
+-- is an idiom we use frequently in testing and benchmarking, usually
+-- replacing the InputStream with something like:
+--
+-- >     x' <- S.readFile "properly-formatted-response.txt"
+-- >     i  <- Streams.fromByteString x'
+--
+-- If you're going to do that, keep in mind that you /must/ have CR-LF
+-- pairs after each header line and between the header and body to
+-- be compliant with the HTTP protocol; otherwise, parsers will
+-- reject your message.
+--
 makeConnection
     :: ByteString
-    -- ^ will be used as the Host: header in the HTTP request.
+    -- ^ will be used as the @Host:@ header in the HTTP request.
     -> IO ()
-    -- ^ called when the connection is terminated.
+    -- ^ an action to be called when the connection is terminated.
     -> OutputStream ByteString
-    -- ^ write end of the HTTP client connection.
+    -- ^ write end of the HTTP client-server connection.
     -> InputStream ByteString
-    -- ^ read end of the client connection.
+    -- ^ read end of the HTTP client-server connection.
     -> IO Connection
-makeConnection h c o i =
-    return $! Connection h c o i
+makeConnection h c o1 i = do
+    o2 <- Streams.builderStream o1
+    return $! Connection h c o2 i
 
 
 --
@@ -104,7 +124,7 @@
 -- @Connection@ afterwards.
 --
 -- >     x <- withConnection (openConnection "s3.example.com" 80) $ (\c -> do
--- >         q <- buildRequest c $ do
+-- >         q <- buildRequest $ do
 -- >             http GET "/bucket42/object/149"
 -- >         sendRequest c q emptyBody
 -- >         ...
@@ -156,11 +176,14 @@
     s <- socket (addrFamily addr) Stream defaultProtocol
 
     connect s a
-    (i,o) <- Streams.socketToStreams s
+    (i,o1) <- Streams.socketToStreams s
+
+    o2 <- Streams.builderStream o1
+
     return Connection {
         cHost  = h',
         cClose = close s,
-        cOut   = o,
+        cOut   = o2,
         cIn    = i
     }
   where
@@ -212,11 +235,14 @@
     ssl <- SSL.connection ctx s
     SSL.connect ssl
 
-    (i,o) <- Streams.sslToStreams ssl
+    (i,o1) <- Streams.sslToStreams ssl
+
+    o2 <- Streams.builderStream o1
+
     return Connection {
         cHost  = h',
         cClose = closeSSL s ssl,
-        cOut   = o,
+        cOut   = o2,
         cIn    = i
     }
   where
@@ -253,8 +279,6 @@
 -}
 sendRequest :: Connection -> Request -> (OutputStream Builder -> IO α) -> IO α
 sendRequest c q handler = do
-    o2 <- Streams.builderStream o1
-
     -- write the headers
 
     Streams.write (Just msg) o2
@@ -306,15 +330,29 @@
     return x
 
   where
-    o1 = cOut c
+    o2 = cOut c
     e = qBody q
     t = qExpect q
-    msg = composeRequestBytes q
+    msg = composeRequestBytes q h'
+    h' = cHost c
     i = cIn c
     rsp p = Builder.toByteString $ composeResponseBytes p
 
 
 --
+-- | Get the virtual hostname that will be used as the @Host:@ header in
+-- the HTTP 1.1 request. Per RFC 2616 § 14.23, this will be of the form
+-- @hostname:port@ if the port number is other than the default, ie 80
+-- for HTTP.
+--
+getHostname :: Connection -> Request -> ByteString
+getHostname c q =
+    case qHost q of
+        Just h' -> h'
+        Nothing -> cHost c
+
+
+--
 -- | Handle the response coming back from the server. This function
 -- hands control to a handler function you supply, passing you the
 -- 'Response' object with the response headers and an 'InputStream'
@@ -422,7 +460,7 @@
 --
 -- >     c <- openConnection "kernel.operationaldynamics.com" 58080
 -- >
--- >     q <- buildRequest c $ do
+-- >     q <- buildRequest $ do
 -- >         http GET "/time"
 -- >
 -- >     sendRequest c q emptyBody
@@ -445,7 +483,7 @@
 --
 debugHandler :: Response -> InputStream ByteString -> IO ()
 debugHandler p i = do
-    putStr $ show p
+    S.putStr $ S.filter (/= '\r') $ Builder.toByteString $ composeResponseBytes p
     Streams.connect i stdout
 
 
diff --git a/src/Network/Http/Inconvenience.hs b/src/Network/Http/Inconvenience.hs
--- a/src/Network/Http/Inconvenience.hs
+++ b/src/Network/Http/Inconvenience.hs
@@ -155,7 +155,7 @@
 -- >     let url = "https://www.example.com/photo.jpg"
 -- >
 -- >     c <- establishConnection url
--- >     q <- buildRequest c $ do
+-- >     q <- buildRequest $ do
 -- >         http GET url
 -- >     ...
 --
@@ -237,8 +237,17 @@
 
 ------------------------------------------------------------------------------
 
+{-
+    Account for bug where "http://www.example.com" is parsed with no
+    path element, resulting in an illegal HTTP request line.
+-}
+
 path :: URI -> ByteString
-path u = T.encodeUtf8 $! T.pack
+path u = case url of
+            ""  -> "/"
+            _   -> url
+  where
+    url = T.encodeUtf8 $! T.pack
                       $! concat [uriPath u, uriQuery u, uriFragment u]
 
 
@@ -282,7 +291,7 @@
     u = parseURL r'
 
     process c = do
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http GET (path u)
             setAccept "*/*"
 
@@ -348,7 +357,7 @@
     u = parseURL r'
 
     process c = do
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http POST (path u)
             setAccept "*/*"
             setContentType t
@@ -385,7 +394,7 @@
     u = parseURL r'
 
     process c = do
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http POST (path u)
             setAccept "*/*"
             setContentType "application/x-www-form-urlencoded"
@@ -455,7 +464,7 @@
     u = parseURL r'
 
     process c = do
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http PUT (path u)
             setAccept "*/*"
             setHeader "Content-Type" t
diff --git a/src/Network/Http/RequestBuilder.hs b/src/Network/Http/RequestBuilder.hs
--- a/src/Network/Http/RequestBuilder.hs
+++ b/src/Network/Http/RequestBuilder.hs
@@ -30,7 +30,8 @@
 import Blaze.ByteString.Builder (Builder)
 import qualified Blaze.ByteString.Builder as Builder (fromByteString,
                                                       toByteString)
-import qualified Blaze.ByteString.Builder.Char8 as Builder (fromShow)
+import qualified Blaze.ByteString.Builder.Char8 as Builder (fromShow,
+                                                            fromString)
 import Control.Monad.State
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Base64 as BS64
@@ -53,20 +54,27 @@
 -- | Run a RequestBuilder, yielding a Request object you can use on the
 -- given connection.
 --
--- >     q <- buildRequest c $ do
+-- >     q <- buildRequest $ do
 -- >         http POST "/api/v1/messages"
 -- >         setContentType "application/json"
+-- >         setHostname "clue.example.com" 80
 -- >         setAccept "text/html"
 -- >         setHeader "X-WhoDoneIt" "The Butler"
 --
 -- Obviously it's up to you to later actually /send/ JSON data.
 --
-buildRequest :: Connection -> RequestBuilder α -> IO Request
-buildRequest c mm = do
+-- /Note/
+--
+-- The API of this function changed from version 0.3.1 to verison 0.4.0;
+-- the original requirement to pass a Connection object has been removed,
+-- thereby allowing you to build your Request before opening the
+-- connection to the web server.
+--
+buildRequest :: RequestBuilder α -> IO Request
+buildRequest mm = do
     let (RequestBuilder s) = (mm)
-    let h = cHost c
     let q = Request {
-        qHost = h,
+        qHost = Nothing,
         qMethod = GET,
         qPath = "/",
         qBody = Empty,
@@ -83,7 +91,7 @@
 http m p' = do
     q <- get
     let h0 = qHeaders q
-    let h1 = updateHeader h0 "User-Agent" "http-streams/0.3.1.0"
+    let h1 = updateHeader h0 "User-Agent" "http-streams/0.4.0.0"
     let h2 = updateHeader h1 "Accept-Encoding" "gzip"
 
     let e  = case m of
@@ -109,12 +117,20 @@
 -- header in HTTP 1.1 and is set directly from the name of the server
 -- you connected to when calling 'Network.Http.Connection.openConnection'.
 --
-setHostname :: ByteString -> RequestBuilder ()
-setHostname v' = do
+setHostname :: Hostname -> Port -> RequestBuilder ()
+setHostname h p = do
     q <- get
     put q {
-        qHost = v'
+        qHost = Just v'
     }
+  where
+    v' :: ByteString
+    v' = if p == 80
+        then S.pack h
+        else Builder.toByteString $ mconcat
+           [Builder.fromString h,
+            ":",
+            Builder.fromShow p]
 
 --
 -- | Set a generic header to be sent in the HTTP request. The other
@@ -199,7 +215,7 @@
 -- >         setAuthorizationBasic "Aladdin" "open sesame"
 --
 -- will result in an @Authorization:@ header value of
--- @Basic: QWxhZGRpbjpvcGVuIHNlc2FtZQ==@.
+-- @Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==@.
 --
 -- Basic authentication does /not/ use a message digest function to
 -- encipher the password; the above string is only base-64 encoded and
@@ -210,7 +226,7 @@
 -- validate requests. Keep in mind in these cases the secret is still
 -- sent to the servers on the other side and passes in clear through
 -- all layers after the SSL termination. Do /not/ use basic
--- authentication to protect secure or user-originaed privacy-sensitve
+-- authentication to protect secure or user-originated privacy-sensitve
 -- information.
 --
 {-
diff --git a/src/Network/Http/ResponseParser.hs b/src/Network/Http/ResponseParser.hs
--- a/src/Network/Http/ResponseParser.hs
+++ b/src/Network/Http/ResponseParser.hs
@@ -62,22 +62,44 @@
 
     hs <- many parseHeader
 
-    let hp = buildHeaders hs
-
     _ <- crlf
 
+    let h  = buildHeaders hs
+    let te = case lookupHeader h "Transfer-Encoding" of
+            Just x' -> if mk x' == "chunked"
+                        then Chunked
+                        else None
+            Nothing -> None
+
+    let ce = case lookupHeader h "Content-Encoding" of
+            Just x' -> if mk x' == "gzip"
+                        then Gzip
+                        else Identity
+            Nothing -> Identity
+
+    let n  = case lookupHeader h "Content-Length" of
+            Just x' -> readDecimal x' :: Int
+            Nothing -> 0
+
     return Response {
         pStatusCode = sc,
         pStatusMsg = sm,
-        pHeaders = hp
+        pTransferEncoding = te,
+        pContentEncoding = ce,
+        pContentLength = n,
+        pHeaders = h
     }
+  where
 
 
+
 parseStatusLine :: Parser (Int,ByteString)
 parseStatusLine = do
-    sc <- string "HTTP/1.1 " *> decimal <* char ' '
+    sc <- string "HTTP/1." *> satisfy version *> char ' ' *> decimal <* char ' '
     sm <- takeTill (== '\r') <* crlf
     return (sc,sm)
+  where
+    version c = c == '1' || c == '0'
 
 {-
     Needs to be expanded to accept multi-line headers.
@@ -111,36 +133,20 @@
 readResponseBody :: Response -> InputStream ByteString -> IO (InputStream ByteString)
 readResponseBody p i1 = do
 
-    i2 <- case encoding of
+    i2 <- case t of
         None        -> readFixedLengthBody i1 n
         Chunked     -> readChunkedBody i1
 
-    i3 <- case compression of
+    i3 <- case c of
         Identity    -> return i2
         Gzip        -> readCompressedBody i2
-        Deflate     -> throwIO (UnexpectedCompression $ show compression)
+        Deflate     -> throwIO (UnexpectedCompression $ show c)
 
     return i3
   where
-
-    encoding = case header "Transfer-Encoding" of
-        Just x'-> if mk x' == "chunked"
-                    then Chunked
-                    else None
-        Nothing -> None
-
-    compression = case header "Content-Encoding" of
-        Just x'-> if mk x' == "gzip"
-                    then Gzip
-                    else Identity
-        Nothing -> Identity
-
-    header = getHeader p
-
-    n = case header "Content-Length" of
-        Just x' -> readDecimal x' :: Int
-        Nothing -> 0
-
+    t = pTransferEncoding p
+    c = pContentEncoding p
+    n = pContentLength p
 
 readDecimal :: (Enum a, Num a, Bits a) => ByteString -> a
 readDecimal = S.foldl' f 0
@@ -152,12 +158,6 @@
     digitToInt c | c >= '0' && c <= '9' = toEnum $! ord c - ord '0'
                  | otherwise = error $ "'" ++ [c] ++ "' is not an ascii digit"
 {-# INLINE readDecimal #-}
-
-
-data TransferEncoding = None | Chunked
-
-data ContentEncoding = Identity | Gzip | Deflate
-    deriving (Show)
 
 data UnexpectedCompression = UnexpectedCompression String
         deriving (Typeable, Show)
diff --git a/src/Network/Http/Types.hs b/src/Network/Http/Types.hs
--- a/src/Network/Http/Types.hs
+++ b/src/Network/Http/Types.hs
@@ -9,6 +9,7 @@
 -- the BSD licence.
 --
 
+{-# LANGUAGE BangPatterns      #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# OPTIONS -fno-warn-orphans #-}
 
@@ -16,9 +17,10 @@
     Request(..),
     EntityBody(..),
     ExpectMode(..),
-    getHostname,
     Response(..),
     StatusCode,
+    TransferEncoding(..),
+    ContentEncoding(..),
     getStatusCode,
     getStatusMessage,
     getHeader,
@@ -49,6 +51,7 @@
 import Data.CaseInsensitive (CI, mk, original)
 import Data.HashMap.Strict (HashMap, delete, empty, foldrWithKey, insert,
                             lookup)
+import Data.List (foldl')
 import Data.Monoid (mconcat, mempty)
 import Data.String (IsString, fromString)
 
@@ -100,19 +103,24 @@
 -- line and headers (as it will be sent over the wire but with the @\\r@
 -- characters stripped) which can be handy for debugging.
 --
+-- Note that the @Host:@ header is not set until
+-- 'Network.Http.Connection.sendRequest' is called, so you will not see
+-- it in the Show instance (unless you call 'setHostname' to override
+-- the value inherited from the @Connection@).
+--
 data Request
     = Request {
-        qMethod  :: Method,
-        qHost    :: ByteString,
-        qPath    :: ByteString,
-        qBody    :: EntityBody,
-        qExpect  :: ExpectMode,
-        qHeaders :: Headers
+        qMethod  :: !Method,
+        qHost    ::  Maybe ByteString,
+        qPath    :: !ByteString,
+        qBody    :: !EntityBody,
+        qExpect  :: !ExpectMode,
+        qHeaders :: !Headers
     }
 
 instance Show Request where
     show q = {-# SCC "Request.show" #-}
-        S.unpack $ S.filter (/= '\r') $ Builder.toByteString $ composeRequestBytes q
+        S.unpack $ S.filter (/= '\r') $ Builder.toByteString $ composeRequestBytes q "<default>"
 
 
 data EntityBody = Empty | Chunking | Static Int
@@ -132,8 +140,8 @@
     with removing them.
 -}
 
-composeRequestBytes :: Request -> Builder
-composeRequestBytes q =
+composeRequestBytes :: Request -> ByteString -> Builder
+composeRequestBytes q h' =
     mconcat
        [requestline,
         hostLine,
@@ -147,24 +155,29 @@
         " ",
         version,
         "\r\n"]
-    method = Builder.fromString $ show $ qMethod q
+    method = case qMethod q of
+        GET     -> "GET"
+        HEAD    -> "HEAD"
+        POST    -> "POST"
+        PUT     -> "PUT"
+        DELETE  -> "DELETE"
+        TRACE   -> "TRACE"
+        OPTIONS -> "OPTIONS"
+        CONNECT -> "CONNECT"
+        PATCH   -> "PATCH"
+        (Method x) -> Builder.fromByteString x
+
     uri = Builder.copyByteString $ qPath q
     version = "HTTP/1.1"
 
     hostLine = mconcat ["Host: ", hostname, "\r\n"]
-    hostname = Builder.copyByteString $ qHost q
+    hostname = case qHost q of
+        Just x' -> Builder.copyByteString x'
+        Nothing -> Builder.copyByteString h'
 
     headerFields = joinHeaders $ unWrap $ qHeaders q
 
 
---
--- | Get the virtual hostname that will be used as the @Host:@ header in
--- the HTTP 1.1 request. Per RFC 2616 § 14.23, this will be of the form
--- @hostname:port@ if the port number is other than the default, ie 80
--- for HTTP.
---
-getHostname :: Request -> ByteString
-getHostname q = qHost q
 
 type StatusCode = Int
 
@@ -180,15 +193,25 @@
 --
 data Response
     = Response {
-        pStatusCode :: StatusCode,
-        pStatusMsg  :: ByteString,
-        pHeaders    :: Headers
+        pStatusCode       :: !StatusCode,
+        pStatusMsg        :: !ByteString,
+        pTransferEncoding :: !TransferEncoding,
+        pContentEncoding  :: !ContentEncoding,
+        pContentLength    :: !Int,
+        pHeaders          :: !Headers
     }
 
 instance Show Response where
     show p =     {-# SCC "Response.show" #-}
         S.unpack $ S.filter (/= '\r') $ Builder.toByteString $ composeResponseBytes p
 
+
+data TransferEncoding = None | Chunked
+
+data ContentEncoding = Identity | Gzip | Deflate
+    deriving (Show)
+
+
 --
 -- | Get the HTTP response status code.
 --
@@ -250,6 +273,7 @@
 
 instance IsString Builder where
     fromString x = Builder.fromString x
+    {-# INLINE fromString #-}
 
 --
 -- | The map of headers in a 'Request' or 'Response'. Note that HTTP
@@ -298,15 +322,15 @@
 updateHeader x k v =
     Wrap result
   where
-    result = insert (mk k) v m
-    m = unWrap x
+    !result = insert (mk k) v m
+    !m = unWrap x
 
 removeHeader :: Headers -> ByteString -> Headers
 removeHeader x k =
     Wrap result
   where
-    result = delete (mk k) m
-    m = unWrap x
+    !result = delete (mk k) m
+    !m = unWrap x
 
 
 {-
@@ -319,18 +343,18 @@
 buildHeaders hs =
     Wrap result
   where
-    result = foldr addHeader empty hs
+    result = foldl' addHeader empty hs
 
 addHeader
-    :: (ByteString,ByteString)
-    -> HashMap (CI ByteString) ByteString
+    :: HashMap (CI ByteString) ByteString
+    -> (ByteString,ByteString)
     -> HashMap (CI ByteString) ByteString
-addHeader (k,v) m =
+addHeader m (k,v) =
     insert (mk k) v m
 
 lookupHeader :: Headers -> ByteString -> Maybe ByteString
 lookupHeader x k =
     lookup (mk k) m
   where
-    m = unWrap x
+    !m = unWrap x
 
diff --git a/tests/Check.hs b/tests/Check.hs
--- a/tests/Check.hs
+++ b/tests/Check.hs
@@ -24,7 +24,7 @@
 import Network.URI (parseURI)
 import OpenSSL (withOpenSSL)
 import Test.Hspec (Spec, describe, hspec, it)
-import Test.Hspec.Expectations (shouldThrow, Selector, anyException)
+import Test.Hspec.Expectations (Selector, anyException, shouldThrow)
 import Test.HUnit
 
 --
@@ -71,6 +71,7 @@
 
     describe "Parsing responses" $ do
         testResponseParser1
+        testResponseParserMismatch
         testChunkedEncoding
         testContentLength
         testCompressedResponse
@@ -83,6 +84,7 @@
         testPostChunks
         testPostWithForm
         testGetRedirects
+        testGetFormatsRequest
         testExcessiveRedirects
         testGeneralHandler
         testEstablishConnection
@@ -91,11 +93,11 @@
 testRequestTermination =
     it "terminates with a blank line" $ do
         c <- openConnection "127.0.0.1" localPort
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http GET "/time"
             setAccept "text/plain"
 
-        let e' = Builder.toByteString $ composeRequestBytes q
+        let e' = Builder.toByteString $ composeRequestBytes q "booga"
         let n = S.length e' - 4
         let (a',b') = S.splitAt n e'
 
@@ -110,10 +112,10 @@
         (fakeConnection)
         (return)
         (\c -> do
-            q <- buildRequest c $ do
+            q <- buildRequest $ do
                 http GET "/time"
 
-            let e' = Builder.toByteString $ composeRequestBytes q
+            let e' = Builder.toByteString $ composeRequestBytes q (cHost c)
             let l' = S.takeWhile (/= '\r') e'
 
             assertEqual "Invalid HTTP request line" "GET /time HTTP/1.1" l')
@@ -123,18 +125,13 @@
 fakeConnection = do
     i <- Streams.nullInput
     o <- Streams.nullOutput
-    return $ Connection {
-        cHost  = "www.example.com",
-        cClose = return (),
-        cIn    = i,
-        cOut   = o
-    }
+    c <- makeConnection "www.example.com" (return ()) o i
+    return c
 
 
 testAcceptHeaderFormat =
     it "properly formats Accept header" $ do
-        c <- fakeConnection
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             setAccept' [("text/html", 1),("*/*", 0.0)]
 
         let h = qHeaders q
@@ -143,8 +140,7 @@
 
 testBasicAuthorizatonHeader =
     it "properly formats Authorization header" $ do
-        c <- fakeConnection
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             setAuthorizationBasic "Aladdin" "open sesame"
 
         let h = qHeaders q
@@ -176,33 +172,56 @@
 -}
 testEnsureHostField =
     it "has a properly formatted Host header" $ do
-        c <- fakeConnection
-        q1 <- buildRequest c $ do
+        q1 <- buildRequest $ do
             http GET "/hello.txt"
 
         let h1 = qHost q1
-        assertEqual "Incorrect Host header" "www.example.com" h1
+        assertEqual "Incorrect Host header" Nothing h1
 
-        q2 <- buildRequest c $ do
+        q2 <- buildRequest $ do
             http GET "/hello.txt"
-            setHostname "other.example.com"
+            setHostname "other.example.com" 80
 
         let h2 = qHost q2
-        assertEqual "Incorrect Host header" "other.example.com" h2
+        assertEqual "Incorrect Host header" (Just "other.example.com") h2
 
+        q3 <- buildRequest $ do
+            http GET "/hello.txt"
+            setHostname "other.example.com" 54321
 
+        let h3 = qHost q3
+        assertEqual "Incorrect Host header" (Just "other.example.com:54321") h3
+
+
 testResponseParser1 =
     it "parses a simple 200 response" $ do
         b' <- S.readFile "tests/example1.txt"
-        parseTest parseResponse b'
+        let re = parseOnly parseResponse b'
+        let p = case re of
+                    Left str    -> error str
+                    Right x     -> x
+
+        assertEqual "Incorrect parse of response" 200 (getStatusCode p)
         return ()
 
+testResponseParserMismatch =
+    it "parses response when HTTP version doesn't match" $ do
+        b' <- S.readFile "tests/example3.txt"
+        let re = parseOnly parseResponse b'
+        let p = case re of
+                    Left str    -> error str
+                    Right x     -> x
 
+        assertEqual "Incorrect parse of response" 200 (getStatusCode p)
+        return ()
+
+
+
 testChunkedEncoding =
     it "recognizes chunked transfer encoding and decodes" $ do
         c <- openConnection "127.0.0.1" localPort
 
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http GET "/time"
 
         sendRequest c q emptyBody
@@ -221,7 +240,7 @@
     it "recognzies fixed length message" $ do
         c <- openConnection "127.0.0.1" localPort
 
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http GET "/static/statler.jpg"
 
         sendRequest c q emptyBody
@@ -252,7 +271,7 @@
     it "recognizes gzip content encoding and decompresses" $ do
         c <- openConnection "127.0.0.1" localPort
 
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http GET "/static/hello.html"
             setHeader "Accept-Encoding" "gzip"
 
@@ -284,7 +303,7 @@
     it "sends expectation and handles 100 response" $ do
         c <- openConnection "127.0.0.1" localPort
 
-        q <- buildRequest c $ do
+        q <- buildRequest $ do
             http PUT "/resource/x149"
             setExpectContinue
 
@@ -388,7 +407,13 @@
             len <- getCount
             assertEqual "Incorrect number of bytes read" 29 len
 
+testGetFormatsRequest =
+    it "GET includes a properly formatted request path" $ do
+        let url = S.concat ["http://", localhost ]
+        x' <- get "http://localhost" concatHandler'
 
+        assertBool "Incorrect context path" (S.length x' > 0)
+
 testExcessiveRedirects =
     it "too many redirects result in an exception" $ do
         let url = S.concat ["http://", localhost, "/loop"]
@@ -435,7 +460,7 @@
         let url = S.concat ["http://", localhost, "/static/statler.jpg"]
 
         x' <- withConnection (establishConnection url) $ (\c -> do
-            q <- buildRequest c $ do
+            q <- buildRequest $ do
                 http GET "/static/statler.jpg"
                     -- TODO be nice if we could replace that with 'url';
                     -- fix the routeRequests function in TestServer maybe?
