1 #include "ace/INet/HTTP_SessionBase.h"
3 #if !defined (__ACE_INLINE__)
4 #include "ace/INet/HTTP_SessionBase.inl"
7 #include "ace/INet/INet_Log.h"
8 #include "ace/INet/HTTP_StreamPolicy.h"
9 #include "ace/INet/String_IOStream.h"
10 #include "ace/INet/IOS_util.h"
11 #include "ace/INet/HTTP_URL.h"
12 #include "ace/INET_Addr.h"
13 #include "ace/String_Base.h"
17 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
23 SessionBase::SessionBase (u_short port
, bool keep_alive
)
28 http_timeout_ (DEFAULT_TIMEOUT
),
29 keep_alive_timeout_ (DEFAULT_KEEP_ALIVE_TIMEOUT
),
30 reconnect_timer_ (DEFAULT_KEEP_ALIVE_TIMEOUT
),
31 reconnect_countdown_ (&reconnect_timer_
),
32 keep_alive_ (keep_alive
),
33 needs_reconnect_ (false),
34 cannot_reconnect_ (false),
35 expects_response_body_ (false)
37 INET_TRACE ("ACE_HTTP_SessionBase - ctor");
40 SessionBase::SessionBase (u_short port
,
41 const ACE_Time_Value
& timeout
,
43 const ACE_Time_Value
* alive_timeout
)
48 http_timeout_ (timeout
),
49 keep_alive_timeout_ (DEFAULT_KEEP_ALIVE_TIMEOUT
),
50 reconnect_timer_ (DEFAULT_KEEP_ALIVE_TIMEOUT
),
51 reconnect_countdown_ (&reconnect_timer_
),
52 keep_alive_ (keep_alive
),
53 needs_reconnect_ (false),
54 cannot_reconnect_ (false),
55 expects_response_body_ (false)
57 INET_TRACE ("ACE_HTTP_SessionBase - ctor");
58 if (keep_alive
&& alive_timeout
)
60 this->keep_alive_timeout_
= *alive_timeout
;
64 SessionBase::~SessionBase ()
66 INET_TRACE ("ACE_HTTP_SessionBase - dtor");
67 this->close_streams ();
70 bool SessionBase::connect (bool use_reactor
)
72 INET_TRACE ("ACE_HTTP_SessionBase::connect");
76 unsigned long f_reactor
= use_reactor
? ACE_Synch_Options::USE_REACTOR
: 0;
77 ACE_Synch_Options
sync_opt (ACE_Synch_Options::USE_TIMEOUT
| f_reactor
,
80 return this->connect_i (sync_opt
);
83 std::ostream
& SessionBase::send_request (Request
& request
)
85 INET_TRACE ("ACE_HTTP_SessionBase::send_request");
89 delete this->in_stream_
;
93 bool keep_alive
= this->keep_alive ();
94 if ((this->is_connected () && !keep_alive
) || this->reconnect_needed ())
97 this->needs_reconnect_
= false;
100 if (this->out_stream_
)
102 delete this->out_stream_
;
103 this->out_stream_
= 0;
106 if (!this->is_connected ())
108 if (this->cannot_reconnect_
|| !this->connect(this->reactive_
))
110 if (!this->cannot_reconnect_
)
111 INET_ERROR (1, (LM_ERROR
, DLINFO
112 ACE_TEXT ("(%d) HTTP_SessionBase::send_request - ")
113 ACE_TEXT ("reconnect failed\n"),
114 ACE_OS::last_error ()));
115 return ACE::IOS::Null::out_stream_
;
119 request
.set_keep_alive (false);
120 if (!request
.has_host ())
122 if (this->port_
== URL::HTTP_PORT
)
123 request
.set_host (this->host_
);
125 request
.set_host (this->host_
, this->port_
);
128 this->expects_response_body_
= request
.get_method() != Request::HTTP_HEAD
;
130 if (request
.has_chunked_transfer_encoding ())
132 request
.write (this->sock_stream ());
133 ChunkedTransferStreamPolicy
* pol
;
135 ChunkedTransferStreamPolicy (),
136 ACE::IOS::Null::out_stream_
);
137 ACE_NEW_RETURN (this->out_stream_
,
138 OStream (this->sock_stream (), pol
),
139 ACE::IOS::Null::out_stream_
);
141 else if (request
.get_content_length () != Header::UNKNOWN_CONTENT_LENGTH
)
143 ACE::IOS::CString_OStream cs
;
145 FixedLengthStreamPolicy
* pol
;
147 FixedLengthStreamPolicy (cs
.str ().length () + request
.get_content_length ()),
148 ACE::IOS::Null::out_stream_
);
149 ACE_NEW_RETURN (this->out_stream_
,
150 OStream (this->sock_stream (), pol
),
151 ACE::IOS::Null::out_stream_
);
152 (*this->out_stream_
) << cs
.str ().c_str ();
154 else if (request
.get_method () != Request::HTTP_PUT
&& request
.get_method() != Request::HTTP_POST
)
156 ACE::IOS::CString_OStream cs
;
158 FixedLengthStreamPolicy
* pol
;
160 FixedLengthStreamPolicy (cs
.str ().length ()),
161 ACE::IOS::Null::out_stream_
);
162 ACE_NEW_RETURN (this->out_stream_
,
163 OStream (this->sock_stream (), pol
),
164 ACE::IOS::Null::out_stream_
);
165 (*this->out_stream_
) << cs
.str ().c_str ();
169 ACE_NEW_RETURN (this->out_stream_
,
170 OStream (this->sock_stream ()),
171 ACE::IOS::Null::out_stream_
);
172 request
.write (*this->out_stream_
);
174 // reset reconnect timer
175 this->reconnect_timer_
= this->keep_alive_timeout_
;
176 this->reconnect_countdown_
.start ();
178 return *this->out_stream_
;
181 std::ostream
& SessionBase::request_stream ()
183 if (this->out_stream_
)
184 return *this->out_stream_
;
186 return ACE::IOS::Null::out_stream_
;
189 std::ostream
& SessionBase::request_stream (
190 ACE::IOS::StreamInterceptor
& interceptor
)
192 if (this->out_stream_
)
194 this->out_stream_
->set_interceptor (interceptor
);
195 return *this->out_stream_
;
198 return ACE::IOS::Null::out_stream_
;
201 std::istream
& SessionBase::receive_response (Response
& response
)
203 INET_TRACE ("ACE_HTTP_SessionBase::receive_response");
205 if (this->in_stream_
)
207 INET_ERROR (1, (LM_ERROR
, DLINFO
208 ACE_TEXT ("HTTP_Session::receive_response - ")
209 ACE_TEXT ("invalid invocation without send_request\n")));
210 // receive_response called second time without
211 // new send_request in between
212 return ACE::IOS::Null::in_stream_
;
215 if (this->out_stream_
)
217 delete this->out_stream_
;
218 this->out_stream_
= 0;
221 this->sock_stream ().flush ();
226 if (!response
.read (this->sock_stream ()))
228 INET_ERROR (1, (LM_ERROR
, DLINFO
229 ACE_TEXT ("(%d) HTTP_Session::receive_response - ")
230 ACE_TEXT ("failed to read response\n"),
231 ACE_OS::last_error ()));
232 return ACE::IOS::Null::in_stream_
;
235 while (response
.get_status ().get_status() == Status::HTTP_CONTINUE
);
237 this->needs_reconnect_
= this->keep_alive () && !response
.has_keep_alive ();
239 if (!this->expects_response_body_
)
241 FixedLengthStreamPolicy
* pol
;
243 FixedLengthStreamPolicy (0),
244 ACE::IOS::Null::in_stream_
);
245 ACE_NEW_RETURN (this->in_stream_
,
246 IStream (this->sock_stream (), pol
),
247 ACE::IOS::Null::in_stream_
);
249 else if (response
.has_chunked_transfer_encoding ())
251 ChunkedTransferStreamPolicy
* pol
;
253 ChunkedTransferStreamPolicy (),
254 ACE::IOS::Null::in_stream_
);
255 ACE_NEW_RETURN (this->in_stream_
,
256 IStream (this->sock_stream (), pol
),
257 ACE::IOS::Null::in_stream_
);
259 else if (response
.get_content_length () != Header::UNKNOWN_CONTENT_LENGTH
)
261 FixedLengthStreamPolicy
* pol
;
263 FixedLengthStreamPolicy (response
.get_content_length ()),
264 ACE::IOS::Null::in_stream_
);
265 ACE_NEW_RETURN (this->in_stream_
,
266 IStream (this->sock_stream (), pol
),
267 ACE::IOS::Null::in_stream_
);
271 ACE_NEW_RETURN (this->in_stream_
,
272 IStream (this->sock_stream ()),
273 ACE::IOS::Null::in_stream_
);
276 return *this->in_stream_
;
279 std::istream
& SessionBase::response_stream ()
281 if (this->in_stream_
)
282 return *this->in_stream_
;
284 return ACE::IOS::Null::in_stream_
;
287 std::istream
& SessionBase::response_stream (
288 ACE::IOS::StreamInterceptor
& interceptor
)
290 if (this->in_stream_
)
292 this->in_stream_
->set_interceptor (interceptor
);
293 return *this->in_stream_
;
296 return ACE::IOS::Null::in_stream_
;
299 void SessionBase::close ()
301 INET_TRACE ("ACE_HTTP_SessionBase::close");
303 this->close_streams ();
311 ACE_END_VERSIONED_NAMESPACE_DECL