1 /* 2 * lftp - file transfer program 3 * 4 * Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net) 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef HTTP_H 21 #define HTTP_H 22 23 #include "NetAccess.h" 24 #include "buffer.h" 25 #include "lftp_ssl.h" 26 #include "HttpHeader.h" 27 #include "HttpAuth.h" 28 29 class Http : public NetAccess 30 { 31 enum state_t 32 { 33 DISCONNECTED, 34 CONNECTING, 35 CONNECTED, 36 RECEIVING_HEADER, 37 RECEIVING_BODY, 38 DONE 39 }; 40 41 enum tunnel_state_t { 42 NO_TUNNEL, 43 TUNNEL_WAITING, 44 TUNNEL_ESTABLISHED 45 }; 46 47 state_t state; 48 tunnel_state_t tunnel_state; 49 50 void Init(); 51 52 void Send(const xstring& str); 53 void Send(const char *format,...) PRINTF_LIKE(2,3); 54 void Send(const HttpHeader *hdr); 55 56 class Connection 57 { 58 xstring_c closure; 59 public: 60 int sock; 61 SMTaskRef<IOBuffer> send_buf; 62 SMTaskRef<IOBuffer> recv_buf; 63 void MakeBuffers(); 64 #if USE_SSL 65 Ref<lftp_ssl> ssl; 66 void MakeSSLBuffers(); 67 #endif 68 SuspendInternal()69 void SuspendInternal() 70 { 71 if(send_buf) send_buf->SuspendSlave(); 72 if(recv_buf) recv_buf->SuspendSlave(); 73 } ResumeInternal()74 void ResumeInternal() 75 { 76 if(send_buf) send_buf->ResumeSlave(); 77 if(recv_buf) recv_buf->ResumeSlave(); 78 } 79 80 Connection(int s,const char *c); 81 ~Connection(); 82 }; 83 84 Ref<Connection> conn; 85 86 static void AppendHostEncoded(xstring&,const char *); 87 void SendMethod(const char *,const char *); 88 const char *last_method; 89 xstring_c last_uri; 90 xstring_c last_url; // for proxy requests 91 92 enum { HTTP_NONE=0, HTTP_POST, HTTP_MOVE, HTTP_COPY, HTTP_PROPFIND } special; 93 xstring special_data; 94 95 void DirFile(xstring& path,const xstring& ecwd,const xstring& efile) const; 96 void SendAuth(); 97 void SendProxyAuth(); 98 void SendCacheControl(); 99 void SendBasicAuth(const char *tag,const char *auth); 100 void SendBasicAuth(const char *tag,const char *u,const char *p); 101 void SendRequest(const char *connection,const char *f); 102 void SendRequest(const char *connection=0) 103 { 104 SendRequest(connection,file); 105 } 106 int SendArrayInfoRequest(); // returns count of sent requests 107 void ProceedArrayInfo(); 108 void SendPropfind(const xstring& efile,int depth); 109 void SendPropfindBody(); 110 static const xstring& FormatLastModified(time_t); 111 void SendProppatch(const xstring& efile); 112 113 int status_code; 114 void HandleHeaderLine(const char *name,const char *value); 115 static const xstring& extract_quoted_header_value(const char *value,const char **end=0); 116 void HandleRedirection(); 117 void GetBetterConnection(int level); 118 void SetCookie(const char *val); 119 void MakeCookie(xstring &cookie,const char *host,const char *path); 120 void CookieMerge(xstring &c,const char *add); 121 bool CookieClosureMatch(const char *closure,const char *host,const char *path); 122 123 void DisconnectLL(); 124 void ResetRequestData(); 125 void MoveConnectionHere(Http *o); IsConnected()126 int IsConnected() const 127 { 128 if(!conn) 129 return 0; 130 if(state==CONNECTING || tunnel_state==TUNNEL_WAITING) 131 return 1; 132 return 2; 133 } 134 void LogErrorText(); 135 136 xstring status; 137 int status_consumed; 138 int proto_version; 139 xstring line; 140 off_t body_size; 141 off_t bytes_received; 142 bool sent_eot; 143 144 bool ModeSupported(); ModeIs(open_mode m)145 bool ModeIs(open_mode m) const { 146 if(m==STORE) 147 return mode==m && !sending_proppatch; 148 return mode==m; 149 } 150 151 int keep_alive_max; 152 bool keep_alive; 153 154 int array_send; 155 156 bool chunked; 157 bool chunked_trailer; 158 long chunk_size; 159 off_t chunk_pos; 160 161 off_t request_pos; 162 163 Ref<DirectedBuffer> inflate; 164 SMTaskRef<IOBuffer> propfind; 165 xstring_c content_encoding; 166 static bool IsCompressed(const char *s); 167 bool CompressedContentEncoding() const; 168 bool CompressedContentType() const; 169 170 bool no_ranges; 171 bool seen_ranges_bytes; 172 bool entity_date_set; 173 bool sending_proppatch; 174 175 bool no_cache; 176 bool no_cache_this; 177 178 // for WWW[0] and PROXY[1] 179 int auth_sent[2]; 180 HttpAuth::scheme_t auth_scheme[2]; 181 void NewAuth(const char *hdr,HttpAuth::target_t target,const char *user,const char *pass); 182 void SendAuth(HttpAuth::target_t target,const char *user,const char *uri); 183 184 xstring_c auth_user; 185 xstring_c auth_pass; 186 187 bool use_propfind_now; 188 xstring allprop; 189 190 long retry_after; 191 192 const char *user_agent; 193 194 int _Read(Buffer *,int); // does not update pos, rate_limit, retries, does not check state. 195 void _Skip(int to_skip); // skip in recv_buf or inflate (unless moved), update real_pos 196 void _UpdatePos(int to_skip); // update real_pos, chunk_pos etc. 197 198 protected: 199 bool hftp; // ftp over http proxy. 200 bool https; // secure http 201 bool use_head; 202 203 public: 204 static void ClassInit(); 205 206 Http(); 207 Http(const Http *); 208 ~Http(); 209 GetProto()210 const char *GetProto() const { return "http"; } 211 Clone()212 FileAccess *Clone() const { return new Http(this); } 213 static FileAccess *New(); 214 FileSet *ParseLongList(const char *buf,int len,int *err=0) const; 215 216 int Do(); 217 int Done(); 218 int Read(Buffer *,int); 219 int Write(const void *,int); 220 int StoreStatus(); 221 int SendEOT(); 222 int Buffered(); 223 224 void ResetLocationData(); 225 226 void Close(); 227 const char *CurrentStatus(); 228 229 void Reconfig(const char *name=0); 230 231 bool SameSiteAs(const FileAccess *fa) const; 232 bool SameLocationAs(const FileAccess *fa) const; 233 234 DirList *MakeDirList(ArgV *a); 235 Glob *MakeGlob(const char *pattern); 236 ListInfo *MakeListInfo(const char *path); 237 UseCache(bool use)238 void UseCache(bool use) { no_cache_this=!use; } 239 NeedSizeDateBeforehand()240 bool NeedSizeDateBeforehand() { return true; } 241 242 void SuspendInternal(); 243 void ResumeInternal(); 244 245 static const time_t ATOTM_ERROR = -1; 246 static time_t atotm (const char *time_string); 247 }; 248 249 class HFtp : public Http 250 { 251 public: 252 HFtp(); 253 HFtp(const HFtp *); 254 ~HFtp(); 255 GetProto()256 const char *GetProto() const { return "hftp"; } 257 Clone()258 FileAccess *Clone() const { return new HFtp(this); } 259 static FileAccess *New(); 260 261 virtual void Login(const char *,const char *); 262 virtual void Reconfig(const char *); 263 }; 264 265 class Https : public Http 266 { 267 public: 268 Https(); 269 Https(const Https *); 270 ~Https(); 271 GetProto()272 const char *GetProto() const { return "https"; } 273 Clone()274 FileAccess *Clone() const { return new Https(this); } 275 static FileAccess *New(); 276 }; 277 278 #endif//HTTP_H 279