1 martin 1.60 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.61 //
|
3 martin 1.60 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.61 //
|
10 martin 1.60 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.61 //
|
17 martin 1.60 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.61 //
|
20 martin 1.60 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.61 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.60 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.61 //
|
28 martin 1.60 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.2 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #ifndef Pegasus_HTTPConnection_h
33 #define Pegasus_HTTPConnection_h
34
35 #include <iostream>
|
36 brian.campbell 1.27 #include <Pegasus/Common/Exception.h>
|
37 mike 1.2 #include <Pegasus/Common/Config.h>
38 #include <Pegasus/Common/MessageQueue.h>
39 #include <Pegasus/Common/String.h>
40 #include <Pegasus/Common/Message.h>
|
41 kumpf 1.63 #include <Pegasus/Common/HTTPMessage.h>
|
42 kumpf 1.14 #include <Pegasus/Common/ArrayInternal.h>
|
43 mike 1.2 #include <Pegasus/Common/AuthenticationInfo.h>
44 #include <Pegasus/Common/TLS.h>
|
45 kumpf 1.13 #include <Pegasus/Common/Linkage.h>
|
46 kumpf 1.54 #include <Pegasus/Common/SharedPtr.h>
|
47 kumpf 1.44 #include <Pegasus/Common/ContentLanguageList.h>
|
48 mike 1.43 #include <Pegasus/Common/Buffer.h>
|
49 kumpf 1.58 #include <Pegasus/Common/PegasusAssert.h>
|
50 mike 1.2
51 PEGASUS_NAMESPACE_BEGIN
52
|
53 mday 1.15 class Monitor;
|
54 kumpf 1.58 class HTTPAcceptor;
|
55 mday 1.15
|
56 mday 1.5 class PEGASUS_COMMON_LINKAGE HTTPConnection : public MessageQueue
|
57 mike 1.2 {
|
58 kumpf 1.39 public:
59 typedef MessageQueue Base;
|
60 david.dillard 1.37
|
61 kumpf 1.39 /** Constructor. */
62 HTTPConnection(
|
63 david.dillard 1.38 Monitor* monitor,
|
64 kumpf 1.54 SharedPtr<MP_Socket>& socket,
|
65 kumpf 1.51 const String& ipAddress,
|
66 kumpf 1.58 HTTPAcceptor * owningAcceptor,
|
67 sushma.fernandes 1.50 MessageQueue * outputMessageQueue);
|
68 mday 1.4
|
69 kumpf 1.39 /** Destructor. */
70 ~HTTPConnection();
|
71 mday 1.4
|
72 kumpf 1.49 virtual void enqueue(Message *);
73
|
74 sahana.prabhakar 1.66 /**
75 In this specialization of isActive a check is performed on the
76 non-blocking socket to see if it is active by reading 1 byte. Since the
77 current thread is processing the request, its safe to try to read 1 byte
78 from the socket as there should be no data on the socket. If read
79 returns a message of size zero, it is an indication that the client has
80 closed the connection and the socket at the server end can be closed.
81 */
82 virtual Boolean isActive();
83
|
84 kumpf 1.39 /** This method is called whenever a SocketMessage is enqueued
85 on the input queue of the HTTPConnection object.
86 */
87 virtual void handleEnqueue(Message *);
|
88 brian.campbell 1.30
|
89 kumpf 1.39 virtual void handleEnqueue();
|
90 brian.campbell 1.31
|
91 kumpf 1.39 /** Return socket this connection is using. */
|
92 mike 1.47 SocketHandle getSocket() { return _socket->getSocket();}
|
93 mike 1.2
|
94 kumpf 1.39 MP_Socket& getMPSocket() { return *_socket;}
|
95 mike 1.2
|
96 kumpf 1.56 /** Indicates whether this connection has an outstanding response.
|
97 kumpf 1.39 */
|
98 kumpf 1.56 Boolean isResponsePending();
|
99 kumpf 1.39
100 Boolean run(Uint32 milliseconds);
101
|
102 kumpf 1.58 HTTPAcceptor& getOwningAcceptor()
|
103 kumpf 1.39 {
|
104 kumpf 1.58 PEGASUS_ASSERT(_owningAcceptor);
105 return *_owningAcceptor;
|
106 kumpf 1.39 }
107
108 // was the request for chunking ?
109 Boolean isChunkRequested();
110
|
111 marek 1.48 void setSocketWriteTimeout(Uint32 socketWriteTimeout);
|
112 kavita.gupta 1.59 static void setIdleConnectionTimeout(Uint32 idleConnectionTimeout);
113 static Uint32 getIdleConnectionTimeout();
|
114 marek 1.48
|
115 dave.sudlik 1.55 Boolean closeConnectionOnTimeout(struct timeval* timeNow);
116
|
117 harsha.bm 1.65 // This method is called in Client code to decide reconnection with
118 // the Server and can also be used in the server code to check if the
119 // connection is still alive and take appropriate action.
120 Boolean needsReconnect();
121
|
122 venkat.puvvada 1.64 // This method is called in Server code when response encoders or
123 // HTTPAuthenticatorDelegator runs out-of-memory. This method calls
124 // _handleWriteEvent() with a dummy HTTPMessage to maintain response
125 // chunk sequence properly. Once all responses are arrived, connection
126 // is closed. Param "respMsgIndex" indicates the response index and
127 // isComplete indicates whether the response is complete or not.
128 void handleInternalServerError(
129 Uint32 respMsgIndex,
130 Boolean isComplete);
131
|
132 kumpf 1.39 // ATTN-RK-P1-20020521: This is a major hack, required to get the CIM
133 // server and tests to run successfully. The problem is that the
134 // HTTPAcceptor is deleting an HTTPConnection before all the threads
135 // that are queued up to run in that HTTPConnection instance have had
136 // a chance to finish. This hack makes the HTTPAcceptor spin until
137 // the HTTPConnection event threads have completed, before deleting
138 // the HTTPConnection. Note that this fix is not perfect, because
139 // there is a window between when the HTTPConnection queue lookup is
140 // done and when the refcount is incremented. If the HTTPAcceptor
141 // deletes the HTTPConnection in that window, the soon-to-be-launched
142 // HTTPConnection event thread will fail (hard).
143 AtomicInt refcount;
144
145 CIMException cimException;
146
147 // list of content languages
|
148 kumpf 1.44 ContentLanguageList contentLanguages;
|
149 kumpf 1.39
150 private:
151
152 void _clearIncoming();
153
154 /**
|
155 david.dillard 1.37 @exception Exception Indicates an error occurred.
|
156 kumpf 1.39 */
157 void _getContentLengthAndContentOffset();
|
158 mike 1.2
|
159 kumpf 1.39 void _closeConnection();
|
160 mike 1.2
|
161 kumpf 1.39 void _handleReadEvent();
|
162 mike 1.2
|
163 kumpf 1.63 Boolean _handleWriteEvent(HTTPMessage& httpMessage);
|
164 brian.campbell 1.27
|
165 kumpf 1.46 void _handleReadEventFailure(const String& httpStatusWithDetail,
166 const String& cimError = String());
|
167 kumpf 1.39 void _handleReadEventTransferEncoding();
168 Boolean _isClient();
169
170 Monitor* _monitor;
171
|
172 kumpf 1.54 SharedPtr<MP_Socket> _socket;
|
173 kumpf 1.51 String _ipAddress;
|
174 kumpf 1.58 HTTPAcceptor* _owningAcceptor;
|
175 kumpf 1.39 MessageQueue* _outputMessageQueue;
176
177 Sint32 _contentOffset;
178 Sint32 _contentLength;
|
179 mike 1.43 Buffer _incomingBuffer;
|
180 kumpf 1.54 SharedPtr<AuthenticationInfo> _authInfo;
|
181 kumpf 1.39
182 // _connectionRequestCount contains the number of
183 // requests that have been received on this connection.
184 Uint32 _connectionRequestCount;
185
|
186 kumpf 1.56 /**
187 The _responsePending flag indicates whether the a request has been
188 received on the connection and is awaiting a response. It is set to
189 true when a request is received on the connection and set to false
190 when a response is sent. The connection object must not be destructed
191 while a response is pending, because the CIM Server must route the
192 response to the connection object when it becomes available.
193 */
|
194 kumpf 1.39 Boolean _responsePending;
195
196 Mutex _connection_mut;
197
198 // The _connectionClosePending flag will be set to true if
199 // the connection receives a close connection socket message.
200 // This flag is used to set the connection status to
201 // either Monitor::IDLE (_connectionClosePending == false)
202 // or Monitor::DYING (_connectionClosePending == true) when
203 // returning control of the connection to the Monitor.
204 Boolean _connectionClosePending;
205
|
206 kumpf 1.40 // The _acceptPending flag is set to true if a server-side
207 // connection is accepted but an SSL handshake has not been
208 // completed.
209 Boolean _acceptPending;
210
|
211 marek 1.67 // The _httpMethodNotChecked flag is disabled after the first bytes of a
212 // request were read and validated to be one of the supported HTTP methods
213 // "POST" or "M-POST".
214 Boolean _httpMethodNotChecked;
|
215 thilo.boehm 1.57
|
216 dave.sudlik 1.55 // Holds time since the accept pending condition was detected.
217 struct timeval _acceptPendingStartTime;
218
|
219 kumpf 1.39 int _entry_index;
220
221 // When used by the client, it is an offset (from start of http message)
222 // representing last NON completely parsed chunk of a transfer encoding.
223 // When used by the server, it is the message index that comes down
|
224 a.dunfey 1.53 // from the providers/repository representing each message chunk.
225 // WARNING: Due to the duel use of this member variable, modifying code
226 // that uses this variable should be done very carefully. Accidental bugs
227 // introduced could easily break interoperability with wbem
228 // clients/servers that transfer and/or receive data via HTTP chunking.
|
229 kumpf 1.39 Uint32 _transferEncodingChunkOffset;
230
231 // list of transfer encoding values from sender
232 Array<String> _transferEncodingValues;
233
234 // list of TE values from client
235 Array<String> _transferEncodingTEValues;
236
237 // 2 digit prefix on http header if mpost was used
238 String _mpostPrefix;
239
|
240 dave.sudlik 1.55 // Holds time since this connection is idle.
241 struct timeval _idleStartTime;
242
243 // Idle connection timeout in seconds specified by Config property
244 // idleConnectionTimeout.
|
245 kavita.gupta 1.59 static Uint32 _idleConnectionTimeoutSeconds;
246 #ifndef PEGASUS_INTEGERS_BOUNDARY_ALIGNED
247 static Mutex _idleConnectionTimeoutSecondsMutex;
248 #endif
|
249 venkat.puvvada 1.64 // When this flag is set to true, it indicates that internal error on this
250 // connection occured. Currently this flag is used by the Server code when
251 // out-of-memory error is occurs and connection is closed by the server
252 // once all responses are arrived.
253 Boolean _internalError;
|
254 dave.sudlik 1.55
|
255 kumpf 1.39 friend class Monitor;
256 friend class HTTPAcceptor;
257 friend class HTTPConnector;
|
258 mike 1.2 };
|
259 mday 1.16
|
260 mike 1.2 PEGASUS_NAMESPACE_END
261
262 #endif /* Pegasus_HTTPConnection_h */
|