Use a variable on the stack to not have a temporary in the call
[ACE_TAO.git] / ACE / protocols / ace / INet / URLBase.cpp
blob9f9517ace109ea008b441260dece33c6860bd438
1 #include "ace/INet/URLBase.h"
2 #include "ace/INet/IOS_util.h"
4 #if !defined (__ACE_INLINE__)
5 #include "ace/INet/URLBase.inl"
6 #endif
8 #include "ace/INet/String_IOStream.h"
10 #include "ace/INet/ClientRequestHandler.h"
11 #include <istream>
13 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
15 namespace ACE
17 namespace INet
19 URLStream::URLStream (const URLStream& url_stream)
20 : request_handler_ref_ (url_stream.request_handler_ref_),
21 request_handler_ (url_stream.request_handler_)
25 URLStream::~URLStream ()
29 bool URLStream::operator ! ()
31 return this->request_handler_ == 0 || !this->request_handler_->is_response_ok ();
34 URLStream::operator bool ()
36 return this->request_handler_ != 0 && this->request_handler_->is_response_ok ();
39 std::istream& URLStream::operator * ()
41 return this->request_handler_ ?
42 this->request_handler_->response_stream () :
43 ACE::IOS::Null::in_stream_;
46 std::istream* URLStream::operator -> ()
48 return this->request_handler_ ?
49 &this->request_handler_->response_stream () :
50 &ACE::IOS::Null::in_stream_;
53 URLStream::URLStream (ClientRequestHandler& rh)
54 : request_handler_ (&rh)
58 URLStream::URLStream (ClientRequestHandler* rh)
59 : request_handler_ref_ (rh),
60 request_handler_ (rh)
64 const ACE_CString URL_Base::empty_;
66 URL_Base::URL_Base ()
70 URL_Base::~URL_Base () {}
72 bool URL_Base::parse (const ACE_CString& url_string)
74 static const int eof =
75 std::char_traits<ACE::IOS::CString_OStream::char_type>::eof ();
77 ACE_CString uri = url_string;
78 if (this->strip_scheme (uri))
80 ACE::IOS::CString_OStream sos;
81 ACE::IOS::CString_IStream sis (uri);
83 int ch;
85 // parse authority part (if any)
86 if ((ch = this->parse_authority (sis)) == '/' ||
87 !this->has_authority ()) // relative paths allowed if no authority
89 // parse path part
90 sos.put (ch);
91 for (ch = sis.get (); ch != '?' && ch != '#' && ch != eof ;ch = sis.get ())
92 sos.put (ch);
93 this->set_path (sos.str ());
94 sos.clear ();
96 else
98 // empty path
99 this->set_path (empty_);
102 if (ch == '?')
104 // parse query part
105 for (ch = sis.get (); ch != '#' && ch != eof ;ch = sis.get ())
106 sos.put (ch);
107 this->set_query (sos.str ());
108 sos.clear ();
111 if (ch == '#')
113 // get fragment
114 sos << sis.rdbuf ();
115 this->set_fragment (sos.str ());
117 else if (ch != eof)
119 // should not happen
120 return false;
123 // check for (minimum) correctness
124 return this->validate ();
126 return false;
129 int URL_Base::parse_authority(std::istream& is)
131 return is.get ();
134 bool URL_Base::has_authority ()
136 return false;
139 bool URL_Base::validate ()
141 return true;
144 URLStream URL_Base::open () const
146 ClientRequestHandler* rh = this->create_default_request_handler ();
147 if (rh)
149 rh->handle_open_request (*this);
150 return URLStream (rh);
152 else
153 return URLStream (0);
156 URLStream URL_Base::open (ClientRequestHandler& rh) const
158 rh.handle_open_request (*this);
159 return URLStream (rh);
162 URL_Base* URL_Base::create_from_string (const ACE_CString& url_string)
164 ACE_CString::size_type pos = url_string.find (':');
165 if (pos >0 )
167 Factory* url_factory = 0;
168 if (factories_->find (url_string.substr (0, pos), url_factory) == 0)
170 return url_factory->create_from_string (url_string);
174 return 0;
177 #if defined (ACE_HAS_WCHAR)
178 bool URL_Base::parse (const ACE_WString& url_string)
180 return this->parse (ACE_Wide_To_Ascii (url_string.c_str ()).char_rep ());
183 ACE_WString URL_Base::to_wstring () const
185 ACE_Ascii_To_Wide ws(this->to_string().c_str ());
186 return ws.wchar_rep ();
189 URL_Base* URL_Base::create_from_wstring (const ACE_WString& url_string)
191 return create_from_string (ACE_Wide_To_Ascii (url_string.c_str ()).char_rep ());
193 #endif
195 bool URL_Base::strip_scheme (ACE_CString& url_string)
197 // since this will be called at a point where the
198 // actual URL class is already known (and with that
199 // the protocol prefix) we allow for the fact we
200 // may get a url passed without the actual prefix
202 ACE_CString::size_type pos = url_string.find (':');
203 if (pos > 0 && url_string[pos+1] == '/' && url_string[pos+2] == '/')
205 // in case we find a scheme check for the right protocol
206 if (this->get_protocol () != url_string.substr (0, pos))
208 return false;
210 url_string = url_string.substr (pos+3); // skip '<protocol>://'
212 return true;
215 void URL_Base::register_factory (Factory* url_factory)
217 if (factories_ == 0)
219 factories_ = URL_Base::TURLFactorySingleton::instance ();
221 if (url_factory)
222 factories_->bind (url_factory->protocol (), url_factory);
225 void URL_Base::deregister_factory (Factory* url_factory)
227 if (factories_ && url_factory)
229 factories_->unbind (url_factory->protocol ());
233 URL_Base::TURLFactoryMap* URL_Base::factories_ = 0;
235 URL_Base::Factory::Factory ()
238 URL_Base::Factory::~Factory ()
241 URL_INetBase::URL_INetBase (u_short port)
242 : URL_Base (), port_ (port)
246 URL_INetBase::~URL_INetBase () {}
248 int URL_INetBase::parse_authority (std::istream& is)
250 ACE::IOS::CString_OStream sos;
251 return this->parse_authority_i (is, sos, 0);
254 int URL_INetBase::parse_authority_i (std::istream& is,
255 std::ostream& os,
256 int lastch)
258 static const int eof =
259 std::char_traits<ACE::IOS::CString_OStream::char_type>::eof ();
261 ACE::IOS::CString_OStream& sos =
262 dynamic_cast<ACE::IOS::CString_OStream&> (os);
264 int ch = lastch;
265 if (ch == 0)
267 // parse host part
268 for (ch = is.get ();
269 #if defined (ACE_HAS_IPV6)
270 ch != '[' && ch != '/' && ch != ':' && ch != '@' && ch != '?' && ch != '#' && ch != eof ;
271 #else
272 ch != '/' && ch != ':' && ch != '@' && ch != '?' && ch != '#' && ch != eof ;
273 #endif
274 ch = is.get ())
275 sos.put (ch);
278 #if defined (ACE_HAS_IPV6)
279 if (ch == '[')
281 sos.clear ();
282 for (ch = is.get (); ch != ']' && ch != eof ;ch = is.get ())
283 sos.put (ch);
284 if (ch != eof)
285 ch = is.get (); // skip ']'
286 if (ch != '/' && ch != ':' && ch != '?' && ch != '#' && ch != eof)
288 this->set_host (empty_); // invalid URL, clear host field
289 ch = eof; // stop parsing
291 else
293 this->set_host (sos.str ());
296 else
298 #endif
299 this->set_host (sos.str ());
300 #if defined (ACE_HAS_IPV6)
302 #endif
303 sos.clear ();
305 if (ch == ':')
307 u_short port = 0;
308 is >> port; // should stop at '/' or '?' or '#' or eof
309 ch = is.get ();
310 if (ch == '/' || ch == '?' || ch == '#' || ch == eof)
311 this->set_port (port);
312 else
313 this->set_port (0);
315 else
317 this->set_port (this->default_port ());
320 return ch;
323 bool URL_INetBase::has_authority ()
325 return true;
328 bool URL_INetBase::validate ()
330 return !this->host_.empty () && this->port_>0;
333 ACE_CString URL_INetBase::get_authority () const
335 ACE::IOS::CString_OStream sos;
336 sos << this->get_host().c_str ();
337 if (this->get_port () != this->default_port ())
338 sos << ':' << this->get_port ();
339 return sos.str ();
342 URL_INetAuthBase::authenticator_map URL_INetAuthBase::authenticators_;
344 URL_INetAuthBase::URL_INetAuthBase (u_short port)
345 : URL_INetBase (port)
349 URL_INetAuthBase::~URL_INetAuthBase () {}
351 ACE_CString URL_INetAuthBase::get_authority () const
353 ACE::IOS::CString_OStream sos;
354 if (!this->get_user_info ().empty ())
355 sos << this->get_user_info ().c_str () << "@";
356 sos << this->get_host().c_str ();
357 if (this->get_port () != this->default_port ())
358 sos << ':' << this->get_port ();
359 return sos.str ();
362 int URL_INetAuthBase::parse_authority (std::istream& is)
364 static const int eof =
365 std::char_traits<ACE::IOS::CString_OStream::char_type>::eof ();
367 ACE::IOS::CString_OStream sos;
369 int ch;
370 // parse userinfo (if any)
371 for (ch = is.get ();
372 #if defined (ACE_HAS_IPV6)
373 ch != '[' && ch != '/' && ch != ':' && ch != '@' && ch != '?' && ch != '#' && ch != eof ;
374 #else
375 ch != '/' && ch != ':' && ch != '@' && ch != '?' && ch != '#' && ch != eof ;
376 #endif
377 ch = is.get ())
378 sos.put (ch);
380 if (ch == '@')
382 this->set_user_info (sos.str ());
383 sos.clear ();
384 ch = URL_INetBase::parse_authority_i (is, sos, 0);
386 else
388 ch = URL_INetBase::parse_authority_i (is, sos, ch);
391 return ch;
394 bool URL_INetAuthBase::add_authenticator (const ACE_CString& auth_id,
395 AuthenticatorBase* authenticator)
397 if (URL_INetAuthBase::authenticators_.find (auth_id) == -1)
399 return URL_INetAuthBase::authenticators_.bind (auth_id,
400 authenticator_ptr (authenticator)) == 0;
402 return false;
405 bool URL_INetAuthBase::has_authenticator (const ACE_CString& auth_id)
407 return (URL_INetAuthBase::authenticators_.find (auth_id) == 0);
410 AuthenticatorBase* URL_INetAuthBase::remove_authenticator (const ACE_CString& auth_id)
412 authenticator_ptr auth;
413 if (URL_INetAuthBase::authenticators_.unbind (auth_id, auth) == 0)
415 auth.release ();
417 return 0;
420 bool URL_INetAuthBase::authenticate (AuthenticationBase& authentication)
422 ACE_GUARD_RETURN (ACE_SYNCH::RECURSIVE_MUTEX,
423 _guard,
424 URL_INetAuthBase::authenticators_.mutex (),
425 false);
427 authenticator_map::iterator it = URL_INetAuthBase::authenticators_.begin ();
428 for (; it != URL_INetAuthBase::authenticators_.end ();
429 ++it)
431 authenticator_ptr auth_ptr = (*it).int_id_;
433 // release lock before calling user code
434 if (URL_INetAuthBase::authenticators_.mutex ().release () != 0)
435 return false;
437 if (auth_ptr->authenticate (authentication))
438 return true;
440 // re-acquire lock
441 if (URL_INetAuthBase::authenticators_.mutex ().acquire () != 0)
442 return false;
445 return false;
450 ACE_END_VERSIONED_NAMESPACE_DECL