2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // http-protocol - HTTP protocol objects
22 #ifndef _H_HTTP_PROTOCOL
23 #define _H_HTTP_PROTOCOL
29 #include "netconnection.h"
30 #include <Security/ip++.h>
31 #include <Security/headermap.h>
32 #include <Security/inetreply.h>
40 // The Protocol object for the HTTP protocol
42 class HTTPProtocol
: public Protocol
{
45 static const IPPort defaultHttpPort
= 80;
47 HTTPProtocol(Manager
&mgr
, const char *scheme
= "http");
50 HTTPTransfer
*makeTransfer(const Target
&target
, Operation operation
);
53 class HTTPHeaderMap
: public HeaderMap
{
55 void merge(string key
, string
&old
, string newValue
);
60 // Our persistent connection object
62 class HTTPConnection
: public TCPConnection
{
63 static const int defaultSubVersion
= 1; // default to HTTP/1.1
65 HTTPConnection(Protocol
&proto
, const HostTarget
&tgt
);
67 // state machine master state
69 errorState
, // invalid state marker
70 connecting
, // awaiting transport level connection
71 primaryResponse
, // read primary response line
72 readHeaders
, // read initial headers
73 readWholeBody
, // read basic body (Transfer-Encoding: identity)
75 idle
, // between requests on persistent connection
78 // state submachine for Transfer-Encoding: chunked
79 chunkHeader
, // chunk header line (hex-length CRNL)
80 chunkDownload
, // data of chunk (read in autoReadInput mode)
81 chunkGap
, // empty line after chunk (now why did they do *that*?)
82 chunkTrailer
, // reading trailer header fields (why not :-)
84 START
= primaryResponse
87 HTTPTransfer
&transfer() { return transferAs
<HTTPTransfer
>(); }
90 void request(const char *operation
);
94 void transit(Event event
, char *input
, size_t inputLength
);
95 void transitError(const CssmCommonError
&error
);
97 void fail(bool forceDrop
= false); // direct fail
98 void fail(Transfer::ResultClass why
, OSStatus how
= Transfer::defaultOSStatusError
)
99 { transfer().fail(why
, how
); } // use in transit(): setup, throws, gets caught, then fails
104 void authorizationHeader(const char *headerName
,
105 const HostTarget
&host
,
106 ParameterSource::Key userKey
, ParameterSource::Key passKey
);
110 int subVersion
; // HTTP/1.x sub-protocol version
111 State state
; // master state machine switch
112 bool deferSendRequest
; // allows a subclass to interrupt state machine
113 string mOperation
; // requested HTTP operation
114 unsigned int httpVersionMajor
; // major version of peer
115 unsigned int httpVersionMinor
; // minor version of peer
120 // A generic Transfer object. All HTTP transfers are transactional (headers in, optional data in,
121 // headers out, optional data out), so there's no reason to distinguish subclasses.
123 class HTTPTransfer
: public Transfer
{
125 HTTPTransfer(Protocol
&proto
, const Target
&tgt
, Operation operation
, IPPort defaultPort
);
127 // access to HTTP-specific protocol details
128 string
&httpResponse() { return mPrimaryResponseString
; }
129 unsigned int &httpResponseCode() { return mPrimaryResponseCode
; }
130 unsigned int httpResponseCode() const { return mPrimaryResponseCode
; }
131 HeaderMap
&httpHeaders() { return mHeaders
; }
133 void fail(ResultClass how
, OSStatus err
= defaultOSStatusError
);
136 ResultClass
resultClass() const;
138 void startRequest(); // start request on our Connection
139 virtual bool useProxyHeaders() const; // should we use proxy form of request headers?
142 void start(); // start HTTP
143 void abort(); // abort the Transfer
146 string mPrimaryResponseString
; // HTTP protocol first response line
147 unsigned int mPrimaryResponseCode
; // numeric response code
148 ResultClass mResultClass
; // explicit classification (unclassified if not set)
149 HTTPHeaderMap mHeaders
; // map of response headers
157 inline HeaderMap
&HTTPProtocol::HTTPConnection::headers()
158 { return transfer().httpHeaders(); }
161 } // end namespace Network
162 } // end namespace Security
165 #endif //_H_HTTP_PROTOCOL