refactor http client implementation
[ntk/apt.git] / methods / http.h
index 7446119..112ce17 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <string>
 
+#include "server.h"
+
 using std::cout;
 using std::endl;
 
@@ -31,7 +33,7 @@ class CircleBuf
    unsigned long long StrPos;
    unsigned long long MaxGet;
    struct timeval Start;
-   
+
    static unsigned long long BwReadLimit;
    static unsigned long long BwTickReadData;
    static struct timeval BwReadTick;
@@ -54,21 +56,20 @@ class CircleBuf
       return Sz;
    }
    void FillOut();
-   
+
    public:
-   
    Hashes *Hash;
-   
+
    // Read data in
    bool Read(int Fd);
    bool Read(std::string Data);
-   
+
    // Write data out
    bool Write(int Fd);
    bool WriteTillEl(std::string &Data,bool Single = false);
-   
+
    // Control the write limit
-   void Limit(long long Max) {if (Max == -1) MaxGet = 0-1; else MaxGet = OutP + Max;}   
+   void Limit(long long Max) {if (Max == -1) MaxGet = 0-1; else MaxGet = OutP + Max;}
    bool IsLimit() const {return MaxGet == OutP;};
    void Print() const {cout << MaxGet << ',' << OutP << endl;};
 
@@ -84,114 +85,55 @@ class CircleBuf
    ~CircleBuf();
 };
 
-struct ServerState
+struct HttpServerState: public ServerState
 {
-   // This is the last parsed Header Line
-   unsigned int Major;
-   unsigned int Minor;
-   unsigned int Result;
-   char Code[360];
-   
-   // These are some statistics from the last parsed header lines
-   unsigned long long Size;
-   signed long long StartPos;
-   time_t Date;
-   bool HaveContent;
-   enum {Chunked,Stream,Closes} Encoding;
-   enum {Header, Data} State;
-   bool Persistent;
-   std::string Location;
-   
-   // This is a Persistent attribute of the server itself.
-   bool Pipeline;
-   
-   HttpMethod *Owner;
-   
    // This is the connection itself. Output is data FROM the server
    CircleBuf In;
    CircleBuf Out;
    int ServerFd;
-   URI ServerName;
-  
-   bool HeaderLine(std::string Line);
-   bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;};
-   void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0;
-                StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false;
-                State = Header; Persistent = false; ServerFd = -1;
-                Pipeline = true;};
-
-   /** \brief Result of the header acquire */
-   enum RunHeadersResult {
-      /** \brief Header ok */
-      RUN_HEADERS_OK,
-      /** \brief IO error while retrieving */
-      RUN_HEADERS_IO_ERROR,
-      /** \brief Parse error after retrieving */
-      RUN_HEADERS_PARSE_ERROR,
-   };
-   /** \brief Get the headers before the data */
-   RunHeadersResult RunHeaders();
-   /** \brief Transfer the data from the socket */
-   bool RunData();
-   
-   bool Open();
-   bool Close();
-   
-   ServerState(URI Srv,HttpMethod *Owner);
-   ~ServerState() {Close();};
+
+   protected:
+   virtual bool ReadHeaderLines(std::string &Data);
+   virtual bool LoadNextResponse(bool const ToFile, FileFd * const File);
+   virtual bool WriteResponse(std::string const &Data);
+
+   public:
+   virtual void Reset() { ServerState::Reset(); ServerFd = -1; };
+
+   virtual bool RunData(FileFd * const File);
+
+   virtual bool Open();
+   virtual bool IsOpen();
+   virtual bool Close();
+   virtual bool InitHashes(FileFd &File);
+   virtual Hashes * GetHashes();
+   virtual bool Die(FileFd &File);
+   virtual bool Flush(FileFd * const File);
+   virtual bool Go(bool ToFile, FileFd * const File);
+
+   HttpServerState(URI Srv, HttpMethod *Owner);
+   virtual ~HttpServerState() {Close();};
 };
 
-class HttpMethod : public pkgAcqMethod
+class HttpMethod : public ServerMethod
 {
-   void SendReq(FetchItem *Itm,CircleBuf &Out);
-   bool Go(bool ToFile,ServerState *Srv);
-   bool Flush(ServerState *Srv);
-   bool ServerDie(ServerState *Srv);
-
-   /** \brief Result of the header parsing */
-   enum DealWithHeadersResult { 
-      /** \brief The file is open and ready */
-      FILE_IS_OPEN,
-      /** \brief We got a IMS hit, the file has not changed */
-      IMS_HIT,
-      /** \brief The server reported a unrecoverable error */
-      ERROR_UNRECOVERABLE,
-      /** \brief The server reported a error with a error content page */
-      ERROR_WITH_CONTENT_PAGE,
-      /** \brief An error on the client side */
-      ERROR_NOT_FROM_SERVER,
-      /** \brief A redirect or retry request */
-      TRY_AGAIN_OR_REDIRECT 
-   };
-   /** \brief Handle the retrieved header data */
-   DealWithHeadersResult DealWithHeaders(FetchResult &Res,ServerState *Srv);
+   public:
+   virtual void SendReq(FetchItem *Itm);
 
    /** \brief Try to AutoDetect the proxy */
    bool AutoDetectProxy();
 
    virtual bool Configuration(std::string Message);
-   
-   // In the event of a fatal signal this file will be closed and timestamped.
-   static std::string FailFile;
-   static int FailFd;
-   static time_t FailTime;
-   static void SigTerm(int);
+
+   virtual ServerState * CreateServerState(URI uri);
 
    protected:
-   virtual bool Fetch(FetchItem *);
-   
-   std::string NextURI;
    std::string AutoDetectProxyCmd;
 
    public:
-   friend struct ServerState;
-
-   FileFd *File;
-   ServerState *Server;
-   
-   int Loop();
-   
-   HttpMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig) 
+   friend struct HttpServerState;
+
+   HttpMethod() : ServerMethod("1.2",Pipeline | SendConfig)
    {
       File = 0;
       Server = 0;