Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / protocols / ace / INet / URLBase.cpp
blob8814eb94dadc8cff40f643fa156f85e1899980a7
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 return ACE_Ascii_To_Wide (this->to_string().c_str ()).wchar_rep ();
188 URL_Base* URL_Base::create_from_wstring (const ACE_WString& url_string)
190 return create_from_string (ACE_Wide_To_Ascii (url_string.c_str ()).char_rep ());
192 #endif
194 bool URL_Base::strip_scheme (ACE_CString& url_string)
196 // since this will be called at a point where the
197 // actual URL class is already known (and with that
198 // the protocol prefix) we allow for the fact we
199 // may get a url passed without the actual prefix
201 ACE_CString::size_type pos = url_string.find (':');
202 if (pos > 0 && url_string[pos+1] == '/' && url_string[pos+2] == '/')
204 // in case we find a scheme check for the right protocol
205 if (this->get_protocol () != url_string.substr (0, pos))
207 return false;
209 url_string = url_string.substr (pos+3); // skip '<protocol>://'
211 return true;
214 void URL_Base::register_factory (Factory* url_factory)
216 if (factories_ == 0)
218 factories_ = URL_Base::TURLFactorySingleton::instance ();
220 if (url_factory)
221 factories_->bind (url_factory->protocol (), url_factory);
224 void URL_Base::deregister_factory (Factory* url_factory)
226 if (factories_ && url_factory)
228 factories_->unbind (url_factory->protocol ());
232 URL_Base::TURLFactoryMap* URL_Base::factories_ = 0;
234 URL_Base::Factory::Factory ()
237 URL_Base::Factory::~Factory ()
240 URL_INetBase::URL_INetBase (u_short port)
241 : URL_Base (), port_ (port)
245 URL_INetBase::~URL_INetBase () {}
247 int URL_INetBase::parse_authority (std::istream& is)
249 ACE::IOS::CString_OStream sos;
250 return this->parse_authority_i (is, sos, 0);
253 int URL_INetBase::parse_authority_i (std::istream& is,
254 std::ostream& os,
255 int lastch)
257 static const int eof =
258 std::char_traits<ACE::IOS::CString_OStream::char_type>::eof ();
260 ACE::IOS::CString_OStream& sos =
261 dynamic_cast<ACE::IOS::CString_OStream&> (os);
263 int ch = lastch;
264 if (ch == 0)
266 // parse host part
267 for (ch = is.get ();
268 #if defined (ACE_HAS_IPV6)
269 ch != '[' && ch != '/' && ch != ':' && ch != '@' && ch != '?' && ch != '#' && ch != eof ;
270 #else
271 ch != '/' && ch != ':' && ch != '@' && ch != '?' && ch != '#' && ch != eof ;
272 #endif
273 ch = is.get ())
274 sos.put (ch);
277 #if defined (ACE_HAS_IPV6)
278 if (ch == '[')
280 sos.clear ();
281 for (ch = is.get (); ch != ']' && ch != eof ;ch = is.get ())
282 sos.put (ch);
283 if (ch != eof)
284 ch = is.get (); // skip ']'
285 if (ch != '/' && ch != ':' && ch != '?' && ch != '#' && ch != eof)
287 this->set_host (empty_); // invalid URL, clear host field
288 ch = eof; // stop parsing
290 else
292 this->set_host (sos.str ());
295 else
297 #endif
298 this->set_host (sos.str ());
299 #if defined (ACE_HAS_IPV6)
301 #endif
302 sos.clear ();
304 if (ch == ':')
306 u_short port = 0;
307 is >> port; // should stop at '/' or '?' or '#' or eof
308 ch = is.get ();
309 if (ch == '/' || ch == '?' || ch == '#' || ch == eof)
310 this->set_port (port);
311 else
312 this->set_port (0);
314 else
316 this->set_port (this->default_port ());
319 return ch;
322 bool URL_INetBase::has_authority ()
324 return true;
327 bool URL_INetBase::validate ()
329 return !this->host_.empty () && this->port_>0;
332 ACE_CString URL_INetBase::get_authority () const
334 ACE::IOS::CString_OStream sos;
335 sos << this->get_host().c_str ();
336 if (this->get_port () != this->default_port ())
337 sos << ':' << this->get_port ();
338 return sos.str ();
341 URL_INetAuthBase::authenticator_map URL_INetAuthBase::authenticators_;
343 URL_INetAuthBase::URL_INetAuthBase (u_short port)
344 : URL_INetBase (port)
348 URL_INetAuthBase::~URL_INetAuthBase () {}
350 ACE_CString URL_INetAuthBase::get_authority () const
352 ACE::IOS::CString_OStream sos;
353 if (!this->get_user_info ().empty ())
354 sos << this->get_user_info ().c_str () << "@";
355 sos << this->get_host().c_str ();
356 if (this->get_port () != this->default_port ())
357 sos << ':' << this->get_port ();
358 return sos.str ();
361 int URL_INetAuthBase::parse_authority (std::istream& is)
363 static const int eof =
364 std::char_traits<ACE::IOS::CString_OStream::char_type>::eof ();
366 ACE::IOS::CString_OStream sos;
368 int ch;
369 // parse userinfo (if any)
370 for (ch = is.get ();
371 #if defined (ACE_HAS_IPV6)
372 ch != '[' && ch != '/' && ch != ':' && ch != '@' && ch != '?' && ch != '#' && ch != eof ;
373 #else
374 ch != '/' && ch != ':' && ch != '@' && ch != '?' && ch != '#' && ch != eof ;
375 #endif
376 ch = is.get ())
377 sos.put (ch);
379 if (ch == '@')
381 this->set_user_info (sos.str ());
382 sos.clear ();
383 ch = URL_INetBase::parse_authority_i (is, sos, 0);
385 else
387 ch = URL_INetBase::parse_authority_i (is, sos, ch);
390 return ch;
393 bool URL_INetAuthBase::add_authenticator (const ACE_CString& auth_id,
394 AuthenticatorBase* authenticator)
396 if (URL_INetAuthBase::authenticators_.find (auth_id) == -1)
398 return URL_INetAuthBase::authenticators_.bind (auth_id,
399 authenticator_ptr (authenticator)) == 0;
401 return false;
404 bool URL_INetAuthBase::has_authenticator (const ACE_CString& auth_id)
406 return (URL_INetAuthBase::authenticators_.find (auth_id) == 0);
409 AuthenticatorBase* URL_INetAuthBase::remove_authenticator (const ACE_CString& auth_id)
411 authenticator_ptr auth;
412 if (URL_INetAuthBase::authenticators_.unbind (auth_id, auth) == 0)
414 auth.release ();
416 return 0;
419 bool URL_INetAuthBase::authenticate (AuthenticationBase& authentication)
421 ACE_GUARD_RETURN (ACE_SYNCH::RECURSIVE_MUTEX,
422 _guard,
423 URL_INetAuthBase::authenticators_.mutex (),
424 false);
426 authenticator_map::iterator it = URL_INetAuthBase::authenticators_.begin ();
427 for (; it != URL_INetAuthBase::authenticators_.end ();
428 ++it)
430 authenticator_ptr auth_ptr = (*it).int_id_;
432 // release lock before calling user code
433 if (URL_INetAuthBase::authenticators_.mutex ().release () != 0)
434 return false;
436 if (auth_ptr->authenticate (authentication))
437 return true;
439 // re-acquire lock
440 if (URL_INetAuthBase::authenticators_.mutex ().acquire () != 0)
441 return false;
444 return false;
449 ACE_END_VERSIONED_NAMESPACE_DECL