* apt-pkg/contrib/configuration.cc:
[ntk/apt.git] / methods / http.h
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/// $Id: http.h,v 1.12 2002/04/18 05:09:38 jgg Exp $
3 // $Id: http.h,v 1.12 2002/04/18 05:09:38 jgg Exp $
4 /* ######################################################################
5
6 HTTP Acquire Method - This is the HTTP aquire method for APT.
7
8 ##################################################################### */
9 /*}}}*/
10
11 #ifndef APT_HTTP_H
12 #define APT_HTTP_H
13
14 #define MAXLEN 360
15
16 #include <apt-pkg/hashes.h>
17
18 using std::cout;
19 using std::endl;
20
21 class HttpMethod;
22
23 class CircleBuf
24 {
25 unsigned char *Buf;
26 unsigned long long Size;
27 unsigned long long InP;
28 unsigned long long OutP;
29 string OutQueue;
30 unsigned long long StrPos;
31 unsigned long long MaxGet;
32 struct timeval Start;
33
34 static unsigned long long BwReadLimit;
35 static unsigned long long BwTickReadData;
36 static struct timeval BwReadTick;
37 static const unsigned int BW_HZ;
38
39 unsigned long long LeftRead() const
40 {
41 unsigned long long Sz = Size - (InP - OutP);
42 if (Sz > Size - (InP%Size))
43 Sz = Size - (InP%Size);
44 return Sz;
45 }
46 unsigned long long LeftWrite() const
47 {
48 unsigned long long Sz = InP - OutP;
49 if (InP > MaxGet)
50 Sz = MaxGet - OutP;
51 if (Sz > Size - (OutP%Size))
52 Sz = Size - (OutP%Size);
53 return Sz;
54 }
55 void FillOut();
56
57 public:
58
59 Hashes *Hash;
60
61 // Read data in
62 bool Read(int Fd);
63 bool Read(string Data);
64
65 // Write data out
66 bool Write(int Fd);
67 bool WriteTillEl(string &Data,bool Single = false);
68
69 // Control the write limit
70 void Limit(long long Max) {if (Max == -1) MaxGet = 0-1; else MaxGet = OutP + Max;}
71 bool IsLimit() const {return MaxGet == OutP;};
72 void Print() const {cout << MaxGet << ',' << OutP << endl;};
73
74 // Test for free space in the buffer
75 bool ReadSpace() const {return Size - (InP - OutP) > 0;};
76 bool WriteSpace() const {return InP - OutP > 0;};
77
78 // Dump everything
79 void Reset();
80 void Stats();
81
82 CircleBuf(unsigned long long Size);
83 ~CircleBuf() {delete [] Buf; delete Hash;};
84 };
85
86 struct ServerState
87 {
88 // This is the last parsed Header Line
89 unsigned int Major;
90 unsigned int Minor;
91 unsigned int Result;
92 char Code[MAXLEN];
93
94 // These are some statistics from the last parsed header lines
95 unsigned long long Size;
96 signed long long StartPos;
97 time_t Date;
98 bool HaveContent;
99 enum {Chunked,Stream,Closes} Encoding;
100 enum {Header, Data} State;
101 bool Persistent;
102 string Location;
103
104 // This is a Persistent attribute of the server itself.
105 bool Pipeline;
106
107 HttpMethod *Owner;
108
109 // This is the connection itself. Output is data FROM the server
110 CircleBuf In;
111 CircleBuf Out;
112 int ServerFd;
113 URI ServerName;
114
115 bool HeaderLine(string Line);
116 bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;};
117 void Reset() {Major = 0; Minor = 0; Result = 0; Size = 0; StartPos = 0;
118 Encoding = Closes; time(&Date); ServerFd = -1;
119 Pipeline = true;};
120
121 /** \brief Result of the header acquire */
122 enum RunHeadersResult {
123 /** \brief Header ok */
124 RUN_HEADERS_OK,
125 /** \brief IO error while retrieving */
126 RUN_HEADERS_IO_ERROR,
127 /** \brief Parse error after retrieving */
128 RUN_HEADERS_PARSE_ERROR,
129 };
130 /** \brief Get the headers before the data */
131 RunHeadersResult RunHeaders();
132 /** \brief Transfer the data from the socket */
133 bool RunData();
134
135 bool Open();
136 bool Close();
137
138 ServerState(URI Srv,HttpMethod *Owner);
139 ~ServerState() {Close();};
140 };
141
142 class HttpMethod : public pkgAcqMethod
143 {
144 void SendReq(FetchItem *Itm,CircleBuf &Out);
145 bool Go(bool ToFile,ServerState *Srv);
146 bool Flush(ServerState *Srv);
147 bool ServerDie(ServerState *Srv);
148
149 /** \brief Result of the header parsing */
150 enum DealWithHeadersResult {
151 /** \brief The file is open and ready */
152 FILE_IS_OPEN,
153 /** \brief We got a IMS hit, the file has not changed */
154 IMS_HIT,
155 /** \brief The server reported a unrecoverable error */
156 ERROR_UNRECOVERABLE,
157 /** \brief The server reported a error with a error content page */
158 ERROR_WITH_CONTENT_PAGE,
159 /** \brief A error on the client side */
160 ERROR_NOT_FROM_SERVER,
161 /** \brief A redirect or retry request */
162 TRY_AGAIN_OR_REDIRECT
163 };
164 /** \brief Handle the retrieved header data */
165 DealWithHeadersResult DealWithHeaders(FetchResult &Res,ServerState *Srv);
166
167 /** \brief Try to AutoDetect the proxy */
168 bool AutoDetectProxy();
169
170 virtual bool Configuration(string Message);
171
172 // In the event of a fatal signal this file will be closed and timestamped.
173 static string FailFile;
174 static int FailFd;
175 static time_t FailTime;
176 static void SigTerm(int);
177
178 protected:
179 virtual bool Fetch(FetchItem *);
180
181 string NextURI;
182 string AutoDetectProxyCmd;
183
184 public:
185 friend struct ServerState;
186
187 FileFd *File;
188 ServerState *Server;
189
190 int Loop();
191
192 HttpMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig)
193 {
194 File = 0;
195 Server = 0;
196 };
197 };
198
199 #endif