|
6 | 6 | {-# LANGUAGE LambdaCase #-}
|
7 | 7 | {-# LANGUAGE TupleSections #-}
|
8 | 8 | {-# LANGUAGE CPP #-}
|
| 9 | + |
9 | 10 | module Network.HTTP.ReverseProxy
|
10 | 11 | ( -- * Types
|
11 | 12 | ProxyDest (..)
|
@@ -78,6 +79,23 @@ data ProxyDest = ProxyDest
|
78 | 79 | , pdPort :: !Int
|
79 | 80 | } deriving (Read, Show, Eq, Ord, Generic)
|
80 | 81 |
|
| 82 | +-- | Trim optional whitespace (OWS) from both ends of a strict 'ByteString'. |
| 83 | + |
| 84 | +-- Per RFC 7230 §3.2.3, OWS = SP / HTAB. This function removes only leading |
| 85 | +-- and trailing space (0x20) and horizontal tab (0x09) bytes. It does not |
| 86 | +-- modify internal whitespace. |
| 87 | + |
| 88 | +-- On newer @bytestring@ versions (those that provide |
| 89 | +-- 'Data.ByteString.Char8.strip') this is a thin wrapper around that |
| 90 | +-- function; on older versions we provide a compatible fallback. |
| 91 | +trimOWS :: S8.ByteString -> S8.ByteString |
| 92 | +#if MIN_VERSION_bytestring(0,12,0) |
| 93 | +trimOWS = S8.strip |
| 94 | +#else |
| 95 | +trimOWS = S8.reverse . S8.dropWhile isOWS . S8.reverse . S8.dropWhile isOWS |
| 96 | + where isOWS c = c == ' ' || c == '\t' |
| 97 | +#endif |
| 98 | + |
81 | 99 | -- | Set up a reverse proxy server, which will have a minimal overhead.
|
82 | 100 | --
|
83 | 101 | -- This function uses raw sockets, parsing as little of the request as
|
@@ -361,7 +379,7 @@ fixReqHeaders wps req =
|
361 | 379 | fromSocket = (("X-Real-IP", S8.pack $ showSockAddr $ WAI.remoteHost req):)
|
362 | 380 | fromForwardedFor = do
|
363 | 381 | h <- lookup "x-forwarded-for" (WAI.requestHeaders req)
|
364 |
| - listToMaybe $ map S8.strip $ S8.split ',' h |
| 382 | + listToMaybe $ map trimOWS $ S8.split ',' h |
365 | 383 | addXRealIP =
|
366 | 384 | case wpsSetIpHeader wps of
|
367 | 385 | SIHFromSocket -> fromSocket
|
|
0 commit comments