2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * A fast, easy-to-use, parallelizing, pipelining HTTP/1.1 file retriever.
7 * Just create a WvHttpPool object, add it to your list, and use pool.addurl()
8 * to get a WvStream* that gives you the file you requested.
10 #ifndef __WVHTTPPOOL_H
11 #define __WVHTTPPOOL_H
15 #include "wvistreamlist.h"
16 #include "wvstreamclone.h"
18 #include "wvhashtable.h"
19 #include "wvbufstream.h"
28 static const WvString
DEFAULT_ANON_PW("weasels@");
34 WvHTTPHeader(WvStringParm _name
, WvStringParm _value
)
35 : name(_name
), value(_value
)
40 DeclareWvDict(WvHTTPHeader
, WvString
, name
);
48 WvUrlStream
*instream
;
49 WvBufUrlStream
*outstream
;
58 WvUrlRequest(WvStringParm _url
, WvStringParm _method
, WvStringParm _headers
,
59 WvStream
*content_source
, bool _create_dirs
, bool _pipeline_test
);
65 DeclareWvList(WvUrlRequest
);
73 WvUrlLink(WvStringParm _linkname
, WvStringParm _url
)
74 : linkname(_linkname
), url(_url
)
77 DeclareWvList(WvUrlLink
);
80 class WvBufUrlStream
: public WvBufStream
85 WvUrlLinkList links
; // HTML links or FTP directory listing
90 WvHTTPHeaderDict headers
;
92 WvBufUrlStream() : status(0), headers(10)
94 virtual ~WvBufUrlStream()
98 const char *wstype() const { return "WvBufUrlStream"; }
101 DeclareWvTable(WvIPPortAddr
);
104 class WvUrlStream
: public WvStreamClone
110 WvIPPortAddr remaddr
;
113 Target(const WvIPPortAddr
&_remaddr
, WvStringParm _username
)
114 : remaddr(_remaddr
), username(_username
) {}
118 bool operator== (const Target
&n2
) const
119 { return (username
== n2
.username
&& remaddr
== n2
.remaddr
); }
122 static int max_requests
;
126 WvUrlRequestList urls
, waiting_urls
;
128 WvUrlRequest
*curl
; // current url
129 virtual void doneurl() = 0;
130 virtual void request_next() = 0;
133 WvUrlStream(const WvIPPortAddr
&_remaddr
, WvStringParm _username
,
134 WvStringParm logname
)
135 : WvStreamClone(new WvTCPConn(_remaddr
)), target(_remaddr
, _username
),
136 log(logname
, WvLog::Debug
)
142 virtual ~WvUrlStream() {};
144 virtual void close() = 0;
145 void addurl(WvUrlRequest
*url
);
146 void delurl(WvUrlRequest
*url
);
147 // only implemented in WvHttpStream
148 virtual size_t remaining()
151 virtual void execute() = 0;
154 const char *wstype() const { return "WvUrlStream"; }
157 unsigned WvHash(const WvUrlStream::Target
&n
);
159 DeclareWvDict(WvUrlStream
, WvUrlStream::Target
, target
);
162 class WvHttpStream
: public WvUrlStream
165 static bool global_enable_pipelining
;
166 bool enable_pipelining
;
169 int pipeline_test_count
;
171 bool sent_url_request
; // Have we sent a request to the server yet?
172 WvIPPortAddrTable
&pipeline_incompatible
;
173 WvString http_response
, pipeline_test_response
;
174 WvDynBuf putstream_data
;
176 enum { Unknown
, Chunked
, ContentLength
, Infinity
,
177 PostHeadInfinity
, PostHeadChunked
, PostHeadStream
,
178 ChuckInfinity
, ChuckChunked
, ChuckStream
} encoding
;
179 size_t bytes_remaining
;
180 bool in_chunk_trailer
, last_was_pipeline_test
, in_doneurl
;
182 virtual void doneurl();
183 virtual void request_next();
184 void start_pipeline_test(WvUrl
*url
);
185 WvString
request_str(WvUrlRequest
*url
, bool keep_alive
);
186 void send_request(WvUrlRequest
*url
);
187 void pipelining_is_broken(int why
);
190 WvHttpStream(const WvIPPortAddr
&_remaddr
, WvStringParm _username
,
191 bool ssl
, WvIPPortAddrTable
&_pipeline_incompatible
);
192 virtual ~WvHttpStream();
194 virtual void close();
195 virtual void pre_select(SelectInfo
&si
);
196 virtual bool post_select(SelectInfo
&si
);
197 virtual void execute();
198 virtual size_t remaining()
199 { return bytes_remaining
; }
202 const char *wstype() const { return "WvHttpStream"; }
206 class WvFtpStream
: public WvUrlStream
208 bool logged_in
, pasv_acked
;
211 time_t last_request_time
;
214 virtual void doneurl();
215 virtual void request_next();
217 // Disregard all lines that are of the form "xxx-", meaning that another
218 // line follows. Only the last line is important for us.
219 char *get_important_line();
221 // Parse response to "PASV" command and returns a pointer to the address
222 // of the data port (or NULL if it can't parse the response)..
223 // This mucks about with line.
224 WvIPPortAddr
*parse_pasv_response(char *line
);
226 WvString
parse_for_links(char *line
);
229 void* real_execute(void*);
232 WvFtpStream(const WvIPPortAddr
&_remaddr
, WvStringParm _username
,
233 WvStringParm _password
);
235 virtual void pre_select(SelectInfo
&si
);
236 virtual bool post_select(SelectInfo
&si
);
237 virtual void close();
238 virtual void execute();
241 const char *wstype() const { return "WvFtpStream"; }
245 // FIXME: Rename this to WvUrlPool someday.
246 class WvHttpPool
: public WvIStreamList
250 WvUrlStreamDict conns
;
251 WvUrlRequestList urls
;
252 int num_streams_created
;
255 WvIPPortAddrTable pipeline_incompatible
;
259 virtual ~WvHttpPool();
261 virtual void pre_select(SelectInfo
&si
);
262 virtual bool post_select(SelectInfo
&si
);
263 virtual void execute();
265 WvBufUrlStream
*addurl(WvStringParm _url
, WvStringParm _method
= "GET",
266 WvStringParm _headers
= "",
267 WvStream
*content_source
= NULL
,
268 bool create_dirs
= false);
270 // For URL uploads. create_dirs should be true if you want all
271 // non-existent directories in _url to be created.
272 // WvBufUrlStream *addputurl(WvStringParm _url, WvStringParm _headers,
273 // WvStream *s, bool create_dirs = false);
275 void unconnect(WvUrlStream
*s
);
279 { return !urls
.count(); }
282 const char *wstype() const { return "WvHttpPool"; }
286 #endif // __WVHTTPPOOL_H