inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_web 00005 #define inlib_web 00006 00007 #include "system" 00008 #include "net/ftp" 00009 #include "net/http" 00010 00011 namespace inlib { 00012 namespace web { 00013 00014 inline bool wget_file(std::ostream& a_out,const std::string& a_url,const std::string& a_local,bool a_verbose = false){ 00015 std::string cmd; 00016 if(inlib::getenv("INLIB_WGET",cmd)) { 00017 } else { 00018 #ifdef WIN32 00019 cmd = "C:\\cygwin\\bin\\curl.exe --silent --compressed --output"; 00020 #else 00021 #ifdef __APPLE__ 00022 cmd = "curl --silent --compressed --output"; 00023 #else // Linux 00024 cmd = "wget -O"; 00025 #endif 00026 #endif 00027 } 00028 std::string local; 00029 if(a_local.size()) { 00030 local = a_local; 00031 } else { 00032 local = base_name(a_url); 00033 } 00034 cmd += " "; 00035 cmd += local; 00036 cmd += " "; 00037 cmd += a_url; 00038 00039 ::remove(local.c_str()); 00040 00041 if(a_verbose) { 00042 a_out << "inlib::wget_file :" 00043 << " call ::system(" << sout(cmd) << ") ..." 00044 << std::endl; 00045 } 00046 00047 if(::system(cmd.c_str())==(-1)){ 00048 a_out << "inlib::wget_file :" 00049 << " call to ::system(" << sout(cmd) << ") failed." 00050 << std::endl; 00051 return false; 00052 } 00053 00054 //WARNING : the call to system(cmd) may be ok, but the command 00055 // may have failed ! 00056 00057 if(!inlib::file::exists(local)) { 00058 a_out << "inlib::wget_file :" 00059 << " can't get " << sout(a_url) << "." 00060 << std::endl; 00061 return false; 00062 } 00063 00064 std::vector<std::string> txt; 00065 if(!inlib::file::read_num(local,3,txt)) { 00066 a_out << "inlib::wget_file :" 00067 << " can't read head of " << sout(local) << "." 00068 << std::endl; 00069 ::remove(local.c_str()); 00070 return false; 00071 } 00072 if((txt.size()>=3)&&(txt[2]=="<title>404 Not Found</title>")) { 00073 a_out << "inlib::wget_file :" 00074 << " url " << sout(a_url) << " not found." 00075 << std::endl; 00076 ::remove(local.c_str()); 00077 return false; 00078 } 00079 00080 //::printf("debug : curl_file : \"%s\" end\n",a_url.c_str()); 00081 00082 return true; 00083 } 00084 00085 inline bool ftp_file(std::ostream& a_out,const std::string& a_url,const std::string& a_local,bool a_verbose = false) { 00086 00087 ::remove(a_local.c_str()); 00088 00089 std::string host; 00090 std::string path; 00091 if(!inlib::net::ftp::parse(a_url,host,path)) return false; 00092 00093 if(a_verbose) { 00094 a_out << "inlib::ftp_file :" 00095 << " host " << inlib::sout(host) 00096 << " path " << inlib::sout(path) 00097 << std::endl; 00098 } 00099 00100 inlib::net::ftp ftp(a_out,a_verbose); 00101 if(!ftp.start(host,inlib::net::ftp::s_anonymous(),"")) return false; 00102 if(!ftp.fetch_file(path,a_local)) return false; 00103 00104 if(a_verbose) { 00105 a_out << "inlib::ftp_file :" 00106 << " fetch " << sout(a_url) << " end." 00107 << std::endl; 00108 } 00109 00110 return true; 00111 } 00112 00113 // our own http getter : 00114 inline bool http_file(std::ostream& a_out,const std::string& a_url,const std::string& a_local,bool a_verbose = false) { 00115 00116 ::remove(a_local.c_str()); 00117 00118 std::string host; 00119 std::string path; 00120 if(!inlib::net::http::parse(a_url,host,path)) return false; 00121 00122 if(a_verbose) { 00123 a_out << "inlib::http_file :" 00124 << " host " << inlib::sout(host) 00125 << " path " << inlib::sout(path) 00126 << std::endl; 00127 } 00128 00129 inlib::net::http http(a_out,a_verbose); 00130 if(!http.start(host)) return false; 00131 if(!http.fetch(path,a_local)) return false; 00132 00133 if(a_verbose) { 00134 a_out << "inlib::http_file :" 00135 << " fetch " << sout(a_url) << " end." 00136 << std::endl; 00137 } 00138 00139 return true; 00140 } 00141 00142 }} 00143 00144 #include "fcache" 00145 00146 namespace inlib { 00147 namespace web { 00148 00149 class cache : public file::base_cache { 00150 public: 00151 virtual bool fetch_file(const std::string& a_what,const std::string& a_file){ 00152 if(!m_func) return false; 00153 return m_func(m_out,a_what,a_file,m_verbose); 00154 } 00155 public: 00156 inline cache(std::ostream& a_out,bool a_verbose) 00157 : file::base_cache(a_out,a_verbose) 00158 ,m_func(def_func) 00159 {} 00160 virtual ~cache(){} 00161 private: 00162 inline cache(const cache& a_from) 00163 :file::cache(a_from),file::base_cache(a_from) 00164 ,m_func(a_from.m_func) 00165 {} 00166 inline cache& operator=(const cache&){return *this;} 00167 public: 00168 typedef bool(*get_file_func)(std::ostream&,const std::string&,const std::string&,bool a_verbose); 00169 inline void set_get_file_func(get_file_func a_func) {m_func = a_func;} 00170 inline void set_wget_func() {m_func = wget_file;} 00171 inline void set_ftp_func() {m_func = ftp_file;} 00172 private: 00173 inline static bool def_func(std::ostream& a_out,const std::string& a_url,const std::string& a_local,bool a_verbose){ 00174 bool status = false; 00175 if(a_url.substr(0,4)=="ftp:") { 00176 status = ftp_file(a_out,a_url,a_local,a_verbose); 00177 } 00178 if(!status) { 00179 status = http_file(a_out,a_url,a_local,a_verbose); 00180 } 00181 if(!status) { 00182 status = wget_file(a_out,a_url,a_local,a_verbose); 00183 } 00184 return status; 00185 } 00186 private: 00187 get_file_func m_func; 00188 }; 00189 00190 }} 00191 00192 #endif