// -*- mode: cpp; mode: fold -*- // Description /*{{{*/// $Id: http.h,v 1.12 2002/04/18 05:09:38 jgg Exp $ // $Id: http.h,v 1.12 2002/04/18 05:09:38 jgg Exp $ /* ###################################################################### HTTP Acquire Method - This is the HTTP aquire method for APT. ##################################################################### */ /*}}}*/ #ifndef APT_HTTP_H #define APT_HTTP_H #define MAXLEN 360 #include <iostream> using std::cout; using std::endl; class HttpMethod; class CircleBuf { unsigned char *Buf; unsigned long Size; unsigned long InP; unsigned long OutP; string OutQueue; unsigned long StrPos; unsigned long MaxGet; struct timeval Start; static unsigned long BwReadLimit; static unsigned long BwTickReadData; static struct timeval BwReadTick; static const unsigned int BW_HZ; unsigned long LeftRead() { unsigned long Sz = Size - (InP - OutP); if (Sz > Size - (InP%Size)) Sz = Size - (InP%Size); return Sz; } unsigned long LeftWrite() { unsigned long Sz = InP - OutP; if (InP > MaxGet) Sz = MaxGet - OutP; if (Sz > Size - (OutP%Size)) Sz = Size - (OutP%Size); return Sz; } void FillOut(); public: Hashes *Hash; // Read data in bool Read(int Fd); bool Read(string Data); // Write data out bool Write(int Fd); bool WriteTillEl(string &Data,bool Single = false); // Control the write limit void Limit(long Max) {if (Max == -1) MaxGet = 0-1; else MaxGet = OutP + Max;} bool IsLimit() {return MaxGet == OutP;}; void Print() {cout << MaxGet << ',' << OutP << endl;}; // Test for free space in the buffer bool ReadSpace() {return Size - (InP - OutP) > 0;}; bool WriteSpace() {return InP - OutP > 0;}; // Dump everything void Reset(); void Stats(); CircleBuf(unsigned long Size); ~CircleBuf() {delete [] Buf; delete Hash;}; }; struct ServerState { // This is the last parsed Header Line unsigned int Major; unsigned int Minor; unsigned int Result; char Code[MAXLEN]; // These are some statistics from the last parsed header lines unsigned long Size; signed long StartPos; time_t Date; bool HaveContent; enum {Chunked,Stream,Closes} Encoding; enum {Header, Data} State; bool Persistent; 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(string Line); bool Comp(URI Other) {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; void Reset() {Major = 0; Minor = 0; Result = 0; Size = 0; StartPos = 0; Encoding = Closes; time(&Date); ServerFd = -1; Pipeline = true;}; int RunHeaders(); bool RunData(); bool Open(); bool Close(); ServerState(URI Srv,HttpMethod *Owner); ~ServerState() {Close();}; }; class HttpMethod : public pkgAcqMethod { void SendReq(FetchItem *Itm,CircleBuf &Out); bool Go(bool ToFile,ServerState *Srv); bool Flush(ServerState *Srv); bool ServerDie(ServerState *Srv); int DealWithHeaders(FetchResult &Res,ServerState *Srv); virtual bool Fetch(FetchItem *); virtual bool Configuration(string Message); // In the event of a fatal signal this file will be closed and timestamped. static string FailFile; static int FailFd; static time_t FailTime; static void SigTerm(int); string NextURI; public: friend class ServerState; FileFd *File; ServerState *Server; int Loop(); HttpMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig) { File = 0; Server = 0; }; }; #endif