Copyright | (c) Soostone Inc. 2014-2015 Michael Xavier 2014-2015 |
---|---|
License | BSD3 |
Maintainer | michael.xavier@soostone.com |
Stability | experimental |
Safe Haskell | None |
Language | Haskell2010 |
URI.ByteString
Contents
Description
URI.ByteString aims to be an RFC3986 compliant URI parser that uses efficient ByteStrings for parsing and representing the data. This module provides a URI datatype as well as a parser and serializer.
Note that this library is an early release and may have issues. It is currently being used in production and no issues have been encountered, however. Please report any issues encountered to the issue tracker.
This module also provides analogs to Lens over the various types in this library. These are written in a generic way to avoid a dependency on any particular lens library. You should be able to use these with a number of packages including lens and lens-family-core.
Synopsis
- newtype Scheme = Scheme {}
- newtype Host = Host {
- hostBS :: ByteString
- newtype Port = Port {
- portNumber :: Int
- data Authority = Authority {}
- data UserInfo = UserInfo {}
- newtype Query = Query {
- queryPairs :: [(ByteString, ByteString)]
- data URIRef a where
- data Absolute
- data Relative
- data SchemaError
- data URIParseError
- data URIParserOptions = URIParserOptions {
- upoValidQueryChar :: Word8 -> Bool
- strictURIParserOptions :: URIParserOptions
- laxURIParserOptions :: URIParserOptions
- data URINormalizationOptions = URINormalizationOptions {}
- noNormalization :: URINormalizationOptions
- rfc3986Normalization :: URINormalizationOptions
- httpNormalization :: URINormalizationOptions
- aggressiveNormalization :: URINormalizationOptions
- httpDefaultPorts :: Map Scheme Port
- toAbsolute :: Scheme -> URIRef a -> URIRef Absolute
- parseURI :: URIParserOptions -> ByteString -> Either URIParseError (URIRef Absolute)
- parseRelativeRef :: URIParserOptions -> ByteString -> Either URIParseError (URIRef Relative)
- uriParser :: URIParserOptions -> Parser (URIRef Absolute)
- relativeRefParser :: URIParserOptions -> Parser (URIRef Relative)
- serializeURIRef :: URIRef a -> Builder
- serializeURIRef' :: URIRef a -> ByteString
- normalizeURIRef :: URINormalizationOptions -> URIRef a -> Builder
- normalizeURIRef' :: URINormalizationOptions -> URIRef a -> ByteString
- urlDecode :: Bool -> ByteString -> ByteString
- urlDecodeQuery :: ByteString -> ByteString
- urlEncodeQuery :: ByteString -> Builder
- urlEncodePath :: ByteString -> Builder
- urlEncode :: [Word8] -> ByteString -> Builder
- schemeBSL :: Lens' Scheme ByteString
- hostBSL :: Lens' Host ByteString
- portNumberL :: Lens' Port Int
- authorityUserInfoL :: Lens' Authority (Maybe UserInfo)
- authorityHostL :: Lens' Authority Host
- authorityPortL :: Lens' Authority (Maybe Port)
- uiUsernameL :: Lens' UserInfo ByteString
- uiPasswordL :: Lens' UserInfo ByteString
- queryPairsL :: Lens' Query [(ByteString, ByteString)]
- uriSchemeL :: Lens' (URIRef Absolute) Scheme
- authorityL :: Lens' (URIRef a) (Maybe Authority)
- pathL :: Lens' (URIRef a) ByteString
- queryL :: Lens' (URIRef a) Query
- fragmentL :: Lens' (URIRef a) (Maybe ByteString)
- upoValidQueryCharL :: Lens' URIParserOptions (Word8 -> Bool)
- type URI = URIRef Absolute
- type RelativeRef = URIRef Relative
- serializeURI :: URIRef Absolute -> Builder
- serializeURI' :: URIRef Absolute -> ByteString
- serializeRelativeRef :: URIRef Relative -> Builder
- serializeRelativeRef' :: URIRef Relative -> ByteString
- uriAuthorityL :: Lens' URI (Maybe Authority)
- uriPathL :: Lens' URI ByteString
- uriQueryL :: Lens' URI Query
- uriFragmentL :: Lens' URI (Maybe ByteString)
- rrAuthorityL :: Lens' RelativeRef (Maybe Authority)
- rrPathL :: Lens' RelativeRef ByteString
- rrQueryL :: Lens' RelativeRef Query
- rrFragmentL :: Lens' RelativeRef (Maybe ByteString)
URI-related types
Required first component to referring to a specification for the remainder of the URI's components, e.g. "http" or "https"
Constructors
Scheme | |
Fields |
Instances
Eq Scheme # | |
Ord Scheme # | |
Show Scheme # | |
Generic Scheme # | |
Lift Scheme # | |
type Rep Scheme # | |
Defined in URI.ByteString.Types type Rep Scheme = D1 (MetaData "Scheme" "URI.ByteString.Types" "uri-bytestring-0.3.2.1-E97hLkCGU7IJfkG5biBeXE" True) (C1 (MetaCons "Scheme" PrefixI True) (S1 (MetaSel (Just "schemeBS") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 ByteString))) |
Constructors
Host | |
Fields
|
Instances
Eq Host # | |
Ord Host # | |
Show Host # | |
Generic Host # | |
Lift Host # | |
type Rep Host # | |
Defined in URI.ByteString.Types type Rep Host = D1 (MetaData "Host" "URI.ByteString.Types" "uri-bytestring-0.3.2.1-E97hLkCGU7IJfkG5biBeXE" True) (C1 (MetaCons "Host" PrefixI True) (S1 (MetaSel (Just "hostBS") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 ByteString))) |
While some libraries have chosen to limit this to a Word16, the spec only specifies that the string be comprised of digits.
Constructors
Port | |
Fields
|
Constructors
Authority | |
Fields |
Instances
Eq Authority # | |
Ord Authority # | |
Show Authority # | |
Generic Authority # | |
Lift Authority # | |
type Rep Authority # | |
Defined in URI.ByteString.Types type Rep Authority = D1 (MetaData "Authority" "URI.ByteString.Types" "uri-bytestring-0.3.2.1-E97hLkCGU7IJfkG5biBeXE" False) (C1 (MetaCons "Authority" PrefixI True) (S1 (MetaSel (Just "authorityUserInfo") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Maybe UserInfo)) :*: (S1 (MetaSel (Just "authorityHost") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Host) :*: S1 (MetaSel (Just "authorityPort") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Maybe Port))))) |
Constructors
UserInfo | |
Fields |
Instances
Eq UserInfo # | |
Ord UserInfo # | |
Defined in URI.ByteString.Types | |
Show UserInfo # | |
Generic UserInfo # | |
Lift UserInfo # | |
type Rep UserInfo # | |
Defined in URI.ByteString.Types type Rep UserInfo = D1 (MetaData "UserInfo" "URI.ByteString.Types" "uri-bytestring-0.3.2.1-E97hLkCGU7IJfkG5biBeXE" False) (C1 (MetaCons "UserInfo" PrefixI True) (S1 (MetaSel (Just "uiUsername") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 ByteString) :*: S1 (MetaSel (Just "uiPassword") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 ByteString))) |
Constructors
Query | |
Fields
|
Instances
Eq Query # | |
Ord Query # | |
Show Query # | |
Generic Query # | |
Semigroup Query # | |
Monoid Query # | |
Lift Query # | |
type Rep Query # | |
Defined in URI.ByteString.Types type Rep Query = D1 (MetaData "Query" "URI.ByteString.Types" "uri-bytestring-0.3.2.1-E97hLkCGU7IJfkG5biBeXE" True) (C1 (MetaCons "Query" PrefixI True) (S1 (MetaSel (Just "queryPairs") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 [(ByteString, ByteString)]))) |
Note: URI fragment does not include the #
Constructors
URI | |
Fields
| |
RelativeRef | |
Fields
|
data SchemaError #
URI Parser Types
Constructors
NonAlphaLeading | Scheme must start with an alphabet character |
InvalidChars | Subsequent characters in the schema were invalid |
MissingColon | Schemas must be followed by a colon |
Instances
Eq SchemaError # | |
Defined in URI.ByteString.Types | |
Read SchemaError # | |
Defined in URI.ByteString.Types Methods readsPrec :: Int -> ReadS SchemaError # readList :: ReadS [SchemaError] # readPrec :: ReadPrec SchemaError # readListPrec :: ReadPrec [SchemaError] # | |
Show SchemaError # | |
Defined in URI.ByteString.Types Methods showsPrec :: Int -> SchemaError -> ShowS # show :: SchemaError -> String # showList :: [SchemaError] -> ShowS # | |
Generic SchemaError # | |
Defined in URI.ByteString.Types Associated Types type Rep SchemaError :: Type -> Type # | |
type Rep SchemaError # | |
Defined in URI.ByteString.Types type Rep SchemaError = D1 (MetaData "SchemaError" "URI.ByteString.Types" "uri-bytestring-0.3.2.1-E97hLkCGU7IJfkG5biBeXE" False) (C1 (MetaCons "NonAlphaLeading" PrefixI False) (U1 :: Type -> Type) :+: (C1 (MetaCons "InvalidChars" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "MissingColon" PrefixI False) (U1 :: Type -> Type))) |
data URIParseError #
Constructors
MalformedScheme SchemaError | |
MalformedUserInfo | |
MalformedQuery | |
MalformedFragment | |
MalformedHost | |
MalformedPort | |
MalformedPath | |
OtherError String | Catchall for unpredictable errors |
Instances
data URIParserOptions #
Options for the parser. You will probably want to use either "strictURIParserOptions" or "laxURIParserOptions"
Constructors
URIParserOptions | |
Fields
|
strictURIParserOptions :: URIParserOptions #
Strict URI Parser config. Follows RFC3986 as-specified. Use this if you can be certain that your URIs are properly encoded or if you want parsing to fail if they deviate from the spec at all.
laxURIParserOptions :: URIParserOptions #
Lax URI Parser config. Use this if you you want to handle common deviations from the spec gracefully.
- Allows non-encoded [ and ] in query string
data URINormalizationOptions #
Constructors
URINormalizationOptions | |
Fields
|
Instances
Eq URINormalizationOptions # | |
Defined in URI.ByteString.Types Methods (==) :: URINormalizationOptions -> URINormalizationOptions -> Bool # (/=) :: URINormalizationOptions -> URINormalizationOptions -> Bool # | |
Show URINormalizationOptions # | |
Defined in URI.ByteString.Types Methods showsPrec :: Int -> URINormalizationOptions -> ShowS # show :: URINormalizationOptions -> String # showList :: [URINormalizationOptions] -> ShowS # |
noNormalization :: URINormalizationOptions #
All normalization options disabled
rfc3986Normalization :: URINormalizationOptions #
Only normalizations deemed appropriate for all protocols by RFC3986 enabled, namely:
- Downcase Scheme
- Downcase Host
- Remove Dot Segments
httpNormalization :: URINormalizationOptions #
The same as rfc3986Normalization
but with additional enabled
features if you're working with HTTP URIs:
- Drop Default Port (with
httpDefaultPorts
) - Drop Extra Slashes
aggressiveNormalization :: URINormalizationOptions #
All options enabled
httpDefaultPorts :: Map Scheme Port #
The set of known default ports to schemes. Currently only
contains http/80 and https/443. Feel free to extend it if needed
with unoDefaultPorts
.
Operations
toAbsolute :: Scheme -> URIRef a -> URIRef Absolute #
toAbsolute scheme ref
converts ref
to an absolute URI.
If ref
is already absolute, then it is unchanged.
Parsing
parseURI :: URIParserOptions -> ByteString -> Either URIParseError (URIRef Absolute) #
Parse a strict ByteString into a URI or an error.
Example:
>>>
parseURI strictURIParserOptions "http://www.example.org/foo?bar=baz#quux"
Right (URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar","baz")]}, uriFragment = Just "quux"})
>>>
parseURI strictURIParserOptions "$$$$://badurl.example.org"
Left (MalformedScheme NonAlphaLeading)
There are some urls that you'll encounter which defy the spec, such as those with square brackets in the query string. If you must be able to parse those, you can use "laxURIParserOptions" or specify your own
>>>
parseURI strictURIParserOptions "http://www.example.org/foo?bar[]=baz"
Left MalformedQuery
>>>
parseURI laxURIParserOptions "http://www.example.org/foo?bar[]=baz"
Right (URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar[]","baz")]}, uriFragment = Nothing})
>>>
let myLaxOptions = URIParserOptions { upoValidQueryChar = liftA2 (||) (upoValidQueryChar strictURIParserOptions) (inClass "[]")}
>>>
parseURI myLaxOptions "http://www.example.org/foo?bar[]=baz"
Right (URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar[]","baz")]}, uriFragment = Nothing})
parseRelativeRef :: URIParserOptions -> ByteString -> Either URIParseError (URIRef Relative) #
Like parseURI
, but do not parse scheme.
uriParser :: URIParserOptions -> Parser (URIRef Absolute) #
Underlying attoparsec parser. Useful for composing with your own parsers.
relativeRefParser :: URIParserOptions -> Parser (URIRef Relative) #
Underlying attoparsec parser. Useful for composing with your own parsers.
Serializing
serializeURIRef :: URIRef a -> Builder #
URI Serializer
Serialize a URI reference into a Builder
.
Example of serializing + converting to a lazy Data.ByteString.Lazy.ByteString:
>>>
BB.toLazyByteString $ serializeURIRef $ URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "www.example.org"}, authorityPort = Nothing}), uriPath = "/foo", uriQuery = Query {queryPairs = [("bar","baz")]}, uriFragment = Just "quux"}
"http://www.example.org/foo?bar=baz#quux"
serializeURIRef' :: URIRef a -> ByteString #
Like serializeURIRef
, with conversion into a strict ByteString
.
Normalized Serialization
normalizeURIRef :: URINormalizationOptions -> URIRef a -> Builder #
Similar to serializeURIRef
but performs configurable degrees of
URI normalization. If your goal is the fastest serialization speed
possible, serializeURIRef
will be fine. If you intend on
comparing URIs (say for caching purposes), you'll want to use this.
normalizeURIRef' :: URINormalizationOptions -> URIRef a -> ByteString #
Low level utility functions
Arguments
:: Bool | Whether to decode |
-> ByteString | |
-> ByteString |
This function was extracted from the http-types
package. The
license can be found in licenseshttp-typesLICENSE
urlDecodeQuery :: ByteString -> ByteString #
ByteString Utilities
Decoding specifically for the query string, which decodes + as
space. Shorthand for urlDecode True
urlEncodeQuery :: ByteString -> Builder #
Encode a ByteString for use in the query section of a URL
urlEncodePath :: ByteString -> Builder #
Encode a ByteString for use in the path section of a URL
urlEncode :: [Word8] -> ByteString -> Builder #
Percent-encoding for URLs. Specify a list of additional unreserved characters to permit.
Lenses
Lenses over Scheme
schemeBSL :: Lens' Scheme ByteString #
Lenses over Host
hostBSL :: Lens' Host ByteString #
Lenses over Port
portNumberL :: Lens' Port Int #
Lenses over Authority
authorityUserInfoL :: Lens' Authority (Maybe UserInfo) #
authorityHostL :: Lens' Authority Host #
authorityPortL :: Lens' Authority (Maybe Port) #
Lenses over UserInfo
uiUsernameL :: Lens' UserInfo ByteString #
uiPasswordL :: Lens' UserInfo ByteString #
Lenses over Query
queryPairsL :: Lens' Query [(ByteString, ByteString)] #
Lenses over URIRef
uriSchemeL :: Lens' (URIRef Absolute) Scheme #
authorityL :: Lens' (URIRef a) (Maybe Authority) #
pathL :: Lens' (URIRef a) ByteString #
fragmentL :: Lens' (URIRef a) (Maybe ByteString) #
Lenses over URIParserOptions
upoValidQueryCharL :: Lens' URIParserOptions (Word8 -> Bool) #
Deprecated
type RelativeRef = URIRef Relative #
serializeURI :: URIRef Absolute -> Builder #
Deprecated: Use serializeURIRef
instead
Serialize a URI into a Builder.
serializeURI' :: URIRef Absolute -> ByteString #
Deprecated: Use serializeURIRef'
instead
Like serializeURI
, with conversion into a strict ByteString
.
serializeRelativeRef :: URIRef Relative -> Builder #
Deprecated: Use serializeURIRef
instead
Like serializeURI
, but do not render scheme.
serializeRelativeRef' :: URIRef Relative -> ByteString #
Deprecated: Use serializeURIRef'
instead
Like serializeRelativeRef
, with conversion into a strict ByteString
.
uriAuthorityL :: Lens' URI (Maybe Authority) #
Deprecated: Use authorityL
instead
uriPathL :: Lens' URI ByteString #
Deprecated: Use pathL
instead
uriFragmentL :: Lens' URI (Maybe ByteString) #
Deprecated: Use fragmentL
instead
rrAuthorityL :: Lens' RelativeRef (Maybe Authority) #
Deprecated: Use authorityL
instead
rrPathL :: Lens' RelativeRef ByteString #
Deprecated: Use pathL
instead
rrQueryL :: Lens' RelativeRef Query #
Deprecated: Use queryL
instead
rrFragmentL :: Lens' RelativeRef (Maybe ByteString) #
Deprecated: Use fragmentL
instead