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
{
64 HTTPConnection(Protocol
&proto
, const HostTarget
&tgt
);
66 // state machine master state
68 errorState
, // invalid state marker
69 connecting
, // awaiting transport level connection
70 primaryResponse
, // read primary response line
71 readHeaders
, // read initial headers
72 readWholeBody
, // read basic body (Transfer-Encoding: identity)
74 idle
, // between requests on persistent connection
77 // state submachine for Transfer-Encoding: chunked
78 chunkHeader
, // chunk header line (hex-length CRNL)
79 chunkDownload
, // data of chunk (read in autoReadInput mode)
80 chunkGap
, // empty line after chunk (now why did they do *that*?)
81 chunkTrailer
, // reading trailer header fields (why not :-)
83 START
= primaryResponse
86 HTTPTransfer
&transfer() { return transferAs
<HTTPTransfer
>(); }
89 void request(const char *operation
);
93 void transit(Event event
, char *input
, size_t inputLength
);
94 void transitError(const CssmCommonError
&error
);
96 void fail(bool forceDrop
= false); // direct fail
97 void fail(Transfer::ResultClass why
, OSStatus how
= Transfer::defaultOSStatusError
)
98 { transfer().fail(why
, how
); } // use in transit(): setup, throws, gets caught, then fails
103 void authorizationHeader(const char *headerName
,
104 const HostTarget
&host
,
105 ParameterSource::Key userKey
, ParameterSource::Key passKey
);
109 State state
; // master state machine switch
110 bool deferSendRequest
; // allows a subclass to interrupt state machine
111 string mOperation
; // requested HTTP operation
112 unsigned int httpVersionMajor
; // major version of peer
113 unsigned int httpVersionMinor
; // minor version of peer
118 // A generic Transfer object. All HTTP transfers are transactional (headers in, optional data in,
119 // headers out, optional data out), so there's no reason to distinguish subclasses.
121 class HTTPTransfer
: public Transfer
{
123 HTTPTransfer(Protocol
&proto
, const Target
&tgt
, Operation operation
, IPPort defaultPort
);
125 // access to HTTP-specific protocol details
126 string
&httpResponse() { return mPrimaryResponseString
; }
127 unsigned int &httpResponseCode() { return mPrimaryResponseCode
; }
128 unsigned int httpResponseCode() const { return mPrimaryResponseCode
; }
129 HeaderMap
&httpHeaders() { return mHeaders
; }
131 void fail(ResultClass how
, OSStatus err
= defaultOSStatusError
);
134 ResultClass
resultClass() const;
136 void startRequest(); // start request on our Connection
137 virtual bool useProxyHeaders() const; // should we use proxy form of request headers?
140 void start(); // start HTTP
141 void abort(); // abort the Transfer
144 string mPrimaryResponseString
; // HTTP protocol first response line
145 unsigned int mPrimaryResponseCode
; // numeric response code
146 ResultClass mResultClass
; // explicit classification (unclassified if not set)
147 HTTPHeaderMap mHeaders
; // map of response headers
155 inline HeaderMap
&HTTPProtocol::HTTPConnection::headers()
156 { return transfer().httpHeaders(); }
159 } // end namespace Network
160 } // end namespace Security
163 #endif //_H_HTTP_PROTOCOL