]> git.saurik.com Git - apple/security.git/blob - Network/http-protocol.h
09ffd3bd63bceae304a97ae6e50243e3be3c7e24
[apple/security.git] / Network / http-protocol.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 //
20 // http-protocol - HTTP protocol objects
21 //
22 #ifndef _H_HTTP_PROTOCOL
23 #define _H_HTTP_PROTOCOL
24
25 #include "neterror.h"
26 #include "xfercore.h"
27 #include "protocol.h"
28 #include "transfer.h"
29 #include "netconnection.h"
30 #include <Security/ip++.h>
31 #include <Security/headermap.h>
32 #include <Security/inetreply.h>
33
34
35 namespace Security {
36 namespace Network {
37
38
39 //
40 // The Protocol object for the HTTP protocol
41 //
42 class HTTPProtocol : public Protocol {
43 class HTTPTransfer;
44 public:
45 static const IPPort defaultHttpPort = 80;
46
47 HTTPProtocol(Manager &mgr, const char *scheme = "http");
48
49 public:
50 HTTPTransfer *makeTransfer(const Target &target, Operation operation);
51
52 private:
53 class HTTPHeaderMap : public HeaderMap {
54 public:
55 void merge(string key, string &old, string newValue);
56 };
57
58 private:
59 //
60 // Our persistent connection object
61 //
62 class HTTPConnection : public TCPConnection {
63 public:
64 HTTPConnection(Protocol &proto, const HostTarget &tgt);
65
66 // state machine master state
67 enum 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)
73
74 idle, // between requests on persistent connection
75 dead, // RIP
76
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 :-)
82
83 START = primaryResponse
84 };
85
86 HTTPTransfer &transfer() { return transferAs<HTTPTransfer>(); }
87 HeaderMap &headers();
88
89 void request(const char *operation);
90 void abort();
91
92 protected:
93 void transit(Event event, char *input, size_t inputLength);
94 void transitError(const CssmCommonError &error);
95 void finish();
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
99 bool validate();
100
101 void sendRequest();
102 void hostHeader();
103 void authorizationHeader(const char *headerName,
104 const HostTarget &host,
105 ParameterSource::Key userKey, ParameterSource::Key passKey);
106 void chooseRetain();
107
108 protected:
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
114 };
115
116
117 //
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.
120 //
121 class HTTPTransfer : public Transfer {
122 public:
123 HTTPTransfer(Protocol &proto, const Target &tgt, Operation operation, IPPort defaultPort);
124
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; }
130
131 void fail(ResultClass how, OSStatus err = defaultOSStatusError);
132
133 // diagnostics
134 ResultClass resultClass() const;
135
136 void startRequest(); // start request on our Connection
137 virtual bool useProxyHeaders() const; // should we use proxy form of request headers?
138
139 protected:
140 void start(); // start HTTP
141 void abort(); // abort the Transfer
142
143 private:
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
148 };
149 };
150
151
152 //
153 // Deferred inlines
154 //
155 inline HeaderMap &HTTPProtocol::HTTPConnection::headers()
156 { return transfer().httpHeaders(); }
157
158
159 } // end namespace Network
160 } // end namespace Security
161
162
163 #endif //_H_HTTP_PROTOCOL