|
Network.HTTP | Portability | non-portable (not tested) | Stability | experimental | Maintainer | bjorn@bringert.net |
|
|
|
|
|
Description |
An easy HTTP interface enjoy.
- Changes by Graham Klyne:
- export httpVersion
- use new URI module (similar to old, but uses revised URI datatype)
- Changes by Bjorn Bringert:
- handle URIs with a port number
- added debugging toggle
- disabled 100-continue transfers to get HTTP/1.0 compatibility
- change ioError to throw
- Changes from 0.1
- change openHTTP to openTCP, removed closeTCP - use close from Stream class.
- added use of inet_addr to openHTTP, allowing use of IP dot notation addresses.
- reworking of the use of Stream, including alterations to make sendHTTP generic
and the addition of a debugging stream.
- simplified error handling.
- TODO
- request pipelining
- https upgrade (includes full TLS, i.e. SSL, implementation)
- use of Stream classes will pay off
- consider C implementation of encryption/decryption
- comm timeouts
- MIME & entity stuff (happening in separate module)
- support "*" uri-request-string for OPTIONS request method
- Header notes:
- Host
-
Required by HTTP/1.1, if not supplied as part
of a request a default Host value is extracted
from the request-uri.
- Connection
-
If this header is present in any request or
response, and it's value is close, then
the current request/response is the last
to be allowed on that connection.
- Expect
-
Should a request contain a body, an Expect
header will be added to the request. The added
header has the value "100-continue". After
a 417 "Expectation Failed" response the request
is attempted again without this added Expect
header.
- TransferEncoding,ContentLength,...
-
if request is inconsistent with any of these
header values then you may not receive any response
or will generate an error response (probably 4xx).
- Response code notes
Some response codes induce special behaviour:
- 1xx
- "100 Continue" will cause any unsent request body to be sent.
"101 Upgrade" will be returned.
Other 1xx responses are ignored.
- 417
- The reason for this code is "Expectation failed", indicating
that the server did not like the Expect "100-continue" header
added to a request. Receipt of 417 will induce another
request attempt (without Expect header), unless no Expect header
had been added (in which case 417 response is returned).
|
|
Synopsis |
|
|
|
Documentation |
|
httpVersion :: String |
|
Type declarations
|
|
Streams
|
|
data Debug x |
Allows stream logging.
Refer to debugStream below.
| Instances | |
|
|
class Stream x where |
Streams should make layering of TLS protocol easier in future,
they allow readingwriting to files etc for debugging,
they allow use of protocols other than TCPIP
and they allow customisation.
Instances of this class should not trim
the input in any way, e.g. leave LF on line
endings etc. Unless that is exactly the behaviour
you want from your twisted instances ;)
| | Methods | readLine :: x -> IO (Result String) | | readBlock :: x -> Int -> IO (Result String) | | writeBlock :: x -> String -> IO (Result ()) | | close :: x -> IO () |
| | Instances | |
|
|
debugStream :: Stream a => String -> a -> IO (Debug a) |
Wraps a stream with logging I/O, the first
argument is a filename which is opened in AppendMode.
|
|
Connections
|
|
data Connection |
The Connection newtype is a wrapper that allows us to make
connections an instance of the StreamIn/Out classes, without ghc extensions.
While this looks sort of like a generic reference to the transport
layer it is actually TCP specific, which can be seen in the
implementation of the 'Stream Connection' instance.
| Instances | |
|
|
data ConnError |
Constructors | ErrorReset | | ErrorClosed | | ErrorParse String | | ErrorMisc String | |
| Instances | |
|
|
openTCP :: String -> IO Connection |
Open a connection to port 80 on a remote host.
|
|
isConnectedTo :: Connection -> String -> IO Bool |
|
HTTP
|
|
data Request |
An HTTP Request.
The Show instance of this type is used for message serialisation,
which means no body data is output.
| Constructors | Request | | rqURI :: URI | might need changing in future
1) to support * uri in OPTIONS request
2) transparent support for both relative
& absolute uris, although this should
already work (leave scheme & host parts empty).
| rqMethod :: RequestMethod | | rqHeaders :: [Header] | | rqBody :: String | |
|
| Instances | |
|
|
data Response |
An HTTP Response.
The Show instance of this type is used for message serialisation,
which means no body data is output, additionally the output will
show an HTTP version of 1.1 instead of the actual version returned
by a server.
| Constructors | Response | | rspCode :: ResponseCode | | rspReason :: String | | rspHeaders :: [Header] | | rspBody :: String | |
|
| Instances | |
|
|
data RequestMethod |
The HTTP request method, to be used in the Request object.
We are missing a few of the stranger methods, but these are
not really necessary until we add full TLS.
| Constructors | HEAD | | PUT | | GET | | POST | | OPTIONS | | TRACE | |
| Instances | |
|
|
simpleHTTP :: Request -> IO (Result Response) |
Simple way to get a resource across a non-persistant connection.
Headers that may be altered:
Host Altered only if no Host header is supplied, HTTP/1.1
requires a Host header.
Connection Where no allowance is made for persistant connections
the Connection header will be set to close
|
|
sendHTTP :: Stream s => s -> Request -> IO (Result Response) |
|
Header Functions
|
|
class HasHeaders x |
This class allows us to write generic header manipulation functions
for both Request and Response data types.
| | Instances | |
|
|
data Header |
The Header data type pairs header names & values.
| Constructors | | Instances | |
|
|
data HeaderName |
HTTP Header Name type:
Why include this at all? I have some reasons
1) prevent spelling errors of header names,
2) remind everyone of what headers are available,
3) might speed up searches for specific headers.
Arguments against:
1) makes customising header names laborious
2) increases code volume.
| Constructors | HdrCacheControl | | HdrConnection | | HdrDate | | HdrPragma | | HdrTransferEncoding | | HdrUpgrade | | HdrVia | | HdrAccept | | HdrAcceptCharset | | HdrAcceptEncoding | | HdrAcceptLanguage | | HdrAuthorization | | HdrCookie | | HdrExpect | | HdrFrom | | HdrHost | | HdrIfModifiedSince | | HdrIfMatch | | HdrIfNoneMatch | | HdrIfRange | | HdrIfUnmodifiedSince | | HdrMaxForwards | | HdrProxyAuthorization | | HdrRange | | HdrReferer | | HdrUserAgent | | HdrAge | | HdrLocation | | HdrProxyAuthenticate | | HdrPublic | | HdrRetryAfter | | HdrServer | | HdrSetCookie | | HdrVary | | HdrWarning | | HdrWWWAuthenticate | | HdrAllow | | HdrContentBase | | HdrContentEncoding | | HdrContentLanguage | | HdrContentLength | | HdrContentLocation | | HdrContentMD5 | | HdrContentRange | | HdrContentType | | HdrETag | | HdrExpires | | HdrLastModified | | HdrContentTransferEncoding | | HdrCustom String | Allows for unrecognised or experimental headers.
|
| Instances | |
|
|
insertHeader :: HasHeaders a => HeaderName -> String -> a -> a |
|
insertHeaderIfMissing :: HasHeaders a => HeaderName -> String -> a -> a |
|
insertHeaders :: HasHeaders a => [Header] -> a -> a |
Inserts multiple headers.
|
|
retrieveHeaders :: HasHeaders a => HeaderName -> a -> [Header] |
Gets a list of headers with a particular HeaderName.
|
|
replaceHeader :: HasHeaders a => HeaderName -> String -> a -> a |
|
URL Encoding
|
|
urlEncode :: String -> String |
|
urlDecode :: String -> String |
|
urlEncodeVars :: [(String, String)] -> String |
|
URI authority parsing
|
|
data URIAuthority |
Constructors | URIAuthority | | user :: (Maybe String) | | password :: (Maybe String) | | host :: String | | port :: (Maybe Int) | |
|
| Instances | |
|
|
parseURIAuthority :: String -> Maybe URIAuthority |
Parse the authority part of a URL.
RFC 1732, section 3.1:
//<user>:<password>@<host>:<port>/<url-path>
Some or all of the parts "<user>:<password>@", ":<password>",
":<port>", and "/<url-path>" may be excluded.
|
|
Produced by Haddock version 0.7 |