// $Id: $ #include "Options.h" #include "Command_Processor.h" #include "URL_Visitor.h" URL_Processing_Strategy::URL_Processing_Strategy (URL &url, URL_Iterator &iterator) : url_ (url), iterator_ (iterator) { } int URL_Processing_Strategy::destroy (void) { // Commit suicide. delete this; return 0; } URL_Download_Strategy::URL_Download_Strategy (URL &url, URL_Iterator &iterator) : URL_Processing_Strategy (url, iterator) { } int URL_Download_Strategy::execute (void) { ACE_CString buffer; // Extract all the contents of the Stream and print them to the // file. while (this->iterator_.next (buffer) != 0) ACE_DEBUG ((LM_DEBUG, "%s", buffer.c_str ())); return 0; } HTTP_Header_Processing_Strategy::HTTP_Header_Processing_Strategy (URL &url, URL_Iterator &iterator) : URL_Processing_Strategy (url, iterator) { } int HTTP_Header_Processing_Strategy::execute (void) { ACE_CString line; // Start with the reply status. this->iterator_.next (line); if (OPTIONS::instance ()->debug ()) ACE_DEBUG ((LM_DEBUG, "status = %s\n", line.c_str ())); // Find the beginning of the reply status, which follows the ' ' // character in HTTP protocol version tag. int i = line.find (' '); ACE_ASSERT (i != -1); URL_Status status (URL_Status::STATUS_CODE (ACE_OS::atoi (line.c_str () + i))); this->url_.reply_status (status); ACE_DEBUG ((LM_DEBUG, "status %d for URL %s\n", this->url_.reply_status ().status (), this->url_.url_addr ().addr_to_string (0))); // Extract the rest of the header. while (this->iterator_.next (line) != 0) { // Keep track of the Content-Type if (line.find ("Content-Type:") == 0) this->url_.content_type (line.substring (sizeof ("Content-Type:"))); if (OPTIONS::instance ()->debug ()) ACE_DEBUG ((LM_DEBUG, "header = %s\n", line.c_str ())); } return 0; } HTML_Body_Validation_Strategy::HTML_Body_Validation_Strategy (URL &url, URL_Iterator &iterator, URL_Validation_Visitor &context) : URL_Processing_Strategy (url, iterator), visitor_context_ (context) { } int HTML_Body_Validation_Strategy::execute (void) { // @@ You fill in here. return 0; } URL_Iterator * URL_Validation_Visitation_Strategy_Factory::make_header_iterator (void) { URL_Iterator *i; ACE_NEW_RETURN (i, HTTP_Header_Iterator (*this->url_), 0); return i; } URL_Iterator * URL_Validation_Visitation_Strategy_Factory::make_body_iterator (void) { URL_Iterator *i; ACE_NEW_RETURN (i, HTML_Body_Iterator (*this->url_), 0); return i; } URL_Processing_Strategy * URL_Validation_Visitation_Strategy_Factory::make_header_strategy (URL_Iterator &iterator) { URL_Processing_Strategy *ps; ACE_NEW_RETURN (ps, HTTP_Header_Processing_Strategy (*this->url_, iterator), 0); return ps; } URL_Processing_Strategy * URL_Validation_Visitation_Strategy_Factory::make_body_strategy (URL_Iterator &iterator) { URL_Processing_Strategy *ps; ACE_NEW_RETURN (ps, HTML_Body_Validation_Strategy (*this->url_, iterator, this->visitor_context_), 0); return ps; } int URL_Validation_Visitation_Strategy_Factory::destroy (void) { // Commit suicide. delete this; return 0; } URL_Validation_Visitor::URL_CACHE & URL_Validation_Visitor::url_cache (void) { return this->url_cache_; } int URL_Validation_Visitor::in_cache (const ACE_URL_Addr &url_addr) { URL_Status reply_status (URL_Status::STATUS_CODE (1)); if (this->url_cache_.find (url_addr, reply_status) == 0) { ACE_DEBUG ((LM_DEBUG, "status %d for URL %s (cached)\n", reply_status.status (), url_addr.addr_to_string (0))); return 1; } else return 0; } URL_Visitation_Strategy_Factory * URL_Validation_Visitor::make_visitation_strategy_factory (URL &url) { // See if we can get connected and send the GET request via the // . if (url.send_request () == -1) { ACE_ERROR ((LM_ERROR, "%p\n", "send_request")); if (this->url_cache_.bind (url.url_addr (), URL_Status (URL_Status::STATUS_SERVICE_UNAVAILABLE)) == -1) ACE_ERROR ((LM_ERROR, "%p\n", "bind")); return 0; } // @@ Here's where we could check to see if the was HTTP or // FTP, etc. But for now we'll just assume that everything is an // HTTP URL. else { URL_Visitation_Strategy_Factory *vs; ACE_NEW_RETURN (vs, URL_Validation_Visitation_Strategy_Factory (&url, *this), 0); return vs; } } int URL_Validation_Visitor::destroy (void) { // Commit suicide. delete this; return 0; } int URL_Validation_Visitor::visit (HTTP_URL &http_url) { // Check to see if the status of the is already in // the cache. if (this->in_cache (http_url.url_addr ()) == 0) { // Only apply the full-blown visitation strategy if we don't // find the status in the cache. Auto_Destroyer vs (this->make_visitation_strategy_factory (http_url)); if (*vs == 0) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_visitation_strategy_factory"), -1); Auto_Destroyer is (vs->make_header_iterator ()); if (*is == 0) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_header_iterator"), -1); Auto_Destroyer ps (vs->make_header_strategy (**is)); if (*ps == 0) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_header_strategy"), -1); if (ps->execute () == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "header execute"), -1); is = vs->make_body_iterator (); if (*is == 0) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_body_iterator"), -1); ps = vs->make_body_strategy (**is); if (*ps == 0) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_body_strategy"), -1); if (ps->execute () == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "body execute"), -1); } return 0; } int URL_Download_Visitation_Strategy_Factory::destroy (void) { // Commit suicide. delete this; return 0; } URL_Iterator * URL_Download_Visitation_Strategy_Factory::make_header_iterator (void) { return 0; } URL_Iterator * URL_Download_Visitation_Strategy_Factory::make_body_iterator (void) { URL_Iterator *i; ACE_NEW_RETURN (i, URL_Download_Iterator (*this->url_), 0); return i; } URL_Processing_Strategy * URL_Download_Visitation_Strategy_Factory::make_header_strategy (URL_Iterator &iterator) { // You fill in here. return 0; } URL_Processing_Strategy * URL_Download_Visitation_Strategy_Factory::make_body_strategy (URL_Iterator &iterator) { URL_Processing_Strategy *ps; ACE_NEW_RETURN (ps, URL_Download_Strategy (*this->url_, iterator), 0); return ps; } URL_Visitation_Strategy_Factory::URL_Visitation_Strategy_Factory (URL *url) : url_ (url) { } URL_Download_Visitation_Strategy_Factory::URL_Download_Visitation_Strategy_Factory (URL *url) : URL_Visitation_Strategy_Factory (url) { } URL_Validation_Visitation_Strategy_Factory::URL_Validation_Visitation_Strategy_Factory (URL *url, URL_Validation_Visitor &visitor_context) : URL_Visitation_Strategy_Factory (url), visitor_context_ (visitor_context) { } URL_Visitation_Strategy_Factory * URL_Download_Visitor::make_visitation_strategy_factory (URL &url) { // See if we can get connected and send the GET request via the // . if (url.send_request () == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send_request"), 0); // @@ Here's where we could check to see if the was HTTP or // FTP, etc. But for now we'll just assume that everything is an // HTTP URL. else { URL_Visitation_Strategy_Factory *vs; ACE_NEW_RETURN (vs, URL_Download_Visitation_Strategy_Factory (&url), 0); return vs; } } int URL_Download_Visitor::destroy (void) { // Commit suicide. delete this; return 0; } int URL_Download_Visitor::visit (HTTP_URL &http_url) { Auto_Destroyer vs (this->make_visitation_strategy_factory (http_url)); if (*vs == 0) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_visitation_strategy_factory"), -1); Auto_Destroyer is (vs->make_body_iterator ()); if (*is == 0) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_body_iterator"), -1); Auto_Destroyer ps (vs->make_body_strategy (**is)); if (*ps == 0) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "make_body_strategy"), -1); if (ps->execute () == -1) ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "body execute"), -1); return 0; }