]> git.saurik.com Git - apple/security.git/blob - Network/http-protocol.h
6e53321ef43266f4c698bab0ac37f696aaab3b2b
[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 public:
44 class HTTPTransfer;
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 protected:
59 //
60 // Our persistent connection object
61 //
62 class HTTPConnection : public TCPConnection {
63 static const int defaultSubVersion = 1; // default to HTTP/1.1
64 public:
65 HTTPConnection(Protocol &proto, const HostTarget &tgt);
66
67 // state machine master state
68 enum 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)
74
75 idle, // between requests on persistent connection
76 dead, // RIP
77
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 :-)
83
84 START = primaryResponse
85 };
86
87 HTTPTransfer &transfer() { return transferAs<HTTPTransfer>(); }
88 HeaderMap &headers();
89
90 void request(const char *operation);
91 void abort();
92
93 protected:
94 void transit(Event event, char *input, size_t inputLength);
95 void transitError(const CssmCommonError &error);
96 void finish();
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
100 bool validate();
101
102 void sendRequest();
103 void hostHeader();
104 void authorizationHeader(const char *headerName,
105 const HostTarget &host,
106 ParameterSource::Key userKey, ParameterSource::Key passKey);
107 void chooseRetain();
108
109 protected:
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
116 };
117
118 public:
119 //
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.
122 //
123 class HTTPTransfer : public Transfer {
124 public:
125 HTTPTransfer(Protocol &proto, const Target &tgt, Operation operation, IPPort defaultPort);
126
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; }
132
133 void fail(ResultClass how, OSStatus err = defaultOSStatusError);
134
135 // diagnostics
136 ResultClass resultClass() const;
137
138 void startRequest(); // start request on our Connection
139 virtual bool useProxyHeaders() const; // should we use proxy form of request headers?
140
141 protected:
142 void start(); // start HTTP
143 void abort(); // abort the Transfer
144
145 private:
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
150 };
151 };
152
153
154 //
155 // Deferred inlines
156 //
157 inline HeaderMap &HTTPProtocol::HTTPConnection::headers()
158 { return transfer().httpHeaders(); }
159
160
161 } // end namespace Network
162 } // end namespace Security
163
164
165 #endif //_H_HTTP_PROTOCOL