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