160 Commits

Author SHA1 Message Date
Darshit Shah
af702340a1 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	src/http.c
	testenv/Makefile.am
	testenv/Test--https.py
	testenv/Test--spider-r.py
	testenv/Test-Content-disposition-2.py
	testenv/Test-Content-disposition.py
	testenv/Test-Head.py
	testenv/Test-O.py
	testenv/Test-Parallel-Proto.py
	testenv/Test-Post.py
	testenv/Test-Proto.py
	testenv/Test-auth-basic-fail.py
	testenv/Test-auth-basic.py
	testenv/Test-auth-both.py
	testenv/Test-auth-digest.py
	testenv/Test-auth-no-challenge-url.py
	testenv/Test-auth-no-challenge.py
	testenv/Test-auth-retcode.py
	testenv/Test-auth-with-content-disposition.py
	testenv/Test-c-full.py
	testenv/Test-cookie-401.py
	testenv/Test-cookie-domain-mismatch.py
	testenv/Test-cookie-expires.py
	testenv/Test-cookie.py
	testenv/conf/__init__.py
	testenv/conf/authentication.py
	testenv/conf/expect_header.py
	testenv/conf/expected_files.py
	testenv/conf/expected_ret_code.py
	testenv/conf/files_crawled.py
	testenv/conf/hook_sample.py
	testenv/conf/local_files.py
	testenv/conf/reject_header.py
	testenv/conf/response.py
	testenv/conf/send_header.py
	testenv/conf/server_files.py
	testenv/conf/urls.py
	testenv/conf/wget_commands.py
	testenv/misc/colour_terminal.py
	testenv/server/http/http_server.py
	testenv/test/base_test.py
	testenv/test/http_test.py
2014-09-14 16:57:15 +05:30
Darshit Shah
6140b1b6e3 Support running tests through valgrind 2014-07-23 18:42:43 +05:30
Darshit Shah
c22b806ee0 Document SERVER_WAIT 2014-07-22 12:49:46 +05:30
Giuseppe Scrivano
ca69294c8a syntax-check: fix tab-space indentation 2014-07-21 17:15:31 +02:00
Giuseppe Scrivano
87a5922141 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	src/Makefile.am
	src/wget.h
2014-07-17 11:07:35 +02:00
Giuseppe Scrivano
99ccc492f4 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	src/progress.c
	src/retr.c
2014-06-22 20:17:50 +02:00
Darshit Shah
825716399c Fix crash in test suite 2014-06-22 01:06:08 +05:30
Darshit Shah
21908a4b13 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	README.checkout
	configure.ac
	src/build_info.c.in
	src/ftp.c
	src/http.c
	src/main.c
	src/options.h
	src/progress.c
	src/retr.c
	src/retr.h
2014-06-09 00:58:01 +05:30
Zihang Chen
ecd69778bf Refactor mainly the test cases classes
Files that were refactored are WgetTest.py, some conf
scripts and some test case file. The purpose of the
refactoring of the test cases classes is to provide
a better interface for the incoming FTP test
counterpart.
2014-06-07 16:34:39 +02:00
Zihang Chen
d26c8ebb16 Create package test for test case classes
delete mode 100644 testenv/WgetTest.py
 create mode 100644 testenv/test/__init__.py
 create mode 100644 testenv/test/base_test.py
 create mode 100644 testenv/test/http_test.py
2014-06-07 16:34:39 +02:00
Zihang Chen
507383df07 Move server classes to package server.protocol
delete mode 100644 testenv/FTPServer.py
 delete mode 100644 testenv/HTTPServer.py
 create mode 100644 testenv/server/__init__.py
 create mode 100644 testenv/server/ftp/__init__.py
 create mode 100644 testenv/server/ftp/ftp_server.py
 create mode 100644 testenv/server/http/__init__.py
 create mode 100644 testenv/server/http/http_server.py
2014-06-07 16:34:39 +02:00
Zihang Chen
195393bf41 Create package conf where rules and hooks are put
create mode 100644 testenv/conf/__init__.py
 create mode 100644 testenv/conf/authentication.py
 create mode 100644 testenv/conf/expect_header.py
 create mode 100644 testenv/conf/expected_files.py
 create mode 100644 testenv/conf/expected_ret_code.py
 create mode 100644 testenv/conf/files_crawled.py
 create mode 100644 testenv/conf/hook_sample.py
 create mode 100644 testenv/conf/local_files.py
 create mode 100644 testenv/conf/reject_header.py
 create mode 100644 testenv/conf/response.py
 create mode 100644 testenv/conf/rule_sample.py
 create mode 100644 testenv/conf/send_header.py
 create mode 100644 testenv/conf/server_conf.py
 create mode 100644 testenv/conf/server_files.py
 create mode 100644 testenv/conf/urls.py
 create mode 100644 testenv/conf/wget_commands.py
2014-06-07 16:34:39 +02:00
Zihang Chen
42e482ad99 Create package exc and move TestFailed to exc
create mode 100644 testenv/exc/__init__.py
 create mode 100644 testenv/exc/test_failed.py
2014-06-07 16:34:39 +02:00
Zihang Chen
82f44f303a Fix a typo in Test-Proto.py 2014-06-07 16:34:39 +02:00
Zihang Chen
31e5f33b5e From WgetTest.py move WgetFile to misc
create mode 100644 testenv/misc/wget_file.py
2014-06-07 16:34:39 +02:00
Zihang Chen
422171da81 Create package misc, move ColourTerm.py to misc
delete mode 100644 testenv/ColourTerm.py
 create mode 100644 testenv/misc/__init__.py
 create mode 100644 testenv/misc/colour_terminal.py
2014-06-07 16:34:38 +02:00
Giuseppe Scrivano
df96c81cf3 Merge remote-tracking branch 'origin' into parallel-wget 2014-03-31 20:55:31 +02:00
Giuseppe Scrivano
60a95d8393 Merge remote-tracking branch 'origin/master' into parallel-wget
Conflicts:
	src/http.c
	src/main.c
2014-03-21 13:12:57 +01:00
Giuseppe Scrivano
35ab8cdd7a Merge remote-tracking branch 'origin/master' into parallel-wget 2014-03-05 11:22:39 +01:00
Giuseppe Scrivano
9020b71c18 Merge branch 'master' into parallel-wget
Conflicts:
	src/main.c
2014-01-22 22:12:22 +01:00
Darshit Shah
b31e6e4674 Add support for HTTPS Servers 2014-01-03 20:32:06 +01:00
Darshit Shah
b828a6e4a7 Sleep for n seconds before calling Wget Executable
This commit adds support for a new Environment Variable, SERVER_WAIT
which if set will cause the script to sleep for SERVER_WAIT seconds
before calling the wget executable. During this period, the custom
HTTP/HTTPS/FTP servers are all set up and running and can be used
for any other purposes. This feature is often used when a separate
executable must be used for testing apart from the one at src/wget
2014-01-03 20:32:06 +01:00
Darshit Shah
7effa90359 Support programatically setting Handler class variables 2014-01-03 20:32:06 +01:00
Darshit Shah
7e1f4c1abc Correct the call to stop_HTTP_Server 2014-01-03 20:32:06 +01:00
Darshit Shah
f616192dfd Improve error handling when wget executable isn't available 2014-01-03 20:32:06 +01:00
Darshit Shah
31868fed6c Split large function to improve readability and extensibility 2014-01-03 20:32:06 +01:00
Darshit Shah
59a03f15dd Add new configure option, --enable-race-checking
This commit adds a new configure option, --enable-race-checking
which is to be used exclusively for debugging. Also, conditionally
add tests to XFAIL_TESTS when Race Checking is enabled.
2013-12-04 20:45:44 +01:00
Darshit Shah
fa670282ee configure: fix redundant --enable-threads and add metalink info.
Remove redundant --enable-threads option and add Metalink to configure
summary.
2013-12-04 20:22:25 +01:00
Giuseppe Scrivano
0d58672dc6 Always define options.jobs 2013-11-10 14:33:04 +01:00
Giuseppe Scrivano
93597efe7b progress bar: fix a possible segfault 2013-11-10 14:24:17 +01:00
Giuseppe Scrivano
3010d9c281 Merge branch 'origin' into parallel-wget 2013-11-04 11:14:18 +01:00
Giuseppe Scrivano
ebfae2c353 progress: show the URL near the progress bar 2013-11-03 00:32:46 +01:00
Giuseppe Scrivano
15d167e264 progress: progress bar supports threads. 2013-11-03 00:32:32 +01:00
Giuseppe Scrivano
b87cee3763 progress: Split update into update and draw 2013-11-03 00:30:19 +01:00
Giuseppe Scrivano
1a48da4cdc http: don't register multiple times the same fd 2013-11-03 00:29:59 +01:00
Giuseppe Scrivano
349cbd0dd5 threads: correctly initialize number of threads. 2013-10-30 22:30:26 +01:00
Giuseppe Scrivano
d9f1cd05c1 testenv: Remove Test--spider-r.py from XFAIL_TESTS 2013-10-14 00:23:41 +02:00
Giuseppe Scrivano
921a23d60c recur: Refactor to use the same code when threads are disabled. 2013-10-13 23:24:32 +02:00
Giuseppe Scrivano
7d18fd1025 metalink: internationalize some messages to the user. 2013-10-13 18:35:43 +02:00
Giuseppe Scrivano
43ca403306 retr: minor aesthetic changes. 2013-10-13 18:17:17 +02:00
Giuseppe Scrivano
93ad38686a Merge remote-tracking branch 'origin' into parallel-wget 2013-10-13 17:53:35 +02:00
Giuseppe Scrivano
89024dda4f testenv: fix make dist 2013-10-06 19:33:19 +02:00
Giuseppe Scrivano
00c93a0625 Merge remote-tracking branch 'pytests' into parallel-wget 2013-10-06 16:26:49 +02:00
Giuseppe Scrivano
44c821227c Merge remote-tracking branch 'origin' into parallel-wget 2013-10-06 14:58:20 +02:00
Giuseppe Scrivano
cb5c287f02 Unregister a connection while it is used 2013-10-06 14:58:17 +02:00
Darshit Shah
3dfba0bec8 use wgint instead of int 2013-09-18 10:00:03 +02:00
Darshit Shah
fd80f6e878 Change commandline option to --metalink-file 2013-09-18 09:59:07 +02:00
Darshit Shah
db4262d6dd Merge branch 'master' into Working 2013-09-17 03:22:23 +05:30
Darshit Shah
7743384820 Update documentation to reflect changes in code 2013-09-17 03:15:01 +05:30
Darshit Shah
b703633715 Add feature that allows to ensure that Wget correctly crawls the website in recursive mode 2013-09-16 21:06:20 +05:30
Darshit Shah
0758f47954 Add new test for recursive spider mode 2013-09-16 21:06:20 +05:30
Darshit Shah
43bb61b4e3 Smartly guess content type header 2013-09-16 21:06:20 +05:30
Darshit Shah
d4d0e6378c Support substring replace in File Contents too 2013-09-16 21:06:20 +05:30
Darshit Shah
f5785003b1 Compatibility fix with multiple servers
We will not maintian two different interfaces as earlier decided.
Instead, a common, single interface will be maintained. Hence, the tests
must adhere to the same format expected of the Parallel Tests.
2013-09-16 21:06:20 +05:30
Darshit Shah
8b1a9b6de7 Extend Functionality to support spawning multiple servers 2013-09-16 21:06:20 +05:30
Darshit Shah
e84192a8d3 Use the provided calls to shutdown server instead of rewriting it 2013-09-10 12:27:00 +05:30
Darshit Shah
99659f3295 Improve Documentation 2013-09-10 12:26:34 +05:30
Darshit Shah
cb94e52d0f Slight code cleanup. Remove unused code 2013-09-07 17:33:54 +05:30
Darshit Shah
886ac1a89b Shift to new Threading Model from Multiprocessing model
This eliminated the use of Global Variables from the HTTPServer module
and uses the more correct threading.Threads module to spawn a new
server. However, on multi-core systems, the performance may deteriorate
when too many servers are launched due to CPython implementation of GIL.

Many artefacts from the old model still remain, sometimes as commenst,
else as executable code. These will be cleaned up soon
2013-09-07 17:33:54 +05:30
Darshit Shah
e74c2ec25e Add new test for POST Requests 2013-09-07 17:33:54 +05:30
Darshit Shah
48644f174e Print diff when file contents don't match 2013-09-07 17:33:53 +05:30
Darshit Shah
b6f9efe7b5 Add tests for Cookie support 2013-09-07 17:33:53 +05:30
Darshit Shah
4c9e6b4f71 Document pending work 2013-09-07 17:33:53 +05:30
Darshit Shah
e13bc90211 Add new test to ensure Content Disposition and Auth work together 2013-09-07 17:33:53 +05:30
Darshit Shah
60d1f4d1ad Add new Test for Continue command 2013-09-07 17:33:53 +05:30
Darshit Shah
738b299419 Add test, Test-Head 2013-09-07 17:33:53 +05:30
Darshit Shah
9b9d16b2f3 Edit non-unique TEST_NAME variable 2013-09-07 17:33:53 +05:30
Darshit Shah
ae958db622 Minor optimizations to the way Server Rules are executed 2013-09-07 17:33:53 +05:30
Darshit Shah
50b4f0c72b The rules need not be a defaultdict. 2013-09-07 17:33:53 +05:30
Darshit Shah
dccc154a0e Introducing Python based Test Environment 2013-09-07 17:33:53 +05:30
Giuseppe Scrivano
4445d48471 Merge remote-tracking branch 'origin' into parallel-wget 2013-07-30 01:02:28 +02:00
Giuseppe Scrivano
f29fded6f4 Disable timeouts when there are threads 2013-07-12 00:53:27 +02:00
Giuseppe Scrivano
a528894d13 Merge remote-tracking branch 'origin/master' into parallel-wget 2013-07-12 00:16:23 +02:00
Giuseppe Scrivano
7bb672a487 doc: fix error with texinfo 5. 2013-07-04 10:25:23 +02:00
Darshit Shah
747023c476 Mention libmetalink in list of required utilities 2013-07-02 19:33:55 +02:00
Giuseppe Scrivano
29cf6bb9d1 Merge remote-tracking branch 'origin/master' into parallel-wget 2013-07-02 11:14:29 +02:00
Giuseppe Scrivano
3595b9de52 configure: by default disable threads and metalink 2013-06-23 21:53:41 +02:00
Giuseppe Scrivano
2d1196b116 Define PCONN_LOCK when threads are not used. 2013-06-23 21:46:25 +02:00
Giuseppe Scrivano
74d5c8bfb7 Fix possible race condition 2013-06-23 21:16:13 +02:00
Giuseppe Scrivano
fec5bb9e93 Merge remote-tracking branch 'origin/master' into parallel-wget 2013-06-23 18:33:06 +02:00
Jochen Hein
5f48ec1500 Remove double empty space from string. 2013-06-03 21:31:20 +02:00
Bykov Aleksey
8560182d57 Changed fopen mode 2013-05-22 19:20:17 +02:00
Ray Satiro
8e5038747b MinGW compatibility fixes 2013-05-22 00:16:58 +02:00
Giuseppe Scrivano
82126ccb67 dist: add some missing files. 2013-05-19 23:34:38 +02:00
Giuseppe Scrivano
ced4c1de82 Merge remote-tracking branch 'origin/master' into parallel-wget 2013-05-19 16:50:07 +02:00
Giuseppe Scrivano
04fcd759fd Ensure that each thread uses a different socket 2013-04-21 23:12:56 +02:00
Giuseppe Scrivano
e9058befae Merge branch 'master' into parallel-wget
Conflicts:
	src/init.c
	src/main.c
2013-04-21 21:11:53 +02:00
Ilim Ugur
c1a44a16ef Fix bug due to ambiguous variable name. 2013-02-07 22:25:56 +01:00
Giuseppe Scrivano
5a0f05423a Fix a tight-loop when a recursion level is used. 2012-12-09 22:04:58 +01:00
Giuseppe Scrivano
3217905144 Fix a build error with new gnulib versions. 2012-12-09 22:00:37 +01:00
Giuseppe Scrivano
e23e8101db Fix build issue with last gnulib version. 2012-12-04 23:47:20 +01:00
Domenico Chierico
2dd255596a Fix tests build fixes 2012-12-04 23:46:43 +01:00
Giuseppe Scrivano
979a485a9a Fix iri support with threads 2012-12-02 21:55:29 +01:00
Giuseppe Scrivano
617bb37d6e Fix segfault 2012-12-02 00:52:42 +01:00
Giuseppe Scrivano
0717a886c2 Fix a deadlock. 2012-12-01 21:04:20 +01:00
Domenico Chierico
2f2483214c fix build issues 2012-11-30 00:23:58 +01:00
Giuseppe Scrivano
e6d8e165c5 Fix a deadlock 2012-11-29 23:40:33 +01:00
Giuseppe Scrivano
7c8735a6ee Fix thread resources leak. 2012-10-30 22:45:07 +01:00
Ilim Ugur
c24dce1d07 Correct faulty logic in elect_resources and elect_checksums. 2012-09-18 23:39:45 +03:00
Ilim Ugur
e7e869f951 Update ChangeLogs. Add missing prototypes to metalink.c. Remove static variable temp from multi.c.(NOT WORKING) 2012-09-18 01:16:56 +03:00
Ilim Ugur
bfe30ea754 Update ChangeLogs to reflect changes before August 16. 2012-09-14 01:06:40 +03:00
Ilim Ugur
dcc6abee90 Correct allocation size in interoption availability checks for --metalink. 2012-08-22 12:26:07 +03:00
Ilim Ugur
4cd6292b31 Parse metalink info to an internal set of structures. 2012-08-20 16:02:27 +03:00
Ilim Ugur
6b59fab021 Correct shallow copying in ftp.c. Correct malloc statement in retr.c. Support multi-thread FTP downloads. 2012-08-18 15:54:38 +03:00
Ilim Ugur
1d18db4bac Interpret name attribute of file tags in metalink as relative paths. Support -P with metalink downloads. 2012-08-18 02:46:53 +03:00
Ilim Ugur
ed8335aa76 Change --metalink-file to --metalink. Support --quota w/ --metalink. Correct clean_range_res_data(). Add interoption availability checks for --metalink. 2012-08-17 22:53:47 +03:00
Ilim Ugur
87a2b8dcb6 Add header comment to new files. Comment the GSoC code. 2012-08-16 19:14:31 +03:00
Ilim Ugur
a41525e5c2 Transfer handling temp files portion of the code to multi.c. 2012-08-16 16:22:53 +03:00
Ilim Ugur
76790a386a Add a default value for opt.jobs. Remove a (now) redundant variable. 2012-08-16 15:39:24 +03:00
Ilim Ugur
c25d01feb7 Transfer struct range array to multi.c. Delete to redundant variables in retr.c. 2012-08-16 14:22:08 +03:00
Ilim Ugur
f51826d9d8 Correct a source of memory leak when --jobs is not explicitly specified. 2012-08-15 02:24:12 +03:00
Ilim Ugur
721697aef6 Correct segmentation fault when specifying a non-existing metalink file path/URL. 2012-08-15 01:48:48 +03:00
Ilim Ugur
270460da98 Update man page and --help documentation. Update default value for --retries. 2012-08-15 00:43:52 +03:00
Ilim Ugur
fa9aaf2ce6 Correct two merging mistakes in src/convert.h and src/http.c. Replace bootstrap. 2012-08-14 20:24:18 +03:00
Ilim Ugur
eb01e9d442 Resolve conflicts to complete merging with master branch. 2012-08-14 19:47:52 +03:00
Ilim Ugur
2807c5c56d Generate random temp file names. 2012-08-13 01:56:02 +03:00
Ilim Ugur
e37ea16957 Update the logic of delete_temp_files() in multi.c. 2012-08-13 01:11:49 +03:00
Ilim Ugur
5abb1dc188 Update initial URL check and final download printing in main.c. Update the logic of merge_temp_files() in multi.c. 2012-08-12 23:57:59 +03:00
Ilim Ugur
54e5b5d373 Add option --metalink-file. Add a few interoption availability checks for --metalink-file. 2012-08-12 23:21:02 +03:00
Ilim Ugur
768202bf88 Assign values to a few uninitialized variables in retrieve_from_file() 2012-08-12 18:30:03 +03:00
Ilim Ugur
5e2c6fefe4 Delete existing temp_ files before starting to download. Retry on failed download or invalid hash using new option --retries. 2012-08-12 03:20:47 +03:00
Ilim Ugur
0ea58b0c31 Remove option --verify. Compare strongest supported hash type to verify files. 2012-08-11 04:47:31 +03:00
Ilim Ugur
3d19087207 Go back to using <hash_type>_stream functions in gnulib. (Reduces a lot of code) 2012-08-11 02:51:09 +03:00
Ilim Ugur
dc7e47d4d1 Correct faulty lengths in verification and faulty logic in case --verify=all. 2012-08-11 01:45:39 +03:00
Ilim Ugur
b1bc6efc8a Initial working attempt at verifying hashes. 2012-08-10 23:04:58 +03:00
Ilim Ugur
d65343a57b Correct fread error in metalink.c. - Still computes hash wrong. 2012-08-10 20:39:56 +03:00
Ilim Ugur
68dbb9ead7 Add sha256. Rewrite hash verification code. - not working 2012-08-08 14:20:08 +03:00
Ilim Ugur
98db799759 Initial attempt at verifying hashes. - not working 2012-08-03 20:47:31 +03:00
Ilim Ugur
8cfac52713 Remove cat and rm commands. Few corrections with ifdef macros. 2012-08-01 20:35:25 +03:00
Ilim Ugur
11d09dd001 Add FTP support to metalink code. (for single-threaded downloads only) 2012-08-01 00:37:40 +03:00
Ilim Ugur
159c371492 Update fallbacking for metalink: next source goes on from where the previous one failed. 2012-07-31 17:25:21 +03:00
Ilim Ugur
38b1df95f9 Make thread support optional. - No check for semaphore in configure.ac. 2012-07-29 23:43:03 +03:00
Ilim Ugur
f07e0a67b4 Have wget --version list metalink as supported. 2012-07-28 03:15:42 +03:00
Ilim Ugur
47bd180ab0 Transfer struct range to wget.h. Make metalink code optional. 2012-07-27 17:08:26 +03:00
Ilim Ugur
198acf4844 Do not fallback to next resource if there is an IO error. Delete a few redundant variables. 2012-07-26 21:29:48 +03:00
Ilim Ugur
5090e0c433 Set a minimum chunk size. 2012-07-25 17:41:53 +03:00
Ilim Ugur
bb28bda88f Accept metalink files specified as URLs. Better counting of the files downloaded in retrieve_from_file. 2012-07-25 01:05:04 +03:00
Ilim Ugur
9fd1e97e40 Correct minor mistakes in syntax. Prevent a leak in http_loop. 2012-07-24 23:59:47 +03:00
Ilim Ugur
40493a76fe Redesign the code block in retrieve_from_file. 2012-07-24 19:03:51 +03:00
Ilim Ugur
6f102902ad Make metalink check in configure.ac automatic. 2012-07-24 00:52:17 +03:00
Micah Cowan
26ca40970a Use latest bootstrap from gnulib, and fix bootstrap.conf. 2012-07-23 12:55:45 -07:00
Ilim Ugur
2f6ef8922b Use pkg-config of libmetalink in configure.ac 2012-07-22 12:44:33 +03:00
Ilim Ugur
39aaaf57f8 Try using pkg-config of libmetalink in configure.ac - error during make 2012-07-22 00:33:20 +03:00
Ilim Ugur
5f4debb6f8 Update configure.ac and src/Makefile.am 2012-07-21 00:40:23 +03:00
Ilim Ugur
2b8e2f8879 Initial attempt at fallbacking in threaded downloads. 2012-07-15 23:59:54 +03:00
Ilim Ugur
b5a8d663f7 Fix No URLs found in <file> message printed after download. 2012-07-15 23:31:47 +03:00
Ilim Ugur
44f75a1955 Separate segmented download and fallbacking. 2012-07-15 00:48:28 +03:00
Ilim Ugur
f4c42b94d8 Remove obsolete retry tag in retr.c 2012-07-11 01:51:34 +03:00
Ilim Ugur
1e1054db8a Initial attempt at incorporating sems logically. 2012-07-11 01:07:44 +03:00
Ilim Ugur
5c608df4e1 Update if statement involving hs->restval http.c:2859 2012-07-10 21:51:41 +03:00
Ilim Ugur
8bc3dbf2d4 Corrected the dual usage mistake of loop variable in retr.c. 2012-07-10 12:26:57 +03:00
Ilim Ugur
7ccf4210f6 Corrected faulty logic on thread creation. Segments recorded separately then merged. 2012-07-10 11:32:57 +03:00
Ilim Ugur
8c66c94989 Initial attempt at achieving segmented downloading from multiple resources. 2012-07-09 23:46:11 +03:00
Micah Cowan
15bfd733f9 Fix some very broken pconn-freeing logic (suspect more like this...). 2012-07-05 18:22:28 -07:00
Ilim Ugur
f63e2230d7 Implemented resource fallbacking during metalink download. No -c behavior. 2012-07-06 02:53:03 +03:00
Ilim Ugur
693b791082 A rough initial attempt at achieving Goal #2. 2012-07-05 17:36:51 +03:00
Ilim Ugur
02d225b5ca Merge http://addictivecode.org/git/parallel-wget into parallel-wget 2012-07-03 15:59:16 +03:00
Micah Cowan
671d681304 Fix bad persistence check. 2012-07-02 16:06:37 -07:00
Ilim Ugur
6ceea0d064 retrieve_from_file in retr.c now checks for metalink files. 2012-07-03 00:51:53 +03:00
Micah Cowan
fc220632fb Merge Giuseppe's parallel-wget patch. 2012-06-30 16:46:29 -07:00
42 changed files with 3716 additions and 266 deletions

View File

@@ -73,6 +73,20 @@
* gnulib: add git submodule.
2013-10-23 Darshit Shah <darnir@gmail.com>
* configure.ac: Add --race-detection.
* configure.ac: Remove redundant --enable-threads option.
Add Metalink to configure summary
2013-07-02 Darshit Shah <darnir@gmail.com>
* README.checkout: Add dependency on libmetalink.
2013-06-23 Giuseppe Scrivano <gscrivano@gnu.org>
* configure.ac: By default disable threads and metalink support.
2013-09-13 Tim Ruehsen <tim.ruehsen@gmx.de>
* configure.ac: added a summary of build options
@@ -80,6 +94,11 @@
removed the unconditionally adding of libz with --with-ssl
removed -lgcrypt and -lgpg-error for gnutls
2013-08-31 Darshit Shah <darnir@gmail.com>
* configure.ac: Add testenv/Makefile to AC_CONFIG_FILES.
* Makefile.am: Add testenv to SUBDIRS
2013-07-23 Tim Ruehsen <tim.ruehsen@gmx.de>
* configure.ac: Remove AM_CONDITIONAL HAVE_NETTLE.
@@ -110,6 +129,62 @@
* po/POTFILES.in: Add more files.
2012-11-28 Domenico Chierico <spaghetty@gmail.com>
* bootstrap: update from upstream.
* configure.ac: Change tests for iri/threads/metalink detection.
2012-08-03 Ilim Ugur <ilimugur@gmail.com>
* bootstrap.conf : Add crypto/sha256 to the list of Gnulib modules used
by this package.
2012-08-03 Ilim Ugur <ilimugur@gmail.com>
* bootstrap.conf : Add crypto/sha1 to the list of Gnulib modules used
by this package.
2012-07-29 Ilim Ugur <ilimugur@gmail.com>
* configure.ac : Check the availability of pthread library, before
enabling thread support.
2012-07-27 Ilim Ugur <ilimugur@gmail.com>
* configure.ac : Update libmetalink check so that metalink support is
not taken into consideration for compilation, if thread support is not
desired.
2012-07-23 Ilim Ugur <ilimugur@gmail.com>
* configure.ac : Make Metalink check in configure.ac automatic by
assigning auto to ENABLE_METALINK in AC_ARG_ENABLE macro. Update the
libmetalink check accordingly.
2012-07-23 Micah Cowan <micah@cowan.name>
* bootstrap : Replace the bootstrap with the latest bootstrap from
Gnulib.
* bootstrap.conf : Remove the line "$build_aux/missing".
2012-07-22 Ilim Ugur <ilimugur@gmail.com>
* configure.ac : Correct the faulty assignment by assigning to CFLAGS
instead of LIBS. Add AM_CONDITIONAL macro to assign a value to a
variable(i.e. METALINK_IS_ENABLED) to be used in src/Metalink.am.
2012-07-21 Ilim Ugur <ilimugur@gmail.com>
* configure.ac : Update the check for libmetalink. The new version tries
using pkg-config.
2012-07-20 Ilim Ugur <ilimugur@gmail.com>
* configure.ac : Add AC_ARG_ENABLE macros to be able to check for the
essential libraries for multi-threaded and metalink downloading support.
Add checks for libmetalink and make essential additions to LIBS and
CFLAGS if found, as well as prompting messages if it is not found.
2012-07-08 Giuseppe Scrivano <gscrivano@gnu.org>
* bootstrap: Update from gnulib.

View File

@@ -4,8 +4,8 @@ Compiling From Repository Sources
does not contain automatically-generated files, even when these are
normally present in the distribution tarballs. Therefore, to build GNU
Wget from the sources in the repository, you'll need to have one or
more of the following (note that gettext, OpenSSL, libidn, libiconv
and libpsl are not absolutely required):
more of the following (note that gettext, OpenSSL, libidn, libiconv,
libpsl and libmetalink are not absolutely required):
* [20]autoconf (currently, GNU Wget requires version 2.61). This is
needed to generate the configure script from configure.in. This is
@@ -68,6 +68,8 @@ Compiling From Repository Sources
* [34]git is used to fetch gnulib files trough the bootstrap.sh script.
* [45]libmetalink is required for compiling with Metalink support.
* [35]libpsl is required for using a public suffix list to check for valid
cookie domains.
@@ -142,3 +144,4 @@ References
42. http://moinmo.in/GPL
43. http://validator.w3.org/check?uri=referer
44. http://wget.addictivecode.org/WikiLicense
45. https://launchpad.net/libmetalink

View File

@@ -55,6 +55,7 @@ mkstemp
mkostemp
crypto/md5
crypto/sha1
crypto/sha256
pipe
quote
quotearg

View File

@@ -100,6 +100,18 @@ ENABLE_DEBUG=$enableval, ENABLE_DEBUG=yes)
test x"${ENABLE_DEBUG}" = xyes && AC_DEFINE([ENABLE_DEBUG], 1,
[Define if you want the debug output support compiled in.])
AC_ARG_ENABLE(metalink,
[ --disable-metalink disable support for metalink file format],
ENABLE_METALINK=$enableval, ENABLE_METALINK=no)
test x"${ENABLE_METALINK}" = xyes && AC_DEFINE([ENABLE_METALINK], 1,
[Define if you want the metalink file format support compiled in.])
AC_ARG_ENABLE(race-detection,
[ --enable-race-detection enable support for detecting race conditions],
ENABLE_RACES=$enableval, ENABLE_RACES=no)
test x"${ENABLE_RACES}" = xyes && AC_DEFINE([ENABLE_RACES], 1,
[Define if you want runtime Race Detection enabled.])
dnl
dnl Find the compiler
dnl
@@ -365,6 +377,74 @@ else
fi
fi
AS_IF([test x"$ENABLE_THREADS" != xno],[
AC_CHECK_LIB(pthread, pthread_create, [
dnl AC_CHECK_LIB(semaphore, sem_init, [
threads=yes
LIBS="${LIBS} -lpthread"
AC_DEFINE([ENABLE_THREADS], 1,
[Define if you want the thread support compiled in.])
AC_MSG_NOTICE([compiling with support for threads])
dnl ],[
dnl threads=no
dnl if test x"$ENABLE_THREADS" == xyes
dnl then
dnl AC_MSG_ERROR([Could not find the sem_init function in semaphore.])
dnl fi
dnl ])
],[
threads=no
if test x"$ENABLE_THREADS" == xyes
then
AC_MSG_ERROR([Could not find the pthread_create function in pthread.])
fi
])
])
AS_IF([test x"$ENABLE_RACES" != xno],[
CFLAGS="$CFLAGS -fsanitize=thread -fPIE";
LDFLAGS="$LDFLAGS -fsanitize=thread -pie";
])
AS_IF([test x"$ENABLE_METALINK" != xno],[
dnl If metalink support is requested
PKG_CHECK_MODULES(LIBMETALINK, libmetalink, [
dnl If metalink module is found
LIBS="$LIBMETALINK_LIBS $LIBS"
CFLAGS="$LIBMETALINK_CFLAGS $CFLAGS"
AC_DEFINE([ENABLE_METALINK], 1,
[Define if you want the metalink support compiled in.])
AC_CHECK_LIB(metalink, metalink_parse_file, [
if test x"$DISABLE_THREADS" == xyes
then
AC_MSG_ERROR([Metalink support depends on threads, which are requested to be disabled.])
elif test "X$threads" != "Xyes"
then
AC_MSG_ERROR([Metalink support depends on threads, support for which could not be enabled.])
else
metalink=yes
AC_MSG_NOTICE([compiling in support for metalink])
fi
], [
if test x"$ENABLE_METALINK" == xyes
then
AC_MSG_ERROR([Could not find the metalink_parse_file function in libmetalink.])
fi
])
], [
dnl If metalink module is not found
if test x"$ENABLE_METALINK" == xyes
then
AC_MSG_ERROR([libmetalink not found])
fi
])
],[
dnl If metalink support is not requested
metalink=no
AC_MSG_NOTICE([compiling without support for metalink])
])
dnl **********************************************************************
dnl Checks for IPv6
@@ -571,8 +651,10 @@ AC_CHECK_HEADER(pcre.h,
dnl Needed by src/Makefile.am
AM_CONDITIONAL([IRI_IS_ENABLED], [test "X$iri" != "Xno"])
AM_CONDITIONAL([IRI_IS_ENABLED], [test "X$iri" == "Xyes"])
AM_CONDITIONAL([METALINK_IS_ENABLED], [test "X$metalink" == "Xyes"])
AM_CONDITIONAL([THREADS_ARE_ENABLED], [test "X$threads" == "Xyes"])
AM_CONDITIONAL([RACE_CHECKING_IS_ENABLED], [test "X$race-detection" == "Xyes"])
dnl
dnl Create output
@@ -598,5 +680,7 @@ AC_MSG_NOTICE([Summary of build options:
Digest: $ENABLE_DIGEST
NTLM: $ENABLE_NTLM
OPIE: $ENABLE_OPIE
Metalink: $ENABLE_METALINK
Debugging: $ENABLE_DEBUG
Race Detection: $ENABLE_RACES
])

View File

@@ -65,6 +65,11 @@
* wget.texi: Document --regex-type and --preserve-permissions.
2013-07-04 Giuseppe Scrivano <gscrivano@gnu.org>
* wget.texi (Download Options): Use '@item' instead of '@itemx'.
Reported by: Darshit Shah <darnir@gmail.com>.
2013-06-17 Dave Reisner <dreisner@archlinux.org> (tiny change)
* texi2pod.pl: Fix formatting error that causes build to fail with
@@ -112,6 +117,10 @@
* doc/wget.texi: remove -nv from --report-speed
2012-08-14 Ilim Ugur <ilimugur@gmail.com>
* wget.texi: Document --metalink-file and --retries.
2012-08-04 mancha <mancha@mac.hush.com> (tiny change)
* wget.texi: Export ENVIRONMENT to the man page.

View File

@@ -533,6 +533,22 @@ would be resolved to @samp{http://foo/baz/b.html}.
@cindex specify config
@item --config=@var{FILE}
Specify the location of a startup file you wish to use.
@cindex metalink
@item --metalink=@var{FILE}
Read @sc{url}s from a local or external metalink @var{file}. If @samp{-} is
specified as @var{file}, @sc{url}s are read from the standard input.
(Use @samp{./-} to read from a file literally named @samp{-}.)
If this function is used, no @sc{url}s need be present on the command
line.
If the @var{file} is an external one, the document will be automatically
downloaded and will not be kept even after wget terminates.
See option @samp{--jobs} to enable multi-threaded downloads from metalink
files, option @samp{--retries} to set a number of retries for downloading a @var{file}
in case of failure.
@end table
@node Download Options, Directory Options, Logging and Input File Options, Invoking
@@ -558,6 +574,11 @@ infinite retrying. The default is to retry 20 times, with the exception
of fatal errors like ``connection refused'' or ``not found'' (404),
which are not retried.
@item --retries=@var{number}
Set number of retries for a file specified in a metalink file to @var{number}.
Specify 0 or @samp{inf} for no retrying in case of failed attempt. The default
is to retry 1 time.
@item -O @var{file}
@itemx --output-document=@var{file}
The documents will not be written to the appropriate files, but all
@@ -1145,6 +1166,14 @@ command line.
Force Wget to unlink file instead of clobbering existing file. This
option is useful for downloading to the directory with hardlinks.
@cindex jobs
@item --jobs=@var{number}
Specify the @var{number} of threads to use. Unless specified, the number of
threads used is 1.
Currently this option works only for recursive downloading and when specified with
option @samp{--metalink}.
@end table
@node Directory Options, HTTP Options, Download Options, Invoking

View File

@@ -1,3 +1,7 @@
2014-07-21 Giuseppe Scrivano <gscrivan@redhat.com>
* Makefile.am (wget_SOURCES): Remove space-tab indentation.
2014-07-23 Darshit Shah <darnir@gmail.com>
* http.c (gethttp): Fix a memory leak when retrying authorization
@@ -304,15 +308,6 @@
* ftp.c (getftp): Send filename of the local file so that it can be printed
with the progress bar.
2013-11-02 Giuseppe Scrivano <gscrivan@redhat.com>
* progress.c (struct progress_implementation): New method draw.
(bar_update): Split into...
(bar_draw): ...this new function.
(dot_update): Split into...
(dot_draw): New function.
(progress_update): Also invoke draw on `current_impl'.
2014-04-22 Tim Ruehsen <tim.ruehsen@gmx.de>
* http.c (gethttp): Fix 204 response handling
@@ -392,6 +387,80 @@
* gnutls.c (ssl_connect_wget): Fix connect timeout failure
2013-11-10 Giuseppe Scrivano <gscrivan@redhat.com>
* options.h (struct options) [!ENABLE_THREADS]: Define jobs.
* progress.c (progress_create): Do not set `current_progress'.
(progress_finish): Do not reset `current_progress' when the progress bar
to remove is the first one in the list.
2013-11-03 Giuseppe Scrivano <gscrivan@redhat.com>
* retr.h (fd_read_body): Accept an additional argument `url'.
* retr.c (fd_read_body): Likewise.
(fd_read_body): Pass the url to the progress bar.
* ftp.c (getftp): Adjust call to fd_read_body.
* http.c (read_response_body): Likewise.
* progress.h (progress_create): Add new argument `url'.
* progress.c (create_image): Show url near the progress bar.
(process_create): Add new argument `url'.
2013-11-02 Giuseppe Scrivano <gscrivan@redhat.com>
* progress.c (struct progress_header): New struct
(progress_update): Dispatch the draw call to a progress struct.
include <pthread.h>.
(dot_draw): Add argument `force'.
(bar_draw): Likewise.
(dot_draw): Likewise.
* progress.c (struct progress_implementation): New method draw.
(bar_update): Split into...
(bar_draw): ...this new function.
(dot_update): Split into...
(dot_draw): New function.
(progress_update): Also invoke draw on `current_impl'.
* http.c (CLOSE_INVALIDATE): Set socket fd to be invalid.
(register_persistent): Add control and avoid to add the same fd
multiple times.
2013-10-30 Giuseppe Scrivano <gscrivan@redhat.com>
* recur.c (retrieve_tree): Correctly initialize `free_threads' to
N_THREADS.
2013-10-13 Giuseppe Scrivano <gscrivan@redhat.com>
* multi.h (struct s_thread_ctx) [!ENABLE_THREADS]: Define "retr_sem"
* recur.c (THREAD_JOIN): Define.
(retrieve_tree) [!ENABLE_THREADS]: Refactor to use similar code
paths to the threads enabled version.
(SEM_INIT): Likewise.
(SEM_WAIT): Likewise.
* retr.c (retrieve_from_file): Internationalize messages.
* retr.c (retrieve_from_file): Follow GNU Coding style.
2013-10-06 Giuseppe Scrivano <gscrivan@redhat.com>
* http.c (gethttp): Unregister a connection while it is used.
2013-09-07 Darshit Shah <darnir@gmail.com>
* wget.h (option_data[]): Use wgint instead of int.
2013-09-06 Darshit Shah <darnir@gmail.com>
* main.c (option_data[]): Change option to metalink-file in accordance
with the information in the documentation
2013-07-12 Giuseppe Scrivano <gscrivano@gnu.org>
* utils.c (run_with_timeout): abort when there are more threads.
2013-11-02 Giuseppe Scrivano <gscrivan@redhat.com>
* http.c (gethttp): Increase max header value length to 512.
@@ -564,6 +633,37 @@
* html-url.c: Define TAG_TD, TAG_TH, TAG_VIDEO, TAG_AUDIO, TAG_SOURCE.
(tag_url_attributes, known_tags): Likewise.
2013-06-23 Giuseppe Scrivano <gscrivano@gnu.org>
* http.c (PCONN_LOCK) [!ENABLE_THREADS]: Define.
(PCONN_UNLOCK) [!ENABLE_THREADS]: Likewise.
* http.c (gethttp): Lock access to `connect_to_host'.
2013-06-03 Jochen Hein <jochen@jochen.org> (tiny change)
* main.c (main): Remove double empty space from string.
2013-05-22 Bykov Aleksey <gnfalex@rambler.ru>
* multi.c (merge_temp_files): Changed fopen mode from text to binary.
* metalink.c (verify_file_hash): Likewise.
2013-05-21 Ray Satiro <raysatiro@yahoo.com>
* http.c (create_authorization_line): Fix syntax error in calls to NTLM
functions.
* url.c (url_file_name): Use MAX_PATH in Windows.
2013-05-19 Giuseppe Scrivano <gscrivano@gnu.org>
* Makefile.am (EXTRA_DIST): Add iri.c multi.c multi.h metalink.c metalink.h.
2013-04-21 Giuseppe Scrivano <gscrivano@gnu.org>
* http.c (gethttp): Do not register the persistent connection too
early.
2013-06-22 Ángel González <keisial@gmail.com>
* init.c (cmd_string_uppercase): Rewrite function.
@@ -574,10 +674,6 @@
avoid access to uninitialized values by inet_ntop().
* ftp.c (ftp_loop_internal): fix segfault caused by warc_tmp NULL pointer.
2013-05-21 Ray Satiro <raysatiro@yahoo.com>
* url.c (url_file_name): Use MAX_PATH in Windows.
2013-06-13 Darshit Shah <darnir@gmail.com>
* http.c (gethttp): Follow RFC 2616 and httpbis specifications when
@@ -830,6 +926,651 @@
* connect.c (connect_to_ip) [ENABLE_IPV6]: Attempt to use IPv6.
* http.c (gethttp): Likewise.
2013-02-07 Ilim Ugur <ilimugur@gmail.com>
* metalink.c (parse_metalink): Rename `mlink' to 'm_link'.
2012-12-09 Giuseppe Scrivano <gscrivano@gnu.org>
* recur.c (retrieve_tree): Do not attempt to re-download a file if
`next_url' is known.
* test.c: Include "wget.h".
2012-12-04 Giuseppe Scrivano <gscrivano@gnu.org>
* metalink.c: Include "wget.h" as first file.
2012-12-02 Domenico Chierico <spaghetty@gmail.com>
* Makefile.am (LDADD): Remove $(LIBS).
2012-12-02 Giuseppe Scrivano <gscrivano@gnu.org>
* recur.c (retrieve_tree): New variable `next_i'.
* http.c (gethttp): Check for pconn before access it.
2012-12-01 Giuseppe Scrivano <gscrivano@gnu.org>
* convert.c (lock_convert_mutex): New function.
(THREAD_SAFE): Use `lock_convert_mutex'.
(THREAD_SAFE_VOID): Likewise.
2012-11-28 Domenico Chierico <spaghetty@gmail.com>
* Makefile.am (THREAD_LIB): Add -lpthread.
* convert.h (register_download): Add definition.
(convert_all_links): Likewise.
(register_delete_file): Likewise.
(register_redirection): Likewise.
(register_css): Likewise.
(register_html): Likewise.
* convert.c: Remove static from register_download, convert_all_links,
register_delete_file, register_redirection, register_css,
register_html.
* retr.c: Call register_html and register_css properly.
2012-11-29 Giuseppe Scrivano <gscrivano@gnu.org>
* http.c (pconn_lock): New function.
(PCONN_LOCK): Use pconn_lock.
(persistent_available_p): Change signature.
(get_persistent): Change calls to persistent_available_p.
2012-10-07 Giuseppe Scrivano <gscrivano@gnu.org>
* wget.h (enum): Add THREADS_ERR and SEM_ERR.
* recur.c (retrieve_tree): Use `pthread_join' to free a terminated
thread resources.
2012-09-18 Ilim Ugur <ilimugur@gmail.com>
* metalink.c (elect_resources): Rewrite function definition, correcting
faulty logic in branching statements.
* metalink.c (elect_checksums): Rewrite function definition, correcting
faulty logic in branching statements.
* metalink.c (delete_mlink): Rename variables tempfile, tempres,
tempcsum, temphash as file_temp, res_temp, csum_temp and phash_temp.
* retr.c : Take functions elect_resources and elect_checksums out of
comment brackets.
2012-09-17 Ilim Ugur <ilimugur@gmail.com>
* metalink.c : Add comments for functions delete_mlink, elect_checksums,
elect_resources and parse_metalink.
* metalink.h : Add prototypes of elect_resources and elect_checksums.
* multi.c : Remove static variable temp.
* options.h : Remove ifdefs that contain metalink_file member, due to
the opt.metalink_file check made in an if statement in main.c.
* retr.c (retrieve_from_file): Use functions elect_checksums and
elect_resources to filter the parsed information during metalink
downloads.
2012-08-22 Ilim Ugur <ilimugur@gmail.com>
* main.c : Correct malloc size for temp_option.
2012-08-20 Ilim Ugur <ilimugur@gmail.com>
* metalink.c (verify_file_hash): Change type of function parameter
checksums. Add a variable checksum of type mlink_checksum. Use checksum
as the loop variable in for loop instead of i. Replace usage of
checksums[i] with checksum within the scope of the loop.
* metalink.c : Add functions parse_metalink, elect_resources,
elect_checksums and delete_mlink.
* metalink.h : Define new types mlink_piece_hash, mlink_checksum,
mlink_resource, mlink_chunk_checksum, mlink_file and mlink. Add
prototypes of parse_metalink and delete_mlink. Update prototype for
verify_file_hash.
* retr.c : Update metalink downloading portion of the code so that new
data types are used in retr.c instead of types provided by libmetalink.
2012-08-18 Ilim Ugur <ilimugur@gmail.com>
* ftp.c : Correct shallow copying of *local_file to con.target.
* retr.c (retrieve_from_file): Correct malloc size for file_path.
2012-08-17 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file): Treat file attribute of a file in a
metalink file as a relative path, and create any non-existent
directories before attempting to merge temporary files.
2012-08-17 Ilim Ugur <ilimugur@gmail.com>
* main.c : Change the option metalink-file to metalink in option_data.
Extend and make, in terms of readability, more concise the interoption
availability checks.
* multi.c (merge_temp_files): Change type of parameter output from const
char to char.
* multi.c (clean_range_res_data): Use opt.jobs instead of
num_of_resources in the termination condition of the for loop. Remove
parameter num_of_resources.
* multi.h : Update prototypes of functions clean_range_res_data and
merge_temp_files.
* retr.c (retrieve_from file): Update calls to clean_range_res_data and
merge_temp_files.
2012-08-16 Ilim Ugur <ilimugur@gmail.com>
* metalink.c : Add header comment in the existing source files of Wget.
Update comment above function verify_file_hash.
* multi.c (init_ranges): Exit after prompting user with a message when
allocation to ranges fails.
* multi.c (collect_thread): Delete the assignment statement of 0 to
thread_ctx[].terminated.
* multi.c : Add header comment in the existing source files of Wget. Add
comments above functions init_temp_files, name_temp_files,
merge_temp_files, delete_temp_files, clean_temp_files, init_ranges,
fill_ranges_data, clean_range_res_data, clean_ranges, spawn_thread,
collect_thread and segmented_retrieve_url which explain their procedure.
* multi.h : Update header comment in the existing source files of Wget.
* retr.c (retrieve_from_file): Add several comments to the parts of the
code that deals with metalink downloading.
2012-08-16 Ilim Ugur <ilimugur@gmail.com>
* muti.c (init_ranges): Control allocation of space for ranges using an
if statement and prompting user with a message in case of a failure in
allocation.
* muti.c (clean_ranges): Assign NULL to ranges after freeing.
* multi.c (spawn_thread): Assign files[index] to thread_ctx[].file
variable. The statement is moved to here from retr.c after making files
of retr.c a static variable of multi.c.
* multi.c (merge_temp_files): Remove parameter inputs as the mentioned
variable is now a static variable of multi.c.
* multi.c (delete_temp_files): Remove parameter files as the mentioned
variable is now a static variable of multi.c.
* multi.c : Add static variables temp and files (moved from retr.c).
Write functions init_temp_files, name_temp_files and clean_temp_files.
Move definitions of functions merge_temp_files and delete_temp_files.
* multi.h : Add prototypes of the new functions. Update prototypes of
merge_temp_files and delete_temp_files.
* retr.c (retrieve_from_file): Remove variables temp, files and index.
Replace statements using mentioned variables with the new functions in
multi.c. Update calls to merge_temp_files and delete_temp_files.
2012-08-16 Ilim Ugur <ilimugur@gmail.com>
* init.c (defaults): Add an assignment of 1 to opt.jobs within ifdef
brackets.
* multi.c (init_ranges): Remove parameter numthreads from function
definition. Replace numthreads with opt.jobs in the malloc call.
* multi.c (fill_ranges_data): Remove parameter numthreads from function
definition.
* multi.c (collect_thread): Remove parameter numthreads from function
definition. Replace numthreads with opt.jobs in termination condition of
the for loop.
* multi.c (merge_temp_files): Remove parameter numthreads from function
definition. Replace numthreads with opt.jobs in termination condition of
the for loop.
* multi.c (delete_temp_files): Remove parameter numthreads from function
definition. Replace numthreads with opt.jobs in termination condition of
the while loop.
* multi.h : Update prototypes of the functions modified in multi.c;
init_ranges, fill_ranges_data, collect_thread, merge_temp_files and
delete_temp_files.
* retr.c (retrieve_from_file): Update calls to the updated functions in
multi.c appropriately. Replace N_THREADS with opt.jobs throughout the
scope of the N_THREADS definition. Remove variable N_THREADS.
2012-08-16 Ilim Ugur <ilimugur@gmail.com>
* multi.c (spawn_thread): Assign ranges + index to thread_ctx[].range
variable. The statement is moved to here from retr.c after making ranges
of retr.c a static variable of multi.c.
* multi.c : Add new static variable ranges.(moved from retr.c).
Write functions init_ranges, fill_ranges_data, clean_range_res_data and
clean_range to initialize, fill, clean and free the data in ranges.
* multi.h : Add the prototypes of the functions which are added to
multi.c; init_ranges, fill_ranges_data, clean_range_res_data and
clean_range.
* retr.c (retrieve_from_file): Replace statements involving the variable
ranges with the new functions defined in multi.c. Delete two obsolete
variables.
2012-08-14 Ilim Ugur <ilimugur@gmail.com>
* multi.c (spawn_thread): Add new argument, numthreads, to prevent a
potential memory leak.
* multi.h : Update the prototype of collect_thread accordingly.
* retr.c (retrieve_from_file): Update the call made to collect_thread
accordingly.
2012-08-14 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file): Move the statement in which a call to
metalink_context is being made, to prevent a potential segmentation
fault in case a non-existing metalink file location is provided.
2012-08-14 Ilim Ugur <ilimugur@gmail.com>
* init.c (defaults): Update the default value for n_retries to 1.
* main.c (main): Update the output prompted when "wget --help" is used.
2012-08-12 Ilim Ugur <ilimugur@gmail.com>
* multi.c (spawn_thread): Delete an argument, name.
* multi.c (delete_temp_files): Change type of variable, inputs from
const char ** to char **.
* multi.c (merge_temp_files): Change type of variable, files from
const char ** to char **.
* multi.h : Remove obsolete TEMP_PREFIX macro. Update function
prototypes to reflect the changes mentioned above.
* retr.c : Use tmpnam to generate unique temporary file names, making
sure no file with the same name will exist, before the download.
delete_temp_files call before starting to download is, now, not needed.
Update the spawn_thread calls accordingly. Update message printing
statements (i.e. use LOG_NOTQUIET instead of LOG_VERBOSE).
2012-08-12 Ilim Ugur <ilimugur@gmail.com>
* multi.c (delete_temp_files): Instead of passing the name of the final
file, pass the array in which the temporary file names are stored.
Update the execution to quickly traverse the names and unlink them,
deleting an allocation and a now-obsolete loop.
* multi.h : Update the prototype of delete_temp_files.
* retr.c : Update the calls to delete_temp_files.
2012-08-12 Ilim Ugur <ilimugur@gmail.com>
* main.c : Initial URL check is updated so it considers metalink-file
option as well as input-file. The conditional statement for printing the
downloaded sum is updated so it considers metalink-file option as well
as input-file. A conditional statement is added to handle calling
retrieve_from_file when opt.metalink_file is specified.
* multi.c (merge_temp_files): Add a new parameter which will be used
internally to improve the execution of the function.
* multi.h : Update the prototype of merge_temp_files.
* retr.c : Update the call to merge_temp_files, passing the newly
required argument.
2012-08-12 Ilim Ugur <ilimugur@gmail.com>
* init.c : Add metalink-file option to commands.
* main.c : Add metalink-file option to option_data, as well as a few
interoption availability checks of the new option with the existing
options output_document, base_href and force_html, enclosed within an
ifdef directive.
* options.h : Add a new member,metalink_file, to struct options.
* retr.c (retrieve_from_file): Update the Metalink portion of the
function code so that it is activated when a metalink file is specified
using --metalink-file.
2012-08-12 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file): Initialize status_least_severe member of
all the members of ranges array with RETROK.
2012-08-11 Ilim Ugur <ilimugur@gmail.com>
* init.c : Add retries option to commands.
* init.c (defaults): Add an initialization statement for opt.n_retries
within an ifdef directive.
* main.c : Add retries option to option_data.
* metalnk.c (lower_hex_case): Make function static.
* metalnk.c (verify_file_hash): Update the return values in case of an
error.
* metalink.h : Remove the prototype of find_file_hash, which has become
obsolete for some time now.
* options.h : Add a new member,n_retries, to struct options.
* retr.c (verify_file_hash): Call delete_temp_files to delete all the
files that have the same name with one of the temporary files, which can
cause errors.
* retr.c (retrieve_from_file): Update the code so that, in case of a
failed attempt at downloading a file (or corrupt hash after a successful
download), it is retried to be downloaded opt.n_retries times in total.
2012-08-10 Ilim Ugur <ilimugur@gmail.com>
* init.c : Remove verify option from commands.
* main.c : Remove verify option from option_data.
* metalink.c : Readjust the elements in supported_hashes, digest_sizes
and hash_function in descending order of the strength of the encryption.
* metalnk.c (verify_file_hash): Readjust the execution of function so
that instead of comparing an explicitly stated type of hash, which used
to be stored in opt.hashtype, compare the strongest type available in
metalink file and is supported by Wget.
* options.h : Remove hashtype member of struct options.
* retr.c : Modify a message prompting statement to be more concise.
2012-08-10 Ilim Ugur <ilimugur@gmail.com>
* metalink.c : Switch back to using <hash_type>_stream functions,
instead of taking a lower level approach. Remove functions init_ctx,
finish_hash_ctx, process_block, process_bytes and find_file_hash, as
they are no longer needed.
* metalink.c (verify_file_hash): Use <hash_type>_stream instead of
find_file_hash.
2012-08-10 Ilim Ugur <ilimugur@gmail.com>
* metalink.c : Correct the value of MAX_DIGEST_LENGTH macro.
* metalink.c (verify_file_hash): Correct the size of two-dimensional
array hashes. Correct format error in conversion from byte-form to
hex-form of hash. Update the value of the argument fed to lower_hex_case
calls, due to the change in value of MAX_DIGEST_LENGTH.
2012-08-10 Ilim Ugur <ilimugur@gmail.com>
* metalink.c (find_file_hash): Convert byte-form hash to hex-form.
* metalink.c : Add a function lower_hex_case to lower the characters
A-E in the hash given in the metalink file.
* retr.c : Add message prompting statements to be printed to inform
users of the result of the verification.
2012-08-10 Ilim Ugur <ilimugur@gmail.com>
* metalink.c (find_file_hash): Update function calls made in this scope.
Move a buffer allocation statement.
* metalink.c (verify_file_hash): Correct the type of multi-dimensional
array, hashes.
* metalink.c : Rename init_ctx and finish_ctx to be init_hash_ctx,
finish_hash_ctx. Correct passed arguments while making calls to
functions *_init_ctx, *_finish_ctx, *_process_blocks, *_process_bytes.
2012-08-08 Ilim Ugur <ilimugur@gmail.com>
* metalink.c : Hash verification code is totally rewritten, using a
lower level (i.e. in terms of abstraction) approach. Functions named
init_ctx, finish_ctx, process_blocks and process_bytes are introduced,
to handle the operation which was conducted by functions md5_stream,
sha1_steam and sha256_stream. Add function find_file_hash to find the
hash of a file. verify_hash is renamed as verify_file_hash. Add error
message printing statements to inform user of the progress.
* metalink.h : Update the prototype of verify_hash and add the prototype
of find_file_hash.
* retr.c: Update call to verify_hash.
2012-08-03 Ilim Ugur <ilimugur@gmail.com>
* init.c : Correct a faulty ifdef directive and add new verify option
to commands array to correspond to the new command-line option.
* main.c : Add a command-line option verify to indicate the hash type
to be compared.
* metalink.c : Include essential modules, md5.h and sha1.h. Define
HASH_TYPES and MAX_DIGEST_VALUE macros. Define arrays supported_hashes,
digest_values and function pointer hash_function. Write function
verify_hash that verifies hash for a given file and its checksums
specified in the relevant metalink file.
* metalink.h : Add the prototype of verify_hash.
* multi.h : Add new member hashtype to struct options.
* retr.c : Call verify_hash after successful downloading of a file
specified in metalink file, and act according to its return value.
2012-08-01 Ilim Ugur <ilimugur@gmail.com>
* http.c (create_authorization_line): Replace an incorrect ifdef
directive with an if defined directive.
* http.c : Move the inclusion of multi.h within the scope of an ifdef
directive.
* http.h : Include wget.h instead of multi.h, as that is where the
definition of the struct range currently is in.
* multi.c : Correct where wget.h is included. Include unistd.h. Two
functions named merge_temp_files and delete_temp_files are written to
deal with merging and deletion of temporary files, by using fread/fwrite
and unlink, respectively.
* multi.c (spawn_thread): Correct the type of a variable, thread. Delete
a now obsolete portion of code, which used to check if a file name of
which is same with a temporary file's name exists. If such a file was
found, it used to be deleted.
* multi.h : Add the prototypes of merge_temp_files and delete_temp_files
and remove the macro FILENAME_SIZE, which is not needed.
* recur.c : Move the inclusion of multi.h within the scope of an ifdef
directive.
* retr.c : Enclose the inclusion of thread and metalink related header
files within the scope of an ifdef directive. Remove a variable,
command. Use new functions merge_temp_files and delete_temp_files,
instead of calling system function and execute commands cat and rm.
* retr.h : Remove the inclusion of multi.h, as the definition of struct
range is no longer in multi.h and wget.h is known to be included aboe
retr.h.
2012-07-31 Ilim Ugur <ilimugur@gmail.com>
* ftp.c (ftp_loop_internal): Add a struct range parameter to function
signature. Assign first_byte and last_byte members of the new struct
range parameter to relevant variables, restval and len, respectively.
Assign the size of the data read, qtyread, to range->bytes_covered.
Update an if statament which checks the availability of local_file
before assigning a value to it.
* ftp.c (ftp_loop): Add a struct range parameter to function signature.
Pass struct range parameter to ftp_loop_internal.
* ftp.c : Update all ftp_loop_internal calls but the one in ftp_loop so
that NULL is passed as the value for the expected struct range argument.
* ftp.h : Update the prototype of ftp_loop to include its new struct
range parameter. Include wget.h, as it is where the definition of struct
range is.
* http.c : Use an if statement instead of an ifdef directive, which was,
in this case, a bad way of trying to simulate conditional execution of a
statement.
* retr.c (retrieve_url): Update ftp_loop_internal call and pass
segment_range as the value of the expected struct range argument.
2012-07-31 Ilim Ugur <ilimugur@gmail.com>
* http.c (http_loop): Assign range->bytes_covered the size of retrieved
data, hstat.len.
* retr.c : Update initialization statements of struct range instances to
consider new struct range member, bytes_covered and not is_covered.
Update the first_byte member of a struct range instance in case of
partially retrieved segments, using new member variable, bytes_covered.
* wget.h : Replace the variable is_covered in the definition of struct
range with another variable, bytes_covered.
2012-07-29 Ilim Ugur <ilimugur@gmail.com>
* Makefile.am : Add a conditional statement for adding metalink.c to
wget_SOURCES.
* build_info.c.in : Add a line to indicate thread support.
* connect.h : Enclose portions of code written either by Giuseppe
Scrivano in his patch for multiple threaded recursive downloads or as a
part of Google Summer of Code project for adding Metalink support to GNU
Wget in ifdef and ifndef directives, based on the availability of thread
and/or metalink support.
* convert.c : Likewise.
* http.c : Likewise.
* init.c : Likewise.
* main.c : Likewise.
* multi.c : Likewise.
* options.h : Likewise.
* recur.c : Likewise.
* retr.c : Likewise.
2012-07-27 Ilim Ugur <ilimugur@gmail.com>
* http.c : Take assertion of local_file having a NULL value and
assignment of value to local_file within scope of an ifndef directive.
* multi.c : Delete a part of a comment, which became redundant.
* multi.h : Correct where wget.h is included. Also, delete the
definition of struct range, which is moved to wget.h.
* retr.c : Take the inclusion of libmetalink header files and metalink.h
within scope of an ifdef directive, to include them only if Metalink
support is compiled.
* retr.c (retrieve_from_file): Take the Metalink downloading portions of
the code within ifdef directives, so that they are compiled only if
Metalink support is compiled.
* wget.h : Definition of struct range is moved to here.
*build_info.c.in : Add a line to indicate Metalink support.
2012-07-26 Ilim Ugur <ilimugur@gmail.com>
* multi.h : Delete variable resources_tried, which is obsolete, from
the definition of struct range.
* retr.c (retrieve_from_file): Delete redundant variable k. Add variable
file_name to be used in merging and deleting temporary files. Replace
strcat calls in merging and deleting temporary files with sprintf calls,
which are tidier than the sprintf calls used before (i.e. does not make
illegal writes, as Valgrind used to claim). Also, an else if branch is
added to the error checking after collecting a thread, to disable
fallbacking in case of an IOERROR.
2012-07-25 Ilim Ugur <ilimugur@gmail.com>
* multi.h : Define a macro, MIN_CHUNK_SIZE to stand for the minimum size
for a segment that can be downloaded by a thread.
* retr.c (retrieve_from_file): Check the size of the segments for the
specified number of threads. If it is smaller than MIN_CHUNK_SIZE,
assign MIN_CHUNK_SIZE to chunk_size and use
(file->size / chunk_size) + 1 threads, instead of opt.jobs. In addition,
replace sprintf calls with strcpy and strcat in merging-temporary-files
and deleting-temporary-files portions of the code.
2012-07-24 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file): Move the code block which deals with
Metalink downloads out of the else if scope it used to be, deleting the
relevant else if branch. Instead, the code is inserted after the if
statement of which it was previously a part(i.e. the if statement which
deals with downloading the input file if its URL was given instead of
its physical location).
2012-07-24 Ilim Ugur <ilimugur@gmail.com>
* http.c (http_loop): Add a missing check to
* multi.c : Correct where wget.h is included.
* retr.c (retrieve_from_file): Correct the variable being incorrectly
used as index variable in a loop for an array. Add the forgotten
pre-incrementation statement of the loop variable of file-traversing
loop to the end of the loop scope of the code.
2012-07-24 Ilim Ugur <ilimugur@gmail.com>
* Makefile.am : Add multi.c and multi.h to wget_SOURCES.
* multi.c : Add functions spawn_thread, segmented_retrieve_url and
collect_thread to handle thread creation and collection in function
retrieve_from_file of retr.c.
* multi.h : Add the prototypes of the functions that are added to
multi.c. Add a member resources to struct range to point to a bool array
that shows which resources are exhausted. Moved the definition of macros
which are relevant to multi-thread downloading, FILENAME_SIZE and
TEMP_PREFIX, to here.
* retr.c (retrieve_from_file): Rewrite the multi-thread downloading.
Instead of adapting the code written by Giuseppe Scrivano for recursive
downloading, use an algorithm that separates thread creation from
collection. Move some of the assignments to newly written thread
spawning and collecting functions in multi.c.
2012-07-23 Ilim Ugur <ilimugur@gmail.com>
* retr.c : Define a TEMP_PREFIX macro to use instead of "temp_" within
retrieve_from_file.
* retr.c (retrieve_from_file): Replace "temp_" with TEMP_PREFIX. Move
the sem_destroy call.
2012-07-22 Ilim Ugur <ilimugur@gmail.com>
* Makefile.am : Add a conditional statement for adding metalink.c to
wget_SOURCES.
* retr.c : Include metalink/metalink_types.h, which is a part of
libmetalink.
2012-07-21 Ilim Ugur <ilimugur@gmail.com>
* Makefile.am : Add metalink.c to EXTRA_wget_SOURCES.
2012-07-20 Ilim Ugur <ilimugur@gmail.com>
* Makefile.am : Delete metalink.c from wget_SOURCES.
2012-07-15 Ilim Ugur <ilimugur@gmail.com>
* multi.h : Add 4 new variables to the definition of struct range.
* retr.c (retrieve_from_file) : Update the multi-thread downloading code
so that it does fallbacking(i.e. uses another one of the resources till
all the resources are exhausted) if a thread is unable to download a
segment from a resource successfully.
2012-07-15 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file) : Add an assignment statement to *count, to
correct the "No URLs found in <file>" message that is printed even after
a successful download.
2012-07-14 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file) : Totally separate fallbacking and multiple
threaded downloading portions of the code based on the value of
N_THREADS.
2012-07-10 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file) : Remove obsolete retry tag.
2012-07-10 Ilim Ugur <ilimugur@gmail.com>
* http.c (gethttp) : A case in an if statement is removed to prevent the
error it causes for multiple thread downloads.
* retr.c (retrieve_from_file) : Initializations of variables that are
used in multi-thread downloading are taken into an if(1) block for
clarification. Encapsulate the thread collecting code within a branching
statement that checks if the file range is covered and if there are any
free threads. Update the loop in which sem_wait is called so that
N_THREADS and free_threads are used in termination condition. Update the
allocation statement for the command, and move the merging-deletion code
into the outer loop(i.e. the one that traverses files).
2012-07-10 Ilim Ugur <ilimugur@gmail.com>
* http.c (gethttp) : An if statement is updated so that a risky case is
considered only for the downloads that are not multi-threaded. Update
the assignments to hstat.restval and hstat.restval_last.
* retr.c (retrieve_from_file) : Move the memory allocation for temp_name
inside the inner loop(i.e. the one that traverses resources).
2012-07-10 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file) : Add a variable file_extension to be able
to label the temporary files by numbers. The variable is used in naming
the files as well and corrects the mistake of threads writing to the
same file. Also, usage of the variable j by two loops that are nested is
corrected by using another variable, k, for the inner loop.
2012-07-10 Ilim Ugur <ilimugur@gmail.com>
* http.c (gethttp) : Correct faulty branching block while calling
request_set_header for Range header.
* retr.c (retrieve_from_file) : Add a variable temp_name for generating
to use while name generation for temporary files. Ensure the continuity
of the inner loop even if number of resources is smaller than opt.jobs.
Further separation of fallbacking and segmented download blocks. Add a
block of code for merging temporary files to the resulting file and
deleting the temporary files after the merging. Add freeing statements
for struct range instances and temporary file names allocated.
2012-07-09 Ilim Ugur <ilimugur@gmail.com>
* http.c : Add wgint restval_last to struct http_stat, to contain the
value for the end of the range. Include multi.h.
* http.c (gethttp) : Take into account the restval_last while calling
request_set_header for Range header.
* http.c (http_loop) : Update the assignments to hstat.restval and
hstat.restval_last. Add a struct range argument to function signature.
* http.h : Update the prototype for http_loop so that it has the latest
argument added, a struct range.
* main.c (main) : While calling retrieve_url, add the value for its new
argument, a struct range.
* multi.h : Add the definition of the struct range. Add the definition
of struct s_thread_ctx, which was previously in recur.c.
* recur.c () : Remove the definition of the struct s_thread_ctx from here.
* recur.c (start_retrieve_url) : While calling retrieve_url, add the
value for its new argument, a struct range.
* recur.c (retrieve_tree) : Initialize thread_ctx[].range values to NULL.
* res.c (res_retrieve_file) : While calling retrieve_url, add the value
for its new argument, a struct range.
* retr.c (retrieve_url) : Add a struct range parameter to function
signature. While calling http_loop, add the value for its new argument,
a struct range.
* retr.c : Include semaphore.h and pthread.h. Add a function called
segmented_retrieve_url for pthread_create to call.
* retr.c (retrieve_from_file) : While calling retrieve_url, add the value
for its new argument, a struct range. Temporarily disable fallbacking
using a branchin statement if(1)-else and adapt multi-threaded download
code, written by Giuseppe Scrivano, into the branch that shall be
executed.
* retr.h : Update the prototype for retrieve_url so that it has the
latest argument added, a struct range.
2012-07-03 Steven Schubiger <stsc@member.fsf.org>
* init.c: Include warc.h for warc_close in cleanup function.
@@ -850,6 +1591,43 @@
* main.c (main): Likewise.
Reported by: Petr Pisar <petr.pisar@atlas.cz>
2012-07-05 Micah Cowan <micah@cowan.name>
* http.c (invalidate_persistent): Use xfree instead of xzero for pconn
freeing.
* http.c (register_persistent): Use xfree instead of xzero for pconn
freeing. Also, free after using the soon-to-be freed value, not before.
2012-07-05 Ilim Ugur <ilimugur@gmail.com>
* http.c (http_loop): Do not assert that no value for *local_file is
passed. If a value is passed, assign that to hstat.local_file.
* retr.c (retrieve_from_file): Do not use opt.output_document to pass
the name of the file to be downloaded. Instead, pass it to retrieve_url
through its 3rd argument (i.e. file parameter).
* retr.c (retrieve_url): Do not assign NULL value to *file if file is
not NULL. Do not assign NULL value to local_file. Instead assign *file.
2012-07-05 Ilim Ugur <ilimugur@gmail.com>
* retr.c (retrieve_from_file): Add nested loop structure to utilize the
information parsed from the metalink files; outer loop traverses the
files in metalink file while the inner loop traverses the resources for
that file.
2012-07-03 Micah Cowan <micah@cowan.name>
* http.c: Add a parenthesis to fix a bad persistence check.
2012-07-03 Ilim Ugur <ilimugur@gmail.com>
* retr.c: Add an else if branch to retrieve_from_file to check if input
file is a metalink file.
* metalink.c: Add a function metalink_context to parse metalink files
using libmetalink.
* metalink.h: Add the prototype of the new function in metalink.c.
* Makefile.am: Update wget_SOURCES to include metalink.c and metalink.h.
2012-06-17 Giuseppe Scrivano <gscrivano@gnu.org>
* wget.h: Define `CLOSEFAILED'.

View File

@@ -1,6 +1,6 @@
# Makefile for `wget' utility
# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014 Free Software
# Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
@@ -34,29 +34,44 @@
if IRI_IS_ENABLED
IRI_OBJ = iri.c
endif
if METALINK_IS_ENABLED
METALINK_OBJ = metalink.c
METALINK_HEADER = metalink.h
endif
if THREADS_ARE_ENABLED
THREAD_OBJ = multi.c
MULTI_HEADER = multi.h
endif
# The following line is losing on some versions of make!
DEFS += -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
LIBS += $(LIBICONV) $(LIBINTL) $(LIB_CLOCK_GETTIME)
EXTRA_DIST = css.l css.c css_.c build_info.c.in
EXTRA_DIST = css.l css.c css_.c build_info.c.in iri.c multi.c multi.h metalink.c metalink.h
bin_PROGRAMS = wget
wget_SOURCES = cmpt.c connect.c convert.c cookies.c ftp.c \
css_.c css-url.c \
ftp-basic.c ftp-ls.c hash.c host.c html-parse.c html-url.c \
http.c init.c log.c main.c netrc.c progress.c ptimer.c \
recur.c res.c retr.c spider.c url.c warc.c \
utils.c exits.c build_info.c $(IRI_OBJ) \
css-url.h css-tokens.h connect.h convert.h cookies.h \
ftp.h hash.h host.h html-parse.h html-url.h \
http.h http-ntlm.h init.h log.h mswindows.h netrc.h \
options.h progress.h ptimer.h recur.h res.h retr.h \
spider.h ssl.h sysdep.h url.h warc.h utils.h wget.h iri.h \
exits.h gettext.h
wget_SOURCES = cmpt.c connect.c convert.c cookies.c ftp.c \
css_.c css-url.c \
ftp-basic.c ftp-ls.c hash.c host.c html-parse.c html-url.c \
http.c init.c log.c main.c netrc.c progress.c ptimer.c \
recur.c res.c retr.c spider.c url.c warc.c \
utils.c exits.c build_info.c $(IRI_OBJ) \
$(THREAD_OBJ) $(METALINK_OBJ) \
css-url.h css-tokens.h connect.h convert.h cookies.h \
ftp.h hash.h host.h html-parse.h html-url.h \
http.h http-ntlm.h init.h log.h mswindows.h netrc.h \
options.h progress.h ptimer.h recur.h res.h retr.h \
spider.h ssl.h sysdep.h url.h warc.h utils.h wget.h iri.h \
exits.h gettext.h $(THREAD_HEADER) $(METALINK_HEADER)
am__wget_SOURCES_DIST = $(wget_SOURCES)
am__libunittest_a_SOURCES_DIST = $(wget_SOURCES)
nodist_wget_SOURCES = version.c
EXTRA_wget_SOURCES = iri.c
LDADD = $(LIBOBJS) ../lib/libgnu.a
AM_LDFLAGS = $(THREAD_LIB)
AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib

View File

@@ -7,6 +7,8 @@ large-file SIZEOF_OFF_T >= 8
nls defined ENABLE_NLS
ntlm defined ENABLE_NTLM
opie defined ENABLE_OPIE
threads defined ENABLE_THREADS
metalink defined ENABLE_METALINK
psl defined HAVE_LIBPSL
ssl choice:

View File

@@ -60,7 +60,11 @@ enum {
WAIT_FOR_READ = 1,
WAIT_FOR_WRITE = 2
};
#ifdef ENABLE_THREADS
int select_fds (int *, int *, int, double, int);
#else
int select_fd (int, double, int);
#endif
bool test_socket_open (int);
struct transport_implementation {

View File

@@ -36,6 +36,9 @@ as that of the covered work. */
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#ifdef ENABLE_THREADS
#include <pthread.h>
#endif
#include "convert.h"
#include "url.h"
#include "recur.h"
@@ -55,6 +58,49 @@ struct hash_table *dl_url_file_map;
struct hash_table *downloaded_html_set;
struct hash_table *downloaded_css_set;
#ifdef ENABLE_THREADS
static pthread_mutex_t convert_mutex = PTHREAD_MUTEX_INITIALIZER;
static void
lock_convert_mutex()
{
static int convert_mutex_init_p = 0;
if (! convert_mutex_init_p)
{
pthread_mutexattr_t mta;
pthread_mutexattr_init (&mta);
pthread_mutexattr_settype (&mta, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&convert_mutex, &mta);
convert_mutex_init_p = 1;
}
pthread_mutex_lock (&convert_mutex);
}
#define THREAD_SAFE(ret, fn, args, argv) \
ret fn args \
{ \
ret r; \
lock_convert_mutex(); \
r = fn##_1 argv; \
pthread_mutex_unlock (&convert_mutex); \
return r; \
}
#define THREAD_SAFE_VOID(fn, args, argv) \
void fn args \
{ \
lock_convert_mutex(); \
fn##_1 argv; \
pthread_mutex_unlock (&convert_mutex); \
}
#define FNNAME_WTHREADS(fn) fn##_1
#else
#define FNNAME_WTHREADS(fn) fn
#endif
static void convert_links (const char *, struct urlpos *);
@@ -182,7 +228,7 @@ convert_links_in_hashtable (struct hash_table *downloaded_set,
extracted from these two lists. */
void
convert_all_links (void)
FNNAME_WTHREADS(convert_all_links) (void)
{
double secs;
int file_count = 0;
@@ -761,7 +807,7 @@ dissociate_urls_from_file (const char *file)
URL has already been downloaded. */
void
register_download (const char *url, const char *file)
FNNAME_WTHREADS(register_download) (const char *url, const char *file)
{
char *old_file, *old_url;
@@ -841,7 +887,7 @@ register_download (const char *url, const char *file)
register_download() above. */
void
register_redirection (const char *from, const char *to)
FNNAME_WTHREADS(register_redirection) (const char *from, const char *to)
{
char *file;
@@ -856,7 +902,7 @@ register_redirection (const char *from, const char *to)
/* Register that the file has been deleted. */
void
register_delete_file (const char *file)
FNNAME_WTHREADS(register_delete_file) (const char *file)
{
char *old_url, *old_file;
@@ -874,7 +920,7 @@ register_delete_file (const char *file)
/* Register that FILE is an HTML file that has been downloaded. */
void
register_html (const char *file)
FNNAME_WTHREADS(register_html) (const char *url, const char *file)
{
if (!downloaded_html_set)
downloaded_html_set = make_string_hash_table (0);
@@ -884,7 +930,7 @@ register_html (const char *file)
/* Register that FILE is a CSS file that has been downloaded. */
void
register_css (const char *file)
FNNAME_WTHREADS(register_css) (const char *url, const char *file)
{
if (!downloaded_css_set)
downloaded_css_set = make_string_hash_table (0);
@@ -895,8 +941,8 @@ static void downloaded_files_free (void);
/* Cleanup the data structures associated with this file. */
void
convert_cleanup (void)
static void
FNNAME_WTHREADS(convert_cleanup) (void)
{
if (dl_file_url_map)
{
@@ -971,7 +1017,7 @@ downloaded_mode_to_ptr (downloaded_file_t mode)
URLs. */
downloaded_file_t
downloaded_file (downloaded_file_t mode, const char *file)
FNNAME_WTHREADS(downloaded_file) (downloaded_file_t mode, const char *file)
{
downloaded_file_t *ptr;
@@ -1085,6 +1131,17 @@ html_quote_string (const char *s)
return res;
}
#ifdef ENABLE_THREADS
THREAD_SAFE (downloaded_file_t, downloaded_file, (downloaded_file_t a, const char *b), (a, b));
THREAD_SAFE_VOID (register_download, (const char *a, const char *b), (a, b));
THREAD_SAFE_VOID (register_redirection, (const char *a, const char *b), (a, b));
THREAD_SAFE_VOID (register_html, (const char *a, const char *b), (a, b));
THREAD_SAFE_VOID (register_css, (const char *a, const char *b), (a, b));
THREAD_SAFE_VOID (register_delete_file, (const char *a), (a));
THREAD_SAFE_VOID (convert_cleanup, (void), ());
THREAD_SAFE_VOID (convert_all_links, (void), ());
#endif
/*
* vim: et ts=2 sw=2
*/

View File

@@ -98,14 +98,12 @@ typedef enum
} downloaded_file_t;
downloaded_file_t downloaded_file (downloaded_file_t, const char *);
void register_download (const char *, const char *);
void register_redirection (const char *, const char *);
void register_html (const char *);
void register_css (const char *);
void register_delete_file (const char *);
void register_download (const char *a, const char *b);
void convert_all_links (void);
void convert_cleanup (void);
void register_delete_file (const char *a);
void register_redirection (const char *a, const char *b);
void register_css (const char *a, const char *b);
void register_html (const char *a, const char *b);
char *html_quote_string (const char *);

View File

@@ -1306,6 +1306,11 @@ Error in server response, closing control connection.\n"));
/* Get the contents of the document. */
flags = 0;
#ifdef ENABLE_METALINK
if (opt.metalink_file && expected_bytes)
/* If content-length is present, read that much; otherwise, read until EOF. */
flags |= rb_read_exactly;
#endif
if (restval && rest_failed)
flags |= rb_skip_startpos;
rd_size = 0;
@@ -1365,8 +1370,13 @@ Error in server response, closing control connection.\n"));
/* If retrieval failed for any reason, return FTPRETRINT, but do not
close socket, since the control connection is still alive. If
there is something wrong with the control connection, it will
become apparent later. */
if (*respline != '2')
become apparent later.
In case of a metalink file download, proabably due to taking only a chunk
of the file, respline becomes '2', even though file download is successful.
TODO: Make sure exempting metalink downloads from this check does not cause
any troubles.
*/
if (*respline != '2' && !opt.metalink_file)
{
xfree (respline);
if (res != -1)
@@ -1536,7 +1546,7 @@ Error in server response, closing control connection.\n"));
This loop either gets commands from con, or (if ON_YOUR_OWN is
set), makes them up to retrieve the file given by the URL. */
static uerr_t
ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file)
ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_file, struct range *range)
{
int count, orig_lp;
wgint restval, len = 0, qtyread = 0;
@@ -1651,6 +1661,7 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
else
restval = 0;
/* Get the current time string. */
tms = datetime_str (time (NULL));
/* Print fetch message, if opt.verbose. */
@@ -1674,11 +1685,24 @@ ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con, char **local_fi
else
len = 0;
/* If range is not NULL, then this is a segmented download. Get the relevant
segment information from the specified range parameter. */
if (range)
{
restval = range->first_byte;
/* It is not the length in the usual sense, but this is the correct
value for getftp to use. */
len = range->last_byte + 1;
}
/* If we are working on a WARC record, getftp should also write
to the warc_tmp file. */
err = getftp (u, len, &qtyread, restval, con, count, &last_expected_bytes,
warc_tmp);
if (range)
range->bytes_covered = qtyread;
if (con->csock == -1)
con->st &= ~DONE_CWD;
else
@@ -1813,7 +1837,7 @@ Removing file due to --delete-after in ftp_loop_internal():\n"));
else
con->cmd &= ~LEAVE_PENDING;
if (local_file)
if (local_file && !*local_file)
*local_file = xstrdup (locf);
return RETROK;
@@ -1851,7 +1875,7 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
con->target = xstrdup (lf);
xfree (lf);
err = ftp_loop_internal (u, NULL, con, NULL);
err = ftp_loop_internal (u, NULL, con, NULL, NULL);
lf = xstrdup (con->target);
xfree (con->target);
con->target = old_target;
@@ -2046,7 +2070,7 @@ Already have correct symlink %s -> %s\n\n"),
else /* opt.retr_symlinks */
{
if (dlthis)
err = ftp_loop_internal (u, f, con, NULL);
err = ftp_loop_internal (u, f, con, NULL, NULL);
} /* opt.retr_symlinks */
break;
case FT_DIRECTORY:
@@ -2057,7 +2081,7 @@ Already have correct symlink %s -> %s\n\n"),
case FT_PLAINFILE:
/* Call the retrieve loop. */
if (dlthis)
err = ftp_loop_internal (u, f, con, NULL);
err = ftp_loop_internal (u, f, con, NULL, NULL);
break;
case FT_UNKNOWN:
logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
@@ -2340,7 +2364,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
{
/* Let's try retrieving it anyway. */
con->st |= ON_YOUR_OWN;
res = ftp_loop_internal (u, NULL, con, NULL);
res = ftp_loop_internal (u, NULL, con, NULL, NULL);
return res;
}
@@ -2361,7 +2385,7 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action)
encoded into a URL. */
uerr_t
ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
bool recursive, bool glob)
bool recursive, bool glob, struct range *range)
{
ccon con; /* FTP connection */
uerr_t res;
@@ -2375,6 +2399,10 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
con.rs = ST_UNIX;
con.id = NULL;
con.proxy = proxy;
/* To let ftp_loop_internal AND getftp know of the desired file name. Added
while implementing metalink support to wget. */
if(local_file && *local_file)
con.target = xstrdup (*local_file);
/* If the file name is empty, the user probably wants a directory
index. We'll provide one, properly HTML-ized. Unless
@@ -2440,7 +2468,7 @@ ftp_loop (struct url *u, char **local_file, int *dt, struct url *proxy,
ispattern ? GLOB_GLOBALL : GLOB_GETONE);
}
else
res = ftp_loop_internal (u, NULL, &con, local_file);
res = ftp_loop_internal (u, NULL, &con, local_file, range);
}
if (res == FTPOK)
res = RETROK;

View File

@@ -32,6 +32,8 @@ as that of the covered work. */
#ifndef FTP_H
#define FTP_H
#include "wget.h"
#include "host.h"
/* System types. */
@@ -152,7 +154,7 @@ enum wget_ftp_fstatus
};
struct fileinfo *ftp_parse_ls (const char *, const enum stype);
uerr_t ftp_loop (struct url *, char **, int *, struct url *, bool, bool);
uerr_t ftp_loop (struct url *, char **, int *, struct url *, bool, bool, struct range *);
uerr_t ftp_index (const char *, struct url *, struct fileinfo *);

View File

@@ -39,7 +39,11 @@ as that of the covered work. */
#include <errno.h>
#include <time.h>
#include <locale.h>
#ifdef ENABLE_THREADS
#include <pthread.h>
# include "multi.h"
#endif
#include "hash.h"
#include "http.h"
#include "utils.h"
@@ -1231,10 +1235,42 @@ parse_content_disposition (const char *hdr, char **filename)
below. Ideally, it should be possible to cache an arbitrary fixed
number of these connections. */
#ifndef ENABLE_THREADS
/* Whether a persistent connection is active. */
static bool pconn_active;
#define PCONN_LOCK()
#define PCONN_UNLOCK()
static struct {
#else
static pthread_mutex_t pconn_mutex;
static void
pconn_lock()
{
static int pconn_mutex_init_p = 0;
if (! pconn_mutex_init_p)
{
pthread_mutexattr_t mta;
pthread_mutexattr_init (&mta);
pthread_mutexattr_settype (&mta, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&pconn_mutex, &mta);
pconn_mutex_init_p = 1;
}
pthread_mutex_lock (&pconn_mutex);
}
#define PCONN_LOCK() pconn_lock()
#define PCONN_UNLOCK() pthread_mutex_unlock (&pconn_mutex)
static struct s_pconn {
struct s_pconn *next;
#endif
/* The socket of the connection. */
int socket;
@@ -1255,12 +1291,19 @@ static struct {
/* NTLM data of the current connection. */
struct ntlmdata ntlm;
#endif
} pconn;
#ifndef ENABLE_THREADS
} pconn;
#else
} *pconn = NULL;
size_t pconn_length = 0;
#endif
/* Mark the persistent connection as invalid and free the resources it
uses. This is used by the CLOSE_* macros after they forcefully
close a registered persistent connection. */
#ifndef ENABLE_THREADS
static void
invalidate_persistent (void)
{
@@ -1270,7 +1313,40 @@ invalidate_persistent (void)
xfree (pconn.host);
xzero (pconn);
}
#else
static void
invalidate_persistent (int fd)
{
struct s_pconn *prev, *it;
DEBUGP (("Disabling further reuse of socket %d.\n", fd));
PCONN_LOCK ();
prev = NULL;
it = pconn;
for (; it; it = it->next)
{
if (it->socket == fd)
break;
prev = it;
}
fd_close (fd);
if (it)
{
if (prev)
prev->next = it->next;
else
pconn = it->next;
pconn_length--;
xfree (it->host);
xfree (it);
}
PCONN_UNLOCK ();
}
#endif
/* Register FD, which should be a TCP/IP connection to HOST:PORT, as
persistent. This will enable someone to use the same connection
later. In the context of HTTP, this must be called only AFTER the
@@ -1282,6 +1358,7 @@ invalidate_persistent (void)
static void
register_persistent (const char *host, int port, int fd, bool ssl)
{
#ifndef ENABLE_THREADS
if (pconn_active)
{
if (pconn.socket == fd)
@@ -1308,32 +1385,103 @@ register_persistent (const char *host, int port, int fd, bool ssl)
pconn.authorized = false;
DEBUGP (("Registered socket %d for persistent reuse.\n", fd));
#else
PCONN_LOCK ();
struct s_pconn *it;
for (it = pconn; it; it = it->next)
if (it->socket == fd)
{
DEBUGP (("Socket %d already registered.\n", fd));
goto exit;
}
if (pconn_length >= opt.jobs)
{
struct s_pconn *prev = NULL;
if (pconn)
{
for (it = pconn; it->next; it = it->next)
prev = it;
if (prev)
{
prev->next = it->next;
xfree (it->host);
xfree (it);
}
else
{
xfree (pconn->host);
xfree (pconn);
pconn = NULL;
}
}
}
it = malloc (sizeof *it);
if (it == NULL)
goto exit;
memset (it, 0, sizeof *it);
it->socket = fd;
it->host = xstrdup (host);
it->port = port;
it->ssl = ssl;
it->authorized = false;
it->next = pconn;
pconn = it;
pconn_length++;
DEBUGP (("Registered socket %d for persistent reuse.\n", fd));
exit:
PCONN_UNLOCK ();
#endif
}
#ifndef ENABLE_THREADS
/* Return true if a persistent connection is available for connecting
to HOST:PORT. */
static bool
persistent_available_p (const char *host, int port, bool ssl,
bool *host_lookup_failed)
#else
/* Return 1 if a persistent connection is available for connecting
to HOST:PORT. 0 if it is not available, -1 if the connection must
be destroyed by the caller. */
static int
persistent_available_p (struct s_pconn *pconn, const char *host, int port,
bool ssl, bool *host_lookup_failed)
#endif
{
#ifndef ENABLE_THREADS
/* First, check whether a persistent connection is active at all. */
if (!pconn_active)
return false;
return 0;
/* If we want SSL and the last connection wasn't or vice versa,
don't use it. Checking for host and port is not enough because
HTTP and HTTPS can apparently coexist on the same port. */
if (ssl != pconn.ssl)
return false;
return 0;
/* If we're not connecting to the same port, we're not interested. */
if (port != pconn.port)
return false;
return 0;
/* If the host is the same, we're in business. If not, there is
still hope -- read below. */
if (0 != strcasecmp (host, pconn.host))
#else
if (ssl != pconn->ssl)
return 0;
if (port != pconn->port)
return 0;
if (0 != strcasecmp (host, pconn->host))
#endif
{
/* Check if pconn.socket is talking to HOST under another name.
This happens often when both sites are virtual hosts
@@ -1351,31 +1499,37 @@ persistent_available_p (const char *host, int port, bool ssl,
/* Don't try to talk to two different SSL sites over the same
secure connection! (Besides, it's not clear that
name-based virtual hosting is even possible with SSL.) */
return false;
return 0;
/* If pconn.socket's peer is one of the IP addresses HOST
resolves to, pconn.socket is for all intents and purposes
already talking to HOST. */
#ifndef ENABLE_THREADS
if (!socket_ip_address (pconn.socket, &ip, ENDPOINT_PEER))
{
/* Can't get the peer's address -- something must be very
wrong with the connection. */
invalidate_persistent ();
return false;
return 0;
}
#else
if (!socket_ip_address (pconn->socket, &ip, ENDPOINT_PEER))
{
return -1;
}
#endif
al = lookup_host (host, 0);
if (!al)
{
*host_lookup_failed = true;
return false;
return 0;
}
found = address_list_contains (al, &ip);
address_list_release (al);
if (!found)
return false;
return 0;
/* The persistent connection's peer address was found among the
addresses HOST resolved to; therefore, pconn.sock is in fact
@@ -1395,17 +1549,69 @@ persistent_available_p (const char *host, int port, bool ssl,
body in response to HEAD, or if it sends more than conent-length
data, we won't reuse the corrupted connection.) */
#ifndef ENABLE_THREADS
if (!test_socket_open (pconn.socket))
{
/* Oops, the socket is no longer open. Now that we know that,
let's invalidate the persistent connection before returning
0. */
invalidate_persistent ();
return false;
return -1;
}
#else
if (!test_socket_open (pconn->socket))
{
return -1;
}
#endif
return 1;
}
#ifdef ENABLE_THREADS
static struct s_pconn *
get_persistent (const char *host, int port, bool ssl, bool *host_lookup_failed)
{
struct s_pconn *prev, *it;
PCONN_LOCK ();
prev = NULL;
it = pconn;
for (; it; it = it->next)
{
int ret;
ret = persistent_available_p (it, host, port, ssl, host_lookup_failed);
if (ret == 1)
break;
if (ret == 0)
prev = it;
else
{
struct s_pconn *next = it->next;
invalidate_persistent (it->socket);
it = next;
if (it == NULL)
break;
}
}
return true;
if (it)
{
pconn_length--;
if (prev)
prev->next = it->next;
else
pconn = it->next;
}
PCONN_UNLOCK ();
return it;
}
#endif
/* The idea behind these two CLOSE macros is to distinguish between
two cases: one when the job we've been doing is finished, and we
@@ -1422,6 +1628,8 @@ persistent_available_p (const char *host, int port, bool ssl,
`pc_active_p && (fd) == pc_last_fd' is "we're *now* using an
active, registered connection". */
#ifndef ENABLE_THREADS
#define CLOSE_FINISH(fd) do { \
if (!keep_alive) \
{ \
@@ -1442,12 +1650,30 @@ persistent_available_p (const char *host, int port, bool ssl,
fd_close (fd); \
fd = -1; \
} while (0)
#else
#define CLOSE_FINISH(fd) do { \
if (!keep_alive) \
{ \
invalidate_persistent (fd); \
} \
} while (0)
#define CLOSE_INVALIDATE(fd) do { \
invalidate_persistent (fd); \
fd = -1; \
} while (0)
#endif
struct http_stat
{
wgint len; /* received length */
wgint contlen; /* expected length */
wgint restval; /* the restart value */
wgint restval_last; /* last byte to download while downloading in
segments */
int res; /* the result of last read */
char *rderrmsg; /* error message from read error */
char *newloc; /* new location (redirection) */
@@ -1687,6 +1913,10 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
int sock = -1;
#ifdef ENABLE_THREADS
struct s_pconn *pconn = NULL;
#endif
/* Set to 1 when the authorization has already been sent and should
not be tried again. */
bool auth_finished = false;
@@ -1796,7 +2026,16 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
/* ... but some HTTP/1.0 caches doesn't implement Cache-Control. */
request_set_header (req, "Pragma", "no-cache", rel_none);
}
if (hs->restval)
if(hs->restval_last)
{
request_set_header (req, "Range",
aprintf ("bytes=%s-%s",
number_to_static_string (hs->restval),
number_to_static_string (hs->restval_last)),
rel_value);
}
else if (hs->restval)
request_set_header (req, "Range",
aprintf ("bytes=%s-",
number_to_static_string (hs->restval)),
@@ -1955,6 +2194,8 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
relevant = u;
#endif
#ifndef ENABLE_THREADS
if (persistent_available_p (relevant->host, relevant->port,
#ifdef HAVE_SSL
relevant->scheme == SCHEME_HTTPS,
@@ -1978,6 +2219,32 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
pconn.port);
DEBUGP (("Reusing fd %d.\n", sock));
if (pconn.authorized)
#else
pconn = get_persistent (relevant->host, relevant->port,
#ifdef HAVE_SSL
relevant->scheme == SCHEME_HTTPS,
#else
0,
#endif
&host_lookup_failed);
if (pconn)
{
int family = socket_family (pconn->socket, ENDPOINT_PEER);
sock = pconn->socket;
using_ssl = pconn->ssl;
if (family == AF_INET6)
logprintf (LOG_VERBOSE, _("Reusing existing connection to [%s]:%d.\n"),
quotearg_style (escape_quoting_style, pconn->host),
pconn->port);
else
logprintf (LOG_VERBOSE, _("Reusing existing connection to %s:%d.\n"),
quotearg_style (escape_quoting_style, pconn->host),
pconn->port);
DEBUGP (("Reusing fd %d.\n", sock));
if (pconn->authorized)
#endif
/* If the connection is already authorized, the "Basic"
authorization added by code above is unnecessary and
only hurts us. */
@@ -1999,7 +2266,9 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
if (sock < 0)
{
PCONN_LOCK();
sock = connect_to_host (conn->host, conn->port);
PCONN_UNLOCK();
if (sock == E_HOST)
{
request_free (req);
@@ -2318,10 +2587,14 @@ read_header:
}
}
if (keep_alive)
/* The server has promised that it will not close the connection
when we're done. This means that we can register it. */
register_persistent (conn->host, conn->port, sock, using_ssl);
/* The server has promised that it will not close the connection
when we're done. This means that we can register it. */
#define REGISTER_PERSISTENT_CONNECTION(i) do { \
if (keep_alive) \
register_persistent (conn->host, conn->port, sock, using_ssl); \
else \
CLOSE_FINISH(sock); \
} while (0)
if (statcode == HTTP_STATUS_UNAUTHORIZED)
{
@@ -2350,19 +2623,25 @@ read_header:
return _err;
}
else
CLOSE_FINISH (sock);
REGISTER_PERSISTENT_CONNECTION (1);
}
else
{
/* Since WARC is disabled, we are not interested in the response body. */
if (keep_alive && !head_only
&& skip_short_body (sock, contlen, chunked_transfer_encoding))
CLOSE_FINISH (sock);
&& skip_short_body (sock, contlen, chunked_transfer_encoding)) {
REGISTER_PERSISTENT_CONNECTION (2);
}
else
CLOSE_INVALIDATE (sock);
}
#ifndef ENABLE_THREADS
pconn.authorized = false;
#else
if (pconn)
pconn->authorized = false;
#endif
uerr_t auth_err = RETROK;
if (!auth_finished && (user && passwd))
{
@@ -2441,6 +2720,8 @@ read_header:
xfree_null (message);
resp_free (resp);
xfree (head);
REGISTER_PERSISTENT_CONNECTION (3);
if (auth_err == RETROK)
return AUTHFAILED;
else
@@ -2450,7 +2731,14 @@ read_header:
{
/* Kludge: if NTLM is used, mark the TCP connection as authorized. */
if (ntlm_seen)
{
#ifndef ENABLE_THREADS
pconn.authorized = true;
#else
if (pconn)
pconn->authorized = true;
#endif
}
}
/* Determine the local filename if needed. Notice that if -O is used
@@ -2492,6 +2780,7 @@ read_header:
resp_free (resp);
xfree (head);
xfree_null (message);
REGISTER_PERSISTENT_CONNECTION (4);
return RETRUNNEEDED;
}
else if (!ALLOW_CLOBBER)
@@ -2674,20 +2963,23 @@ read_header:
return _err;
}
else
CLOSE_FINISH (sock);
REGISTER_PERSISTENT_CONNECTION (5);
}
else
{
/* Since WARC is disabled, we are not interested in the response body. */
if (keep_alive && !head_only
&& skip_short_body (sock, contlen, chunked_transfer_encoding))
CLOSE_FINISH (sock);
{
REGISTER_PERSISTENT_CONNECTION (11);
}
else
CLOSE_INVALIDATE (sock);
}
xfree_null (type);
xfree (head);
REGISTER_PERSISTENT_CONNECTION (6);
/* From RFC2616: The status codes 303 and 307 have
been added for servers that wish to make unambiguously
clear which kind of reaction is expected of the client.
@@ -2775,8 +3067,7 @@ read_header:
xfree (head);
return RETRUNNEEDED;
}
if ((contrange != 0 && contrange != hs->restval)
|| (H_PARTIAL (statcode) && !contrange))
if ((contrange != 0 && (!(hs->restval_last) && contrange != hs->restval)))
{
/* The Range request was somehow misunderstood by the server.
Bail out. */
@@ -2851,7 +3142,7 @@ read_header:
return _err;
}
else
CLOSE_FINISH (sock);
REGISTER_PERSISTENT_CONNECTION(7);
}
else
{
@@ -2865,12 +3156,15 @@ read_header:
CLOSE_FINISH (sock);
else if (keep_alive
&& skip_short_body (sock, contlen, chunked_transfer_encoding))
/* Successfully skipped the body; also keep using the socket. */
CLOSE_FINISH (sock);
{
/* Successfully skipped the body; also keep using the socket. */
REGISTER_PERSISTENT_CONNECTION(8);
}
else
CLOSE_INVALIDATE (sock);
}
REGISTER_PERSISTENT_CONNECTION (9);
xfree (head);
xfree_null (type);
return RETRFINISHED;
@@ -2972,6 +3266,8 @@ read_header:
xfree (head);
xfree_null (type);
REGISTER_PERSISTENT_CONNECTION (10);
if (hs->res >= 0)
CLOSE_FINISH (sock);
else
@@ -2988,7 +3284,7 @@ read_header:
uerr_t
http_loop (struct url *u, struct url *original_url, char **newloc,
char **local_file, const char *referer, int *dt, struct url *proxy,
struct iri *iri)
struct iri *iri, struct range *range)
{
int count;
bool got_head = false; /* used for time-stamping and filename detection */
@@ -3010,12 +3306,14 @@ http_loop (struct url *u, struct url *original_url, char **newloc,
force_full_retrieve = true;
#ifndef ENABLE_METALINK
/* Assert that no value for *LOCAL_FILE was passed. */
assert (local_file == NULL || *local_file == NULL);
/* Set LOCAL_FILE parameter. */
if (local_file && opt.output_document)
*local_file = HYPHENP (opt.output_document) ? NULL : xstrdup (opt.output_document);
#endif
/* Reset NEWLOC parameter. */
*newloc = NULL;
@@ -3041,8 +3339,11 @@ http_loop (struct url *u, struct url *original_url, char **newloc,
}
else if (!opt.content_disposition)
{
hstat.local_file =
url_file_name (opt.trustservernames ? u : original_url, NULL);
if(local_file && *local_file)
hstat.local_file = xstrdup (*local_file);
else
hstat.local_file =
url_file_name (opt.trustservernames ? u : original_url, NULL);
got_name = true;
}
@@ -3128,6 +3429,9 @@ Spider mode enabled. Check if remote file exists.\n"));
else
*dt &= ~HEAD_ONLY;
/* GSoC TODO: should correct assignments to restval_last below to
include cases like server failure in one of the segments. */
/* Decide whether or not to restart. */
if (force_full_retrieve)
hstat.restval = hstat.len;
@@ -3140,12 +3444,20 @@ Spider mode enabled. Check if remote file exists.\n"));
/* When -c is used, continue from on-disk size. (Can't use
hstat.len even if count>1 because we don't want a failed
first attempt to clobber existing data.) */
hstat.restval = st.st_size;
hstat.restval = st.st_size;
else if (count > 1)
/* otherwise, continue where the previous try left off */
hstat.restval = hstat.len;
hstat.restval = hstat.len;
else
hstat.restval = 0;
hstat.restval = 0;
if (range)
{
hstat.restval = range->first_byte;
hstat.restval_last = range -> last_byte;
}
else
hstat.restval_last = 0;
/* Decide whether to send the no-cache directive. We send it in
two cases:
@@ -3165,6 +3477,9 @@ Spider mode enabled. Check if remote file exists.\n"));
/* Time? */
tms = datetime_str (time (NULL));
if(range)
range->bytes_covered = hstat.len;
/* Get the new location (with or without the redirection). */
if (hstat.newloc)
*newloc = xstrdup (hstat.newloc);
@@ -3562,7 +3877,7 @@ Remote file exists.\n\n"));
while (!opt.ntry || (count < opt.ntry));
exit:
if (ret == RETROK && local_file)
if (ret == RETROK && local_file && !(*local_file))
{
xfree_null (*local_file);
*local_file = xstrdup (hstat.local_file);
@@ -3988,7 +4303,16 @@ create_authorization_line (const char *au, const char *user,
*finished = true;
return digest_authentication_encode (au, user, passwd, method, path, auth_err);
#endif
#ifdef ENABLE_NTLM
#if defined ENABLE_NTLM && defined ENABLE_THREADS
case 'N': /* NTLM */
if (!ntlm_input (&pconn->ntlm, au))
{
*finished = true;
return NULL;
}
return ntlm_output (&pconn->ntlm, user, passwd, finished);
#elif defined ENABLE_NTLM
case 'N': /* NTLM */
if (!ntlm_input (&pconn.ntlm, au))
{
@@ -4026,7 +4350,18 @@ save_cookies (void)
void
http_cleanup (void)
{
#ifndef ENABLE_THREADS
xfree_null (pconn.host);
#else
struct s_pconn *it = pconn;
for (; it; it = it->next)
{
xfree_null (it->host);
xzero (it);
}
#endif
if (wget_cookie_jar)
cookie_jar_delete (wget_cookie_jar);
}

View File

@@ -31,10 +31,12 @@ as that of the covered work. */
#ifndef HTTP_H
#define HTTP_H
#include "wget.h"
struct url;
uerr_t http_loop (struct url *, struct url *, char **, char **, const char *,
int *, struct url *, struct iri *);
int *, struct url *, struct iri *, struct range *);
void save_cookies (void);
void http_cleanup (void);
time_t http_atotm (const char *);

View File

@@ -208,6 +208,9 @@ static const struct {
#endif
{ "input", &opt.input_filename, cmd_file },
{ "iri", &opt.enable_iri, cmd_boolean },
#ifdef ENABLE_THREADS
{ "jobs", &opt.jobs, cmd_number },
#endif
{ "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
{ "limitrate", &opt.limit_rate, cmd_bytes },
{ "loadcookies", &opt.cookies_input, cmd_file },
@@ -215,6 +218,9 @@ static const struct {
{ "logfile", &opt.lfilename, cmd_file },
{ "login", &opt.ftp_user, cmd_string },/* deprecated*/
{ "maxredirect", &opt.max_redirect, cmd_number },
#ifdef ENABLE_METALINK
{ "metalink", &opt.metalink_file, cmd_file },
#endif
{ "method", &opt.method, cmd_string_uppercase },
{ "mirror", NULL, cmd_spec_mirror },
{ "netrc", &opt.netrc, cmd_boolean },
@@ -259,6 +265,9 @@ static const struct {
{ "removelisting", &opt.remove_listing, cmd_boolean },
{ "reportspeed", &opt.report_bps, cmd_spec_report_speed},
{ "restrictfilenames", NULL, cmd_spec_restrict_file_names },
#ifdef ENABLE_METALINK
{ "retries", &opt.n_retries, cmd_number_inf },
#endif
{ "retrsymlinks", &opt.retr_symlinks, cmd_boolean },
{ "retryconnrefused", &opt.retry_connrefused, cmd_boolean },
{ "robots", &opt.use_robots, cmd_boolean },
@@ -342,6 +351,12 @@ defaults (void)
opt.cookies = true;
opt.verbose = -1;
opt.ntry = 20;
#ifdef ENABLE_THREADS
opt.jobs = 1;
#endif
#ifdef ENABLE_METALINK
opt.n_retries = 1;
#endif
opt.reclevel = 5;
opt.add_hostdir = true;
opt.netrc = true;

View File

@@ -220,12 +220,18 @@ static struct cmdline_option option_data[] =
#endif
{ "input-file", 'i', OPT_VALUE, "input", -1 },
{ "iri", 0, OPT_BOOLEAN, "iri", -1 },
#ifdef ENABLE_THREADS
{ "jobs", 0, OPT_VALUE, "jobs", 1 },
#endif
{ "keep-session-cookies", 0, OPT_BOOLEAN, "keepsessioncookies", -1 },
{ "level", 'l', OPT_VALUE, "reclevel", -1 },
{ "limit-rate", 0, OPT_VALUE, "limitrate", -1 },
{ "load-cookies", 0, OPT_VALUE, "loadcookies", -1 },
{ "local-encoding", 0, OPT_VALUE, "localencoding", -1 },
{ "max-redirect", 0, OPT_VALUE, "maxredirect", -1 },
#ifdef ENABLE_METALINK
{ "metalink-file", 0, OPT_VALUE, "metalink", -1 },
#endif
{ "method", 0, OPT_VALUE, "method", -1 },
{ "mirror", 'm', OPT_BOOLEAN, "mirror", -1 },
{ "no", 'n', OPT__NO, NULL, required_argument },
@@ -268,6 +274,9 @@ static struct cmdline_option option_data[] =
{ "report-speed", 0, OPT_BOOLEAN, "reportspeed", -1 },
{ "restrict-file-names", 0, OPT_BOOLEAN, "restrictfilenames", -1 },
{ "retr-symlinks", 0, OPT_BOOLEAN, "retrsymlinks", -1 },
#ifdef ENABLE_METALINK
{ "retries", 0, OPT_VALUE, "retries", -1 },
#endif
{ "retry-connrefused", 0, OPT_BOOLEAN, "retryconnrefused", -1 },
{ "save-cookies", 0, OPT_VALUE, "savecookies", -1 },
{ "save-headers", 0, OPT_BOOLEAN, "saveheaders", -1 },
@@ -472,8 +481,18 @@ Logging and input file:\n"),
--no-config Do not read any config file.\n"),
"\n",
#ifdef ENABLE_METALINK
N_("\
--metalink-file download URLs found in local or external metalink FILE.\n"),
#endif
N_("\
Download:\n"),
#ifdef ENABLE_METALINK
N_("\
--retries specify the number of retries for a file.\n\
(needs to be used with --metalink-file)\n"),
#endif
N_("\
-t, --tries=NUMBER set number of retries to NUMBER (0 unlimits).\n"),
N_("\
@@ -552,8 +571,11 @@ Download:\n"),
--remote-encoding=ENC use ENC as the default remote encoding.\n"),
N_("\
--unlink remove file before clobber.\n"),
#ifdef ENABLE_THREADS
N_("\
--jobs specify how many threads use.\n"),
#endif
"\n",
N_("\
Directories:\n"),
N_("\
@@ -1365,7 +1387,11 @@ for details.\n\n"));
opt.always_rest = false;
}
if (!nurl && !opt.input_filename)
if (!nurl && !opt.input_filename
#ifdef ENABLE_METALINK
&& !opt.metalink_file
#endif
)
{
/* No URL specified. */
fprintf (stderr, _("%s: missing URL\n"), exec_name);
@@ -1588,6 +1614,53 @@ outputting to a regular file.\n"));
}
}
#ifdef ENABLE_METALINK
if(opt.metalink_file)
{
/* --protocol-directories is the longest option among the ones checked below. */
char *temp_option = malloc(sizeof "--protocol-directories");
if(opt.user || opt.passwd || opt.http_user || opt.http_passwd ||
opt.ftp_user || opt.ftp_passwd || opt.ask_passwd)
{
fprintf (stderr, _("Username and password information not needed to \
be specified when downloading from a metalink.\n"));
exit (WGET_EXIT_GENERIC_ERROR);
}
temp_option[0] = '\0';
if(opt.input_filename)
sprintf(temp_option, "-i");
else if(opt.output_document)
sprintf(temp_option, "-O");
else if(opt.base_href)
sprintf(temp_option, "--base");
else if(opt.force_html)
sprintf(temp_option, "--force-html");
else if(opt.always_rest)
sprintf(temp_option, "-c");
else if(opt.spider)
sprintf(temp_option, "-spider");
else if(opt.cut_dirs)
sprintf(temp_option, "--cut-dirs");
else if(opt.wait)
sprintf(temp_option, "-w");
else if(opt.waitretry != 10)
sprintf(temp_option, "--waitretry");
else if(opt.timestamping)
sprintf(temp_option, "--timestamping");
else if(opt.protocol_directories)
sprintf(temp_option, "--protocol-directories");
else if(opt.dirstruct)
sprintf(temp_option, "--force-directories");
if(temp_option[0])
{
fprintf (stderr, _("%s can't be used with --metalink.\n"), temp_option);
free(temp_option);
exit (WGET_EXIT_GENERIC_ERROR);
}
}
#endif
#ifdef __VMS
/* Set global ODS5 flag according to the specified destination (if
any), otherwise according to the current default device.
@@ -1661,7 +1734,7 @@ outputting to a regular file.\n"));
else
{
retrieve_url (url_parsed, *t, &filename, &redirected_URL, NULL,
&dt, opt.recursive, iri, true);
&dt, opt.recursive, iri, true, NULL);
}
if (opt.delete_after && filename != NULL && file_exists_p (filename))
@@ -1683,6 +1756,7 @@ outputting to a regular file.\n"));
{
int count;
int status;
status = retrieve_from_file (opt.input_filename, opt.force_html, &count);
inform_exit_status (status);
if (!count)
@@ -1690,6 +1764,21 @@ outputting to a regular file.\n"));
opt.input_filename);
}
#ifdef ENABLE_METALINK
/* And then from the metalink file, if any. */
if (opt.metalink_file)
{
int count;
int status;
status = retrieve_from_file (opt.metalink_file, opt.force_html, &count);
inform_exit_status (status);
if (!count)
logprintf (LOG_NOTQUIET, _("No URLs found in %s.\n"),
opt.input_filename);
}
#endif
/* Print broken links. */
if (opt.recursive && opt.spider)
print_broken_links ();
@@ -1697,7 +1786,11 @@ outputting to a regular file.\n"));
/* Print the downloaded sum. */
if ((opt.recursive || opt.page_requisites
|| nurl > 1
|| (opt.input_filename && total_downloaded_bytes != 0))
|| (opt.input_filename && total_downloaded_bytes != 0)
#ifdef ENABLE_METALINK
|| (opt.metalink_file && total_downloaded_bytes != 0)
#endif
)
&&
total_downloaded_bytes != 0)
{

470
src/metalink.c Normal file
View File

@@ -0,0 +1,470 @@
/* Declarations for HTTP.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014 Free Software
Foundation, Inc.
This file is part of GNU Wget.
GNU Wget is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GNU Wget is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wget. If not, see <http://www.gnu.org/licenses/>.
Additional permission under GNU GPL version 3 section 7
If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
grants you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination
shall include the source code for the parts of OpenSSL used as well
as that of the covered work. */
#include "wget.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <metalink/metalink_parser.h>
#include <metalink/metalink_types.h>
#include "log.h"
#include "md5.h"
#include "sha1.h"
#include "sha256.h"
#include "metalink.h"
#include "utils.h"
#define HASH_TYPES 3
/* Between MD5, SHA1 and SHA256, SHA256 has the greatest hash length, which is
32. In the line below, 64 is written to have a more readable code. */
#define MAX_DIGEST_LENGTH 32
static char supported_hashes[HASH_TYPES][7] = {"sha256", "sha1", "md5"};
static int digest_sizes[HASH_TYPES] = {SHA256_DIGEST_SIZE, SHA1_DIGEST_SIZE, MD5_DIGEST_SIZE};
static int (*hash_function[HASH_TYPES]) (FILE *, void *) = {sha256_stream, sha1_stream, md5_stream};
/* First, parse the metalink using libmetalink functions and structures. Then
pass the information to an internal set of structures. */
mlink *
parse_metalink(char *input_file)
{
int err;
metalink_t *metalink;
metalink_file_t **files;
metalink_resource_t **resources;
metalink_checksum_t **checksums;
metalink_chunk_checksum_t *chunk_checksum;
metalink_piece_hash_t **piece_hashes;
mlink *m_link;
err = metalink_parse_file (input_file, &metalink);
if(err != 0 || !metalink)
{
logprintf (LOG_VERBOSE, "Libmetalink could not parse the metalink file.\n");
return NULL;
}
else if(metalink->files == NULL) {
logprintf (LOG_VERBOSE, "PARSE METALINK: Metalink doesn't have any file data.\n");
metalink_delete(metalink);
return NULL;
}
m_link = malloc (sizeof *m_link);
m_link->identity = (metalink->identity ? xstrdup (metalink->identity) : NULL);
m_link->tags = (metalink->tags ? xstrdup (metalink->tags) : NULL);
m_link->files = NULL;
m_link->num_of_files = 0;
for (files = metalink->files; *files; ++files)
{
mlink_file *file;
if (!(*files)->name)
{
/* File name is missing */
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping file"
" due to missing name/path.\n");
continue;
}
else if (!(*files)->resources)
{
/* URL is missing */
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping file(%s)"
" due to missing resources.\n", (*files)->name);
continue;
}
file = malloc(sizeof(mlink_file));
++(m_link->num_of_files);
file -> next = (m_link->files);
(m_link->files) = file;
file->name = xstrdup ((*files)->name);
file->size = (*files)->size;
file->maxconnections = (*files)->maxconnections;
file->version = ((*files)->version ? xstrdup ((*files)->version) : NULL);
file->language = ((*files)->language ? xstrdup ((*files)->language) : NULL);
file->os = ((*files)->os ? xstrdup ((*files)->os) : NULL);
file->resources = NULL;
file->checksums = NULL;
file->chunk_checksum = NULL;
file->num_of_res = file->num_of_checksums = 0;
for (resources = (*files)->resources; *resources; ++resources)
{
mlink_resource *resource;
if (!(*resources)->url)
{
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping resource"
" due to missing URL.\n");
continue;
}
resource = malloc (sizeof(mlink_resource));
++(file->num_of_res);
resource->url = xstrdup ((*resources)->url);
resource->type = ((*resources)->type ? xstrdup ((*resources)->type) : NULL);
resource->location = ((*resources)->location ? xstrdup ((*resources)->location) : NULL);
resource->preference = (*resources)->preference;
resource->maxconnections = (*resources)->maxconnections;
resource->next = (file->resources);
(file->resources) = resource;
}
for (checksums = (*files)->checksums; *checksums; ++checksums)
{
mlink_checksum *checksum = malloc (sizeof(mlink_checksum));
if (!(*checksums)->type)
{
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping checksum"
" due to missing hash type.\n");
continue;
}
else if (!(*checksums)->hash)
{
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping resource"
" due to missing hash value.\n");
continue;
}
checksum->type = ((*checksums)->type ? xstrdup ((*checksums)->type) : NULL);
checksum->hash = ((*checksums)->hash ? xstrdup ((*checksums)->hash) : NULL);
checksum->next = (file->checksums);
(file->checksums) = checksum;
}
if((chunk_checksum = (*files)->chunk_checksum))
{
mlink_chunk_checksum *chunk_sum;
if(!chunk_checksum->type)
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping chunk checksum"
" due to missing type information.\n");
else
{
chunk_sum = malloc (sizeof(mlink_chunk_checksum));
chunk_sum->length = chunk_checksum->length;
chunk_sum->type = (chunk_checksum->type ? xstrdup (chunk_checksum->type) : NULL);
for (piece_hashes = chunk_checksum->piece_hashes; *piece_hashes; ++piece_hashes)
{
mlink_piece_hash piece_hash;
if(!chunk_checksum->type)
{
logprintf (LOG_VERBOSE, "PARSE METALINK: Skipping chunk checksum"
" due to missing hash value for piece(%d).\n",
(*piece_hashes)->piece);
free (chunk_sum);
break;
}
}
}
}
}
metalink_delete(metalink);
return m_link;
}
/* Elect resouces so that only the URLs with type HTTP and FTP (i.e. the
protocols supported by Metalink&GNU Wget) remain on the list of resources. */
void
elect_resources (mlink *mlink)
{
mlink_file *file;
mlink_resource *res, *res_next;
for (file = mlink->files; file; file = file->next)
{
res = file->resources;
if (!res)
continue;
while (res_next = res->next)
{
if (strcmp(res_next->type, "ftp") && strcmp(res_next->type, "http"))
{
res->next = res_next->next;
free(res_next);
}
else
res = res_next;
}
res = file->resources;
if (strcmp(res->type, "ftp") && strcmp(res->type, "http"))
{
file->resources = res->next;
free(res);
}
}
}
/* Elect checksums so that only the hashes with types MD5, SHA-1 or SHA-256
(i.e. the hashes supported by Metalink) remain on the list of checksums. */
void
elect_checksums (mlink *mlink)
{
int i;
mlink_file *file = mlink -> files;
mlink_checksum *csum, *csum_next;
for (; file; file = file->next)
{
csum = file->checksums;
if (!csum)
continue;
while (csum_next = csum->next)
{
/* Traverse supported hash types & break if csum->type is the same. */
for (i = 0; i < HASH_TYPES; ++i)
if (!strcmp(csum_next->type, supported_hashes[i]))
break;
if(i == HASH_TYPES)
{
csum->next = csum_next->next;
free(csum_next);
}
else
csum=csum_next;
}
csum = file->checksums;
for (i = 0; i < HASH_TYPES; ++i)
if (!strcmp(csum->type, supported_hashes[i]))
break;
if(i == HASH_TYPES)
{
file->checksums = csum->next;
free(csum);
}
}
}
/* Free the space allocated for the whole mlink structure. */
void
delete_mlink(mlink *metalink)
{
mlink_file *file, *file_temp;
mlink_resource *res, *res_temp;
mlink_checksum *csum, *csum_temp;
mlink_piece_hash *phash, *phash_temp;
if(!metalink)
return;
xfree_null (metalink->tags);
xfree_null (metalink->identity);
file = metalink->files;
while (file)
{
xfree_null(file->os);
xfree_null(file->language);
xfree_null(file->version);
xfree_null(file->name);
res = file->resources;
while (res)
{
xfree_null (res->url);
xfree_null (res->type);
xfree_null (res->location);
res_temp = res;
res = res->next;
free (res_temp);
}
csum = file->checksums;
while (csum)
{
xfree_null (csum->type);
xfree_null (csum->hash);
csum_temp = csum;
csum = csum->next;
free (csum_temp);
}
if(file->chunk_checksum)
{
free (file->chunk_checksum->type);
phash = file->chunk_checksum->piece_hashes;
while (phash)
{
xfree_null (phash->hash);
phash_temp = phash;
phash = phash->next;
free (phash_temp);
}
}
file_temp = file;
file = file->next;
free (file_temp);
}
free (metalink);
}
/* Parses metalink into type metalink_t and returns a pointer to it.
Returns NULL if the parsing is failed. */
metalink_t*
metalink_context (const char *url)
{
metalink_error_t err;
metalink_t* metalink;
err = metalink_parse_file (url, &metalink);
if(err != 0)
metalink = NULL;
return metalink;
}
/* It should be taken into account that file hashes in metalink files may
include uppercase letter. This function turns the case of the first length
letters in the space pointed by hash into lowercase. */
static void
lower_hex_case (unsigned char *hash, int length)
{
int i;
/* 32 is the difference between the ascii codes of 'a' and 'A'. */
for(i = 0; i < length; ++i)
if('A' <= hash[i] && hash[i] <= 'Z')
hash[i] += 32;
}
/* Verifies file hash by comparing the file hashes found by gnulib functions
and hashes provided by metalink file. Works by comparing strongest supported
hash type available in the metalink file.
Returns;
-1 if hashes that were compared turned out to be different.
0 if all pairs of hashes compared turned out to be the same.
1 if due to some error, comparisons could not be made. */
int
verify_file_hash (const char *filename, mlink_checksum *checksums)
{
int i, j, req_type, res = 0;
unsigned char hash_raw[MAX_DIGEST_LENGTH];
/* Points to a hash of supported type from the metalink file. The index dedicated
to a type is inversely proportional to its strength. (check supported_types
to see the supported hash types listed in decreasing order of strength)*/
unsigned char *metalink_hashes[HASH_TYPES];
unsigned char file_hash[2 * MAX_DIGEST_LENGTH + 1];
FILE *file;
mlink_checksum *checksum;
if (!checksums)
{
/* Metalink file has no hashes for this file. */
logprintf (LOG_VERBOSE, "Validating(%s) failed: digest missing in metalink file.\n",
filename);
return 1;
}
for (i = 0; i < HASH_TYPES; ++i)
metalink_hashes[i] = NULL;
/* Fill metalink_hashes to contain an instance of supported types of hashes. */
for (checksum = checksums; checksum; checksum = checksum->next)
for (j = 0; j < HASH_TYPES; ++j)
if (!strcmp(checksum->type, supported_hashes[j]))
{
if(metalink_hashes[j])
{
/* As of libmetalin-0.03, it is not checked during parsing the
information in the metalink file whether there are multiple
hashes of same type for one file. That case should be checked,
as none of those hashes can be trusted above the other. */
logprintf (LOG_VERBOSE, "Validating(%s) failed: metalink file contains different hashes of same type.\n",
filename);
return 1;
}
else
metalink_hashes[j] = checksum->hash;
}
for (i = 0; !metalink_hashes[i]; ++i);
if (i == HASH_TYPES)
{
/* no hash of supported types could be found. */
logprintf (LOG_VERBOSE, "Validating(%s) failed: No hash of supported types could be found in metalink file.\n",
filename);
return 1;
}
req_type = i;
if (!(file = fopen(filename, "rb")))
{
/* File could not be opened. */
logprintf (LOG_VERBOSE, "Validating(%s) failed: file could not be opened.\n",
filename);
return 1;
}
res = (*hash_function[req_type]) (file, hash_raw);
fclose(file);
/* Find file hash accordingly. */
if (res)
{
logprintf (LOG_VERBOSE, "Validating(%s) failed: File hash could not be found.\n",
filename);
return 1;
}
/* Turn byte-form hash to hex form. */
for(j = 0 ; j < digest_sizes[req_type]; ++j)
sprintf(file_hash + 2 * j, "%02x", hash_raw[j]);
lower_hex_case(metalink_hashes[req_type], 2 * digest_sizes[req_type]);
if (strcmp(metalink_hashes[req_type], file_hash))
{
logprintf (LOG_VERBOSE, "Verifying(%s) failed: %s hashes are different.\n",
filename, supported_hashes[i]);
return -1;
}
logprintf (LOG_VERBOSE, "Verifying(%s): %s hashes are the same.\n",
filename, supported_hashes[i]);
return 0;
}

106
src/metalink.h Normal file
View File

@@ -0,0 +1,106 @@
/* Declarations for metalink.c.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
Inc.
This file is part of GNU Wget.
GNU Wget is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GNU Wget is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wget. If not, see <http://www.gnu.org/licenses/>.
Additional permission under GNU GPL version 3 section 7
If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
grants you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination
shall include the source code for the parts of OpenSSL used as well
as that of the covered work. */
#ifndef MLINK_H
#define MLINK_H
typedef struct metalink_piece_hash
{
struct metalink_piece_hash *next;
int piece;
char *hash;
} mlink_piece_hash;
typedef struct metalink_checksum
{
struct metalink_checksum *next;
char *type;
char *hash;
} mlink_checksum;
typedef struct metalink_resource
{
struct metalink_resource *next;
char *url;
char *type;
char *location;
int preference;
int maxconnections;
} mlink_resource;
typedef struct
{
char *type;
int length;
mlink_piece_hash *piece_hashes;
} mlink_chunk_checksum;
typedef struct metalink_file
{
struct metalink_file *next;
char *name;
long long int size;
char *version;
char *language;
char *os;
int maxconnections;
mlink_resource *resources;
int num_of_res;
mlink_checksum *checksums;
int num_of_checksums;
mlink_chunk_checksum *chunk_checksum;
} mlink_file;
typedef struct
{
char *identity;
char *tags;
mlink_file *files;
int num_of_files;
} mlink;
mlink *parse_metalink (char *);
void elect_resources (mlink *);
void elect_checksums (mlink *);
void delete_mlink (mlink *);
metalink_t *metalink_context (const char *);
int verify_file_hash (const char *, mlink_checksum *);
#endif /* MLINK_H */

239
src/multi.c Normal file
View File

@@ -0,0 +1,239 @@
/* Declarations for HTTP.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014 Free Software
Foundation, Inc.
This file is part of GNU Wget.
GNU Wget is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GNU Wget is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wget. If not, see <http://www.gnu.org/licenses/>.
Additional permission under GNU GPL version 3 section 7
If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
grants you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination
shall include the source code for the parts of OpenSSL used as well
as that of the covered work. */
#include "wget.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include "multi.h"
#include "url.h"
#include "exits.h"
static struct range *ranges;
char **files;
/* Allocate space for temporary file names. */
void
init_temp_files()
{
int i;
if(!(files = malloc (opt.jobs * (sizeof *files))))
{
logprintf (LOG_VERBOSE, "Space for temporary file data could not be allocated.\n");
exit (WGET_EXIT_GENERIC_ERROR);
}
for (i = 0; i < opt.jobs; ++i)
if(!(files[i] = malloc (L_tmpnam * sizeof(char))))
{
logprintf (LOG_VERBOSE, "Space for temporary file names could not be allocated.\n");
exit (WGET_EXIT_GENERIC_ERROR);
}
}
/* Assign names to temporary files to be used. */
void
name_temp_files()
{
int i;
for (i = 0; i < opt.jobs; ++i)
if(!tmpnam(files[i]))
{
logprintf (LOG_VERBOSE, "Temporary file name could not be assigned.\n");
exit (WGET_EXIT_GENERIC_ERROR);
}
}
/* Merge the temporary files in which the chunks are stored to form the
resulting file(output). */
void
merge_temp_files(char *output)
{
FILE *out, *in;
int j, ret;
void *buf = malloc (MIN_CHUNK_SIZE);
out = fopen (output, "wb");
for(j = 0; j < opt.jobs; ++j)
{
in = fopen(files[j],"rb");
ret = MIN_CHUNK_SIZE;
while(ret == MIN_CHUNK_SIZE)
{
ret = fread(buf, 1, MIN_CHUNK_SIZE, in);
fwrite(buf, 1, ret, out);
}
fclose(in);
}
fclose(out);
free(buf);
}
/* Delete the temporary files used. */
void
delete_temp_files()
{
int j = 0;
while(j < opt.jobs)
unlink(files[j++]);
}
/* Clean the space allocated for temporary files data. */
void
clean_temp_files()
{
int i;
for (i = 0; i < opt.jobs; ++i)
free (files[i]);
free(files);
}
/* Allocate ranges array to store the ranges data. */
void
init_ranges()
{
if(!(ranges = malloc (opt.jobs * (sizeof *ranges))))
{
logprintf (LOG_VERBOSE, "Space for ranges data could not be allocated.\n");
exit (WGET_EXIT_GENERIC_ERROR);
}
}
/* Assign values to the ranges.
Also allocates the resources array each struct range must have.
Returns the number of ranges to which values are assigned. */
int
fill_ranges_data(int num_of_resources, long long int file_size,
long int chunk_size)
{
int i, r;
i = 0;
do
{
ranges[i].first_byte = i * chunk_size;
ranges[i].last_byte = (i+1) * chunk_size - 1;
ranges[i].bytes_covered = ranges[i].is_assigned = 0;
ranges[i].resources = malloc(num_of_resources * sizeof(bool));
ranges[i].status_least_severe = RETROK;
for (r = 0; r < num_of_resources; ++r)
ranges[i].resources[r] = false;
++i;
} while (ranges[i-1].last_byte < (file_size - 1));
ranges[i-1].last_byte = file_size -1;
return i;
}
/* Free the resources array of each range allocated by fill_ranges_data(). */
void
clean_range_res_data()
{
int i;
for (i = 0; i < opt.jobs; ++i)
free (ranges[i].resources);
}
/* Free the ranges array that is used for storing ranges' data. */
void
clean_ranges()
{
free (ranges);
ranges = NULL;
}
/* Assign 'last minute' data to struct s_thread_ctx instances regarding their
usage and range information. Then create a thread using that instance. */
int
spawn_thread (struct s_thread_ctx *thread_ctx, int index, int resource)
{
static pthread_t thread;
thread_ctx[index].url_parsed = url_parse (thread_ctx[index].url,
&(thread_ctx[index].url_err), thread_ctx[index].i, true);
if(!thread_ctx[index].url_parsed)
return 1;
thread_ctx[index].file = files[index];
thread_ctx[index].range = ranges + index;
(thread_ctx[index].range)->is_assigned = 1;
(thread_ctx[index].range)->resources[resource] = true;
thread_ctx[index].used = 1;
thread_ctx[index].terminated = 0;
return pthread_create (&thread, NULL, segmented_retrieve_url, &thread_ctx[index]);
}
/* Collects the first thread to terminate and updates struct s_thread_ctx
instance's data regarding its 'business' (i.e. being used by a thread).
Returns the index of the struct s_thread_ctx instance that was used in the
terminating thread. */
int
collect_thread (sem_t *retr_sem, struct s_thread_ctx *thread_ctx)
{
int k, ret;
do
ret = sem_wait (retr_sem);
while (ret < 0 && errno == EINTR);
for (k = 0; k < opt.jobs; k++)
if (thread_ctx[k].used && thread_ctx[k].terminated)
{
url_free (thread_ctx[k].url_parsed);
thread_ctx[k].used = 0;
(thread_ctx[k].range)->is_assigned = 0;
return k;
}
}
/* The function which is being called by pthread_create in spawn_thread(). It
is used to call retrieve_url(), which requires many arguments. */
static void *
segmented_retrieve_url (void *arg)
{
struct s_thread_ctx *ctx = (struct s_thread_ctx *) arg;
ctx->status = retrieve_url (ctx->url_parsed, ctx->url,
&ctx->file, &ctx->redirected,
ctx->referer, &ctx->dt,
false, ctx->i, true, ctx->range);
ctx->terminated = 1;
sem_post (ctx->retr_sem);
}

89
src/multi.h Normal file
View File

@@ -0,0 +1,89 @@
/* Declarations for HTTP.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software
Foundation, Inc.
This file is part of GNU Wget.
GNU Wget is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
GNU Wget is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wget. If not, see <http://www.gnu.org/licenses/>.
Additional permission under GNU GPL version 3 section 7
If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
grants you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination
shall include the source code for the parts of OpenSSL used as well
as that of the covered work. */
#ifndef MULTI_H
#define MULTI_H
#include <semaphore.h>
#include "wget.h"
#include "iri.h"
#include "url.h"
#define MIN_CHUNK_SIZE 2048
struct s_thread_ctx
{
pthread_t thread;
int used;
int terminated;
int dt, url_err;
char *redirected;
char *referer;
struct url *url_parsed;
struct iri *i;
struct range *range;
char *file;
char *url;
#ifdef ENABLE_THREADS
sem_t *retr_sem;
#else
/* Not used. */
void *retr_sem;
#endif
uerr_t status;
};
void init_temp_files();
void name_temp_files();
void merge_temp_files(char *);
void delete_temp_files();
void clean_temp_files();
void init_ranges();
int fill_ranges_data(int, long long int, long int);
void clean_range_res_data();
void clean_ranges();
int spawn_thread (struct s_thread_ctx*, int, int);
int collect_thread (sem_t *, struct s_thread_ctx *);
static void * segmented_retrieve_url (void *);
#endif /* MULTI_H */

View File

@@ -35,6 +35,11 @@ struct options
hence not boolean.) */
bool quiet; /* Are we quiet? */
int ntry; /* Number of tries per URL */
#ifdef ENABLE_METALINK
int n_retries; /* Number of tries per file */
#endif
char *metalink_file; /* Metalink filename */
bool retry_connrefused; /* Treat CONNREFUSED as non-fatal. */
bool background; /* Whether we should work in background. */
bool ignore_length; /* Do we heed content-length at all? */
@@ -285,6 +290,8 @@ struct options
bool show_all_dns_entries; /* Show all the DNS entries when resolving a
name. */
bool report_bps; /*Output bandwidth in bits format*/
int jobs; /* How many threads use at the same time. */
};
extern struct options opt;

View File

@@ -36,18 +36,24 @@ as that of the covered work. */
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <wchar.h>
#ifdef ENABLE_THREADS
#include <pthread.h>
#endif
#include "progress.h"
#include "utils.h"
#include "retr.h"
#include "ptimer.h"
struct progress_implementation {
const char *name;
bool interactive;
void *(*create) (const char *, wgint, wgint);
void (*update) (void *, wgint, double);
void (*draw) (void *);
void (*draw) (void *, bool);
void (*finish) (void *, double);
void (*set_params) (char *);
};
@@ -57,15 +63,33 @@ struct progress_implementation {
static void *dot_create (const char *, wgint, wgint);
static void dot_update (void *, wgint, double);
static void dot_finish (void *, double);
static void dot_draw (void *);
static void dot_draw (void *, bool);
static void dot_set_params (char *);
static void *bar_create (const char *, wgint, wgint);
static void bar_update (void *, wgint, double);
static void bar_draw (void *);
static void bar_draw (void *, bool);
static void bar_finish (void *, double);
static void bar_set_params (char *);
struct progress_header
{
struct progress_header *next;
};
static struct progress_header *progress_list = NULL;
static struct progress_header *current_progress = NULL;
#ifdef ENABLE_THREADS
static pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER;
# define LOCK_PROGRESS() pthread_mutex_lock (&progress_mutex);
# define UNLOCK_PROGRESS() pthread_mutex_unlock (&progress_mutex);
#else
# define LOCK_PROGRESS()
# define UNLOCK_PROGRESS()
#endif
static struct progress_implementation implementations[] = {
{ "dot", 0, dot_create, dot_update, dot_draw, dot_finish, dot_set_params },
{ "bar", 1, bar_create, bar_update, bar_draw, bar_finish, bar_set_params }
@@ -86,6 +110,37 @@ static int current_impl_locked;
#define FALLBACK_PROGRESS_IMPLEMENTATION "dot"
/* Time between screen refreshes will not be shorter than this, so
that Wget doesn't swamp the TTY with output. */
#define REFRESH_INTERVAL 0.2
/* Time between screen refreshes the file to show when there are multiple
downloads at the same time. */
#define REFRESH_SWITCH_FILE 1.5
/* Assumed screen width if we can't find the real value. */
#define DEFAULT_SCREEN_WIDTH 80
/* Minimum screen width we'll try to work with. If this is too small,
create_image will overflow the buffer. */
#define MINIMUM_SCREEN_WIDTH 45
/* The last known screen width. This can be updated by the code that
detects that SIGWINCH was received (but it's never updated from the
signal handler). */
static int screen_width;
/* A flag that, when set, means SIGWINCH was received. */
static volatile sig_atomic_t received_sigwinch;
static int bp_width; /* screen width we're using at the
time the progress gauge was
created. this is different from
the screen_width global variable in
that the latter can be changed by a
signal. */
/* Return true if NAME names a valid progress bar implementation. The
characters after the first : will be ignored. */
@@ -155,6 +210,7 @@ void *
progress_create (const char *f_download, wgint initial, wgint total)
{
/* Check if the log status has changed under our feet. */
struct progress_header *ret;
if (output_redirected)
{
if (!current_impl_locked)
@@ -162,7 +218,17 @@ progress_create (const char *f_download, wgint initial, wgint total)
output_redirected = 0;
}
return current_impl->create (f_download, initial, total);
ret = current_impl->create (f_download, initial, total);
if (ret)
{
LOCK_PROGRESS ();
ret->next = progress_list;
progress_list = ret;
UNLOCK_PROGRESS ();
}
return ret;
}
/* Return true if the progress gauge is "interactive", i.e. if it can
@@ -182,8 +248,50 @@ progress_interactive_p (void *progress _GL_UNUSED)
void
progress_update (void *progress, wgint howmuch, double dltime)
{
static struct ptimer *last_draw = NULL;
static struct ptimer *last_switch = NULL;
bool force_screen_update = false;
current_impl->update (progress, howmuch, dltime);
current_impl->draw (progress);
LOCK_PROGRESS ();
if (last_draw == NULL)
last_draw = ptimer_new ();
if (last_switch == NULL)
last_switch = ptimer_new ();
/* If SIGWINCH (the window size change signal) been received,
determine the new screen size and update the screen. */
if (received_sigwinch)
{
int old_width = screen_width;
screen_width = determine_screen_width ();
if (!screen_width)
screen_width = DEFAULT_SCREEN_WIDTH;
else if (screen_width < MINIMUM_SCREEN_WIDTH)
screen_width = MINIMUM_SCREEN_WIDTH;
if (screen_width != old_width)
force_screen_update = true;
received_sigwinch = 0;
}
if (ptimer_measure (last_draw) >= REFRESH_INTERVAL || force_screen_update)
{
if (current_progress == NULL)
current_progress = progress_list;
bp_width = screen_width - 1;
current_impl->draw (current_progress, force_screen_update);
ptimer_reset (last_draw);
if (ptimer_measure (last_switch) >= REFRESH_SWITCH_FILE)
{
ptimer_reset (last_switch);
current_progress = current_progress->next;
}
}
UNLOCK_PROGRESS ();
}
/* Tell the progress gauge to clean up. Calling this will free the
@@ -192,12 +300,38 @@ progress_update (void *progress, wgint howmuch, double dltime)
void
progress_finish (void *progress, double dltime)
{
struct progress_header *header = progress;
{
struct progress_header *it, *prev = NULL;
LOCK_PROGRESS ();
for (it = progress_list; it; it = it->next)
{
if (it == progress)
{
if (current_progress == progress)
current_progress = it->next;
if (it == progress_list)
progress_list = progress_list->next;
else
prev->next = it->next;
break;
}
prev = it;
}
UNLOCK_PROGRESS ();
}
current_impl->finish (progress, dltime);
}
/* Dot-printing. */
struct dot_progress {
struct progress_header header;
wgint initial_length; /* how many bytes have been downloaded
previously. */
wgint total_length; /* expected total byte count when the
@@ -352,12 +486,16 @@ dot_update (void *progress, wgint howmuch, double dltime)
}
static void
dot_draw (void *progress)
dot_draw (void *progress, bool force)
{
struct dot_progress *dp = progress;
int dot_bytes = opt.dot_bytes;
wgint ROW_BYTES = opt.dot_bytes * opt.dots_in_line;
/* FIXME: support threads. */
if (opt.jobs > 1)
return;
log_set_flush (false);
for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes)
@@ -467,21 +605,6 @@ dot_set_params (char *params)
/* "Thermometer" (bar) progress. */
/* Assumed screen width if we can't find the real value. */
#define DEFAULT_SCREEN_WIDTH 80
/* Minimum screen width we'll try to work with. If this is too small,
create_image will overflow the buffer. */
#define MINIMUM_SCREEN_WIDTH 45
/* The last known screen width. This can be updated by the code that
detects that SIGWINCH was received (but it's never updated from the
signal handler). */
static int screen_width;
/* A flag that, when set, means SIGWINCH was received. */
static volatile sig_atomic_t received_sigwinch;
/* Size of the download speed history ring. */
#define DLSPEED_HISTORY_SIZE 20
@@ -496,15 +619,12 @@ static volatile sig_atomic_t received_sigwinch;
download speeds are scratched. */
#define STALL_START_TIME 5
/* Time between screen refreshes will not be shorter than this, so
that Wget doesn't swamp the TTY with output. */
#define REFRESH_INTERVAL 0.2
/* Don't refresh the ETA too often to avoid jerkiness in predictions.
This allows ETA to change approximately once per second. */
#define ETA_REFRESH_INTERVAL 0.99
struct bar_progress {
struct progress_header header;
const char *f_download; /* Filename of the downloaded file */
wgint initial_length; /* how many bytes have been downloaded
previously. */
@@ -512,19 +632,8 @@ struct bar_progress {
download finishes */
wgint count; /* bytes downloaded so far */
double last_screen_update; /* time of the last screen update,
measured since the beginning of
download. */
double dltime; /* download time so far */
int width; /* screen width we're using at the
time the progress gauge was
created. this is different from
the screen_width global variable in
that the latter can be changed by a
signal. */
char *buffer; /* buffer where the bar "image" is
stored. */
int tick; /* counter used for drawing the
progress bar where the total size
is not known. */
@@ -559,7 +668,7 @@ struct bar_progress {
int last_eta_value;
};
static void create_image (struct bar_progress *, double, bool);
static void create_image (struct bar_progress *, char *buffer, double, bool);
static void display_image (char *);
static void *
@@ -589,15 +698,11 @@ bar_create (const char *f_download, wgint initial, wgint total)
}
/* - 1 because we don't want to use the last screen column. */
bp->width = screen_width - 1;
/* + enough space for the terminating zero, and hopefully enough room
* for multibyte characters. */
bp->buffer = xmalloc (bp->width + 100);
bp_width = screen_width - 1;
logputs (LOG_VERBOSE, "\n");
create_image (bp, 0, false);
display_image (bp->buffer);
bar_draw (bp, false);
return bp;
}
@@ -624,37 +729,20 @@ bar_update (void *progress, wgint howmuch, double dltime)
}
static void
bar_draw (void *progress)
bar_draw (void *progress, bool force)
{
bool force_screen_update = false;
struct bar_progress *bp = progress;
static char *buffer = NULL;
/* If SIGWINCH (the window size change signal) been received,
determine the new screen size and update the screen. */
if (received_sigwinch)
if (buffer == NULL)
buffer = xmalloc (bp_width + 100);
if (force)
{
int old_width = screen_width;
screen_width = determine_screen_width ();
if (!screen_width)
screen_width = DEFAULT_SCREEN_WIDTH;
else if (screen_width < MINIMUM_SCREEN_WIDTH)
screen_width = MINIMUM_SCREEN_WIDTH;
if (screen_width != old_width)
{
bp->width = screen_width - 1;
bp->buffer = xrealloc (bp->buffer, bp->width + 100);
force_screen_update = true;
}
received_sigwinch = 0;
buffer = xrealloc (buffer, bp_width + 100);
}
if (bp->dltime - bp->last_screen_update < REFRESH_INTERVAL && !force_screen_update)
/* Don't update more often than five times per second. */
return;
create_image (bp, bp->dltime, false);
display_image (bp->buffer);
bp->last_screen_update = bp->dltime;
create_image (bp, buffer, bp->dltime, false);
display_image (buffer);
}
static void
@@ -667,13 +755,11 @@ bar_finish (void *progress, double dltime)
/* See bar_update() for explanation. */
bp->total_length = bp->initial_length + bp->count;
create_image (bp, dltime, true);
display_image (bp->buffer);
bar_draw (bp, false);
logputs (LOG_VERBOSE, "\n");
logputs (LOG_PROGRESS, "\n");
xfree (bp->buffer);
xfree (bp);
}
@@ -871,10 +957,10 @@ get_eta (int *bcd)
#endif
static void
create_image (struct bar_progress *bp, double dl_total_time, bool done)
create_image (struct bar_progress *bp, char *buffer, double dl_total_time, bool done)
{
const int MAX_FILENAME_LEN = bp->width / 4;
char *p = bp->buffer;
const int MAX_FILENAME_LEN = bp_width / 4;
char *p = buffer;
wgint size = bp->initial_length + bp->count;
const char *size_grouped = with_thousand_seps (size);
@@ -898,6 +984,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
"file " - Downloaded filename - MAX_FILENAME_LEN chars + 1
"xx% " or "100%" - percentage - 4 chars
" url " - string - MAX MAX_URL_LEN chars + 2
"[]" - progress bar decorations - 2 chars
" nnn.nnK" - downloaded bytes - 7 chars + 1
" 12.5KB/s" - download rate - 8 chars + 1
@@ -913,7 +1000,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
#define PROGRESS_DWNLOAD_RATE 8 + 1
#define PROGRESS_ETA_LEN 14
int progress_size = bp->width - (PROGRESS_FILENAME_LEN + PROGRESS_PERCENT_LEN +
int progress_size = bp_width - (PROGRESS_FILENAME_LEN + PROGRESS_PERCENT_LEN +
PROGRESS_DECORAT_LEN + PROGRESS_FILESIZE_LEN +
PROGRESS_DWNLOAD_RATE + PROGRESS_ETA_LEN);
@@ -1018,8 +1105,8 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
}
*p++ = ']';
++bp->tick;
}
++bp->tick;
/* " 234.56M" */
const char * down_size = human_readable (size, 1000, 2);
@@ -1122,7 +1209,7 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
move_to_end (p);
}
while (p - bp->buffer - bytes_cols_diff - size_grouped_diff < bp->width)
while (p - buffer - bytes_cols_diff - size_grouped_diff < bp_width)
*p++ = ' ';
*p = '\0';
}

View File

@@ -37,6 +37,12 @@ as that of the covered work. */
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#ifdef ENABLE_THREADS
#include <pthread.h>
#include <semaphore.h>
#endif
#include "multi.h"
#include "url.h"
#include "recur.h"
@@ -165,6 +171,27 @@ static bool download_child_p (const struct urlpos *, struct url *, int,
static bool descend_redirect_p (const char *, struct url *, int,
struct url *, struct hash_table *, struct iri *);
#if !ENABLE_THREADS
# define THREAD_JOIN(...) (0)
# define SEM_INIT(...) (0)
# define SEM_WAIT(...) (0)
#else
# define THREAD_JOIN pthread_join
# define SEM_INIT sem_init
# define SEM_WAIT sem_wait
static void *
start_retrieve_url (void *arg)
{
struct s_thread_ctx *ctx = (struct s_thread_ctx *) arg;
ctx->status = retrieve_url (ctx->url_parsed, ctx->url,
&ctx->file, &ctx->redirected,
ctx->referer, &ctx->dt,
false, ctx->i, true, NULL);
ctx->terminated = 1;
sem_post (ctx->retr_sem);
}
#endif
/* Retrieve a part of the web beginning with START_URL. This used to
be called "recursive retrieval", because the old function was
@@ -191,6 +218,21 @@ uerr_t
retrieve_tree (struct url *start_url_parsed, struct iri *pi)
{
uerr_t status = RETROK;
struct s_thread_ctx *thread_ctx;
char *next_url = NULL, *next_referer;
int next_depth;
bool next_html_allowed, next_css_allowed;
struct iri *next_i = NULL;
#ifdef ENABLE_THREADS
const int N_THREADS = opt.jobs > 0 ? opt.jobs : 1;
sem_t retr_sem;
#else
const int N_THREADS = 1;
void *retr_sem;
#endif
int free_threads = N_THREADS;
/* The queue of URLs we need to load. */
struct url_queue *queue;
@@ -213,6 +255,11 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
set_uri_encoding (i, opt.locale, true);
#undef COPYSTR
thread_ctx = calloc (N_THREADS, sizeof *thread_ctx);
/* FIXME: CHECK FOR ERRORS. */
SEM_INIT (&retr_sem, 0, 0);
queue = url_queue_new ();
blacklist = make_string_hash_table (0);
@@ -225,11 +272,14 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
while (1)
{
bool descend = false;
char *url, *referer, *file = NULL;
int depth;
bool html_allowed, css_allowed;
char *file = NULL;
bool is_css = false;
bool dash_p_leaf_HTML = false;
char *url = NULL, *referer;
int depth;
bool html_allowed, css_allowed;
bool dequed = false;
int index = 0;
if (opt.quota && total_downloaded_bytes > opt.quota)
break;
@@ -238,10 +288,20 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
/* Get the next URL from the queue... */
if (!url_dequeue (queue, (struct iri **) &i,
(const char **)&url, (const char **)&referer,
&depth, &html_allowed, &css_allowed))
break;
if (next_url == NULL)
{
if (url_dequeue (queue, (struct iri **) &next_i,
(const char **)&next_url, (const char **)&next_referer,
&next_depth, &next_html_allowed, &next_css_allowed))
dequed = true;
}
i = next_i;
url = next_url;
referer = next_referer;
depth = next_depth;
html_allowed = next_html_allowed;
css_allowed = next_css_allowed;
/* ...and download it. Note that this download is in most cases
unconditional, as download_child_p already makes sure a file
@@ -251,7 +311,7 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
and again under URL2, but at a different (possibly smaller)
depth, we want the URL's children to be taken into account
the second time. */
if (dl_url_file_map && hash_table_contains (dl_url_file_map, url))
if (dequed && url && dl_url_file_map && hash_table_contains (dl_url_file_map, url))
{
bool is_css_bool;
@@ -273,15 +333,110 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
}
else
{
int dt = 0, url_err;
char *redirected = NULL;
struct url *url_parsed = url_parse (url, &url_err, i, true);
int j;
retry:
if (! url)
{
int used = 0;
for (j = 0; j < N_THREADS; j++)
{
if (thread_ctx[j].used)
{
used = 1;
break;
}
}
status = retrieve_url (url_parsed, url, &file, &redirected, referer,
&dt, false, i, true);
if (! used)
break;
}
if (url && free_threads)
{
int err;
for (j = 0; j < N_THREADS; j++)
if (! thread_ctx[j].used)
{
index = j;
free_threads--;
thread_ctx[j].used = 1;
thread_ctx[j].terminated = 0;
break;
}
assert (j < N_THREADS);
thread_ctx[index].file = file;
thread_ctx[index].referer = referer;
thread_ctx[index].dt = 0;
thread_ctx[index].i = i;
thread_ctx[index].redirected = NULL;
thread_ctx[index].range = NULL;
thread_ctx[index].url = url;
thread_ctx[index].retr_sem = &retr_sem;
thread_ctx[index].url_parsed = url_parse (thread_ctx[index].url,
&thread_ctx[index].url_err,
i, true);
#ifdef ENABLE_THREADS
err = pthread_create (&thread_ctx[index].thread, NULL,
start_retrieve_url, &thread_ctx[index]);
#else
thread_ctx[index].status = retrieve_url (thread_ctx[index].url_parsed,
thread_ctx[index].url,
&thread_ctx[index].file,
&thread_ctx[index].redirected,
thread_ctx[index].referer,
&thread_ctx[index].dt,
false, i, true,
NULL);
thread_ctx[index].used = 1;
thread_ctx[index].terminated = 1;
err = 0;
#endif
if (err == 0)
next_url = NULL;
else
{
logprintf (LOG_NOTQUIET, "pthread_create: %s\n", strerror (errno));
url_free (thread_ctx[index].url_parsed);
thread_ctx[index].used = 0;
free_threads++;
return THREADS_ERR;
}
continue;
}
index = -1;
for (j = 0; j < N_THREADS; j++)
if (thread_ctx[j].used && thread_ctx[j].terminated)
{
index = j;
thread_ctx[j].used = 0;
THREAD_JOIN (thread_ctx[j].thread, NULL);
free_threads++;
break;
}
if (index < 0)
{
int ret;
do
ret = SEM_WAIT (&retr_sem);
while (ret < 0 && errno == EINTR);
if (ret < 0)
return SEM_ERR;
goto retry;
}
file = thread_ctx[index].file;
referer = thread_ctx[index].referer;
i = thread_ctx[index].i;
url = thread_ctx[index].url;
if (html_allowed && file && status == RETROK
&& (dt & RETROKF) && (dt & TEXTHTML))
&& (thread_ctx[index].dt & RETROKF) && (thread_ctx[index].dt & TEXTHTML))
{
descend = true;
is_css = false;
@@ -291,21 +446,23 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
lots of web servers serve css with an incorrect content type
*/
if (file && status == RETROK
&& (dt & RETROKF) &&
((dt & TEXTCSS) || css_allowed))
&& (thread_ctx[index].dt & RETROKF) &&
((thread_ctx[index].dt & TEXTCSS) || css_allowed)
)
{
descend = true;
is_css = true;
}
if (redirected)
if (thread_ctx[index].redirected)
{
/* We have been redirected, possibly to another host, or
different path, or wherever. Check whether we really
want to follow it. */
if (descend)
{
if (!descend_redirect_p (redirected, url_parsed, depth,
if (!descend_redirect_p (thread_ctx[index].redirected,
thread_ctx[index].url_parsed, depth,
start_url_parsed, blacklist, i))
descend = false;
else
@@ -314,15 +471,15 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
string_set_add (blacklist, url);
}
xfree (url);
url = redirected;
xfree (thread_ctx[index].url);
url = thread_ctx[index].redirected;
}
else
{
xfree (url);
url = xstrdup (url_parsed->url);
xfree (thread_ctx[index].url);
url = xstrdup (thread_ctx[index].url_parsed->url);
}
url_free(url_parsed);
url_free(thread_ctx[index].url_parsed);
}
if (opt.spider)
@@ -438,11 +595,12 @@ retrieve_tree (struct url *start_url_parsed, struct iri *pi)
logputs (LOG_VERBOSE, "\n");
register_delete_file (file);
}
#ifndef ENABLE_THREADS
xfree (url);
xfree_null (referer);
xfree_null (file);
iri_free (i);
#endif
}
/* If anything is left of the queue due to a premature exit, free it

View File

@@ -563,7 +563,7 @@ res_retrieve_file (const char *url, char **file, struct iri *iri)
else
{
err = retrieve_url (url_parsed, robots_url, file, NULL, NULL, NULL,
false, i, false);
false, i, false, NULL);
url_free(url_parsed);
}

View File

@@ -37,10 +37,22 @@ as that of the covered work. */
#include <errno.h>
#include <string.h>
#include <assert.h>
#ifdef ENABLE_THREADS
#include <pthread.h>
#include <semaphore.h>
#endif
#ifdef ENABLE_METALINK
#include <metalink/metalink_parser.h>
#include <metalink/metalink_types.h>
#ifdef VMS
# include <unixio.h> /* For delete(). */
#endif
#include "metalink.h"
#endif
#ifdef ENABLE_THREADS
#include "multi.h"
#endif
#include "exits.h"
#include "utils.h"
#include "retr.h"
@@ -57,6 +69,17 @@ as that of the covered work. */
#include "html-url.h"
#include "iri.h"
#ifdef ENABLE_METALINK
static pthread_mutex_t pconn_mutex = PTHREAD_MUTEX_INITIALIZER;
#define IS_IO_ERROR(status) status == FOPENERR || status == WRITEFAILED || \
status == UNLINKERR || status == FWRITEERR || status == FOPEN_EXCL_ERR
#define PCONN_LOCK() pthread_mutex_lock (&pconn_mutex)
#define PCONN_UNLOCK() pthread_mutex_unlock (&pconn_mutex)
#endif
/* Total size of downloaded files. Used to enforce quota. */
SUM_SIZE_INT total_downloaded_bytes;
@@ -227,7 +250,6 @@ write_data (FILE *out, FILE *out2, const char *buf, int bufsize,
int
fd_read_body (const char *downloaded_filename, int fd, FILE *out, wgint toread, wgint startpos,
wgint *qtyread, wgint *qtywritten, double *elapsed, int flags,
FILE *out2)
{
@@ -712,7 +734,7 @@ static char *getproxy (struct url *);
uerr_t
retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
char **newloc, const char *refurl, int *dt, bool recursive,
struct iri *iri, bool register_status)
struct iri *iri, bool register_status, struct range *segment_range)
{
uerr_t result;
char *url;
@@ -739,8 +761,13 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
url = xstrdup (origurl);
if (newloc)
*newloc = NULL;
#ifndef ENABLE_METALINK
/* Note that, each and every call to retrieve_url(), except the ones made by
functions relevant to metalink support, the value of *file is NULL. */
if (file)
*file = NULL;
#endif
if (!refurl)
refurl = opt.referer;
@@ -750,7 +777,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
result = NOCONERROR;
mynewloc = NULL;
local_file = NULL;
local_file = *file;
proxy_url = NULL;
proxy = getproxy (u);
@@ -792,7 +819,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
|| (proxy_url && proxy_url->scheme == SCHEME_HTTP))
{
result = http_loop (u, orig_parsed, &mynewloc, &local_file, refurl, dt,
proxy_url, iri);
proxy_url, iri, segment_range);
}
else if (u->scheme == SCHEME_FTP)
{
@@ -803,7 +830,7 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
if (redirection_count)
oldrec = glob = false;
result = ftp_loop (u, &local_file, dt, proxy_url, recursive, glob);
result = ftp_loop (u, &local_file, dt, proxy_url, recursive, glob, segment_range);
recursive = oldrec;
/* There is a possibility of having HTTP being redirected to
@@ -942,10 +969,10 @@ retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
register_redirection (origurl, u->url);
if (*dt & TEXTHTML)
register_html (local_file);
register_html ("",local_file);
if (*dt & TEXTCSS)
register_css (local_file);
register_css ("",local_file);
}
if (file)
@@ -1019,7 +1046,7 @@ retrieve_from_file (const char *file, bool html, int *count)
opt.base_href = xstrdup (url);
status = retrieve_url (url_parsed, url, &url_file, NULL, NULL, &dt,
false, iri, true);
false, iri, true, NULL);
url_free (url_parsed);
if (!url_file || (status != RETROK))
@@ -1043,71 +1070,302 @@ retrieve_from_file (const char *file, bool html, int *count)
else
input_file = (char *) file;
url_list = (html ? get_urls_html (input_file, NULL, NULL, iri)
: get_urls_file (input_file));
#ifdef ENABLE_METALINK
mlink *mlink = parse_metalink(input_file);
xfree_null (url_file);
for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
if(opt.metalink_file && mlink)
{
char *filename = NULL, *new_file = NULL;
int dt;
struct iri *tmpiri = iri_dup (iri);
struct url *parsed_url = NULL;
int i, j, r, ranges_covered, chunk_size, url_err, retries, ret, dt=0;
pthread_t thread;
sem_t retr_sem;
uerr_t status;
mlink_file* file;
mlink_resource *resource;
struct s_thread_ctx *thread_ctx;
if (cur_url->ignore_when_downloading)
continue;
/* Wget supports HTTP&FTP, and Metalink supports MD5, SHA1 & SHA-256. */
elect_resources (mlink);
elect_checksums (mlink);
if (opt.quota && total_downloaded_bytes > opt.quota)
init_temp_files();
init_ranges ();
thread_ctx = malloc (opt.jobs * (sizeof *thread_ctx));
retries = 0;
file = mlink->files;
while (file)
{
status = QUOTEXC;
break;
memset (thread_ctx, '\0', opt.jobs * (sizeof *thread_ctx));
/* If chunk_size is too small, set it equal to MIN_CHUNK_SIZE. */
chunk_size = (file->size) / opt.jobs;
if(chunk_size < MIN_CHUNK_SIZE)
chunk_size = MIN_CHUNK_SIZE;
j = fill_ranges_data (file->num_of_res, file->size, chunk_size);
/* If chunk_size was set to MIN_CHUNK_SIZE, opt.jobs should be corrected. */
if (j < opt.jobs)
opt.jobs = j;
name_temp_files ();
sem_init (&retr_sem, 0, 0);
j = ranges_covered = 0;
resource = file->resources;
/* Assign values to thread_ctx[] elements and spawn threads that will
conduct the download. */
for (r = 0; r < opt.jobs; ++r)
{
if (!resource)
{
j = 0;
resource = file->resources;
}
thread_ctx[r].referer = NULL;
thread_ctx[r].redirected = NULL;
thread_ctx[r].dt = dt;
thread_ctx[r].i = iri;
thread_ctx[r].url = resource->url;
thread_ctx[r].retr_sem = &retr_sem;
ret = spawn_thread (thread_ctx, r, j);
if (ret)
{
/* If thread creation is unsuccessful */
char *error = url_error (thread_ctx[r].url, thread_ctx[r].url_err);
logprintf (LOG_NOTQUIET, "%s: %s.\n", thread_ctx[r].url, error);
xfree (error);
free (thread_ctx);
clean_range_res_data ();
clean_ranges ();
clean_temp_files ();
return URLERROR;
}
++j;
resource = resource->next;
}
/* Until all the ranges are covered, collect threads. */
while (ranges_covered < opt.jobs)
{
r = collect_thread (&retr_sem, thread_ctx);
++ranges_covered;
status = thread_ctx[r].status;
/* Check return status of thread for errors. */
if (IS_IO_ERROR (status))
{
/* The error is of type WGET_EXIT_IO_FAIL given in exits.c.
No fallbacking is needed for this type of error. */
inform_exit_status (status);
break;
}
else if(status != RETROK)
{
int error_severity;
PCONN_LOCK ();
/* Pick the least severe error.*/
error_severity = get_exit_status();
inform_exit_status ((thread_ctx[r].range)->status_least_severe);
if(get_exit_status() != error_severity)
(thread_ctx[r].range)->status_least_severe = status;
PCONN_UNLOCK ();
/* Look for resource from which downloading this range is not
tried. */
j = 0;
resource = file->resources;
while (j < file->num_of_res)
{
if (!((thread_ctx[r].range)->resources)[j])
break;
++j;
resource = resource -> next;
}
/* If there is such a resource, then update the range values
to try that not-tried resource and spawn thread.
If all the resources are exhausted, stop collecting the
threads, as the download failed. */
if (j < file->num_of_res)
{
if ((thread_ctx[r].range)->bytes_covered)
{
thread_ctx[r].url = resource->url;
(thread_ctx[r].range)->first_byte =
(thread_ctx[r].range)->bytes_covered;
(thread_ctx[r].range)->bytes_covered = 0;
}
--ranges_covered;
ret = spawn_thread (thread_ctx, r, j);
if (ret)
{
/* If thread creation is unsuccessful */
char *error = url_error (thread_ctx[r].url, thread_ctx[r].url_err);
logprintf (LOG_NOTQUIET, "%s: %s.\n", thread_ctx[r].url, error);
xfree (error);
free (thread_ctx);
clean_range_res_data ();
clean_ranges ();
clean_temp_files ();
return URLERROR;
}
}
else
break;
}
}
sem_destroy(&retr_sem);
/* Check the download status. If conditions are suitable, retry. */
if (status != RETROK)
{
logprintf (LOG_VERBOSE, _("Downloading %s failed. Chunk %d could "
"not be downloaded from any of the "
"URLs listed in metalink file.\n"),
file->name, r);
/* Failed downloads should only be retried if the error causing
the failure is not an IO error. */
if (!(IS_IO_ERROR((thread_ctx[r].range)->status_least_severe)))
{
if(retries < opt.n_retries)
{
logprintf (LOG_VERBOSE,
_("Retrying to download(%s). (TRY #%d)\n"),
file->name, ++retries + 1);
continue;
}
}
}
else
{
char *file_path;
int res;
/* Form the actual file to be downloaded and verify hash. */
file_path = malloc((opt.dir_prefix ? strlen(opt.dir_prefix) : 0)
+ strlen(file->name) + (sizeof "/"));
if(opt.dir_prefix)
sprintf(file_path, "%s/%s", opt.dir_prefix, file->name);
else
sprintf(file_path, "%s", file->name);
mkalldirs(file_path);
merge_temp_files(file_path);
res = verify_file_hash(file_path, file->checksums);
free(file_path);
if(!res)
{
++*count;
logprintf (LOG_VERBOSE, _("Verifying(%s) succeeded.\n"),
file->name);
}
else if(res < 0)
{
logprintf (LOG_VERBOSE, _("Verifying(%s) failed.\n"),
file->name);
if(retries < opt.n_retries)
{
logprintf (LOG_VERBOSE,
_("Retrying to download(%s). (TRY #%d)\n"),
file->name, ++retries + 1);
continue;
}
}
}
delete_temp_files();
clean_range_res_data();
if (opt.quota && total_downloaded_bytes > opt.quota)
{
status = QUOTEXC;
break;
}
file = file->next;
}
parsed_url = url_parse (cur_url->url->url, NULL, tmpiri, true);
free(thread_ctx);
clean_ranges ();
clean_temp_files ();
delete_mlink(mlink);
}
else
{
#endif
url_list = (html ? get_urls_html (input_file, NULL, NULL, iri)
: get_urls_file (input_file));
char *proxy = getproxy (cur_url->url);
if ((opt.recursive || opt.page_requisites)
&& (cur_url->url->scheme != SCHEME_FTP || proxy))
xfree_null (url_file);
for (cur_url = url_list; cur_url; cur_url = cur_url->next, ++*count)
{
int old_follow_ftp = opt.follow_ftp;
char *filename = NULL, *new_file = NULL;
int dt;
struct iri *tmpiri = iri_dup (iri);
struct url *parsed_url = NULL;
/* Turn opt.follow_ftp on in case of recursive FTP retrieval */
if (cur_url->url->scheme == SCHEME_FTP)
opt.follow_ftp = 1;
if (cur_url->ignore_when_downloading)
continue;
status = retrieve_tree (parsed_url ? parsed_url : cur_url->url,
if (opt.quota && total_downloaded_bytes > opt.quota)
{
status = QUOTEXC;
break;
}
parsed_url = url_parse (cur_url->url->url, NULL, tmpiri, true);
char *proxy = getproxy (cur_url->url);
if ((opt.recursive || opt.page_requisites)
&& (cur_url->url->scheme != SCHEME_FTP || proxy))
{
int old_follow_ftp = opt.follow_ftp;
/* Turn opt.follow_ftp on in case of recursive FTP retrieval */
if (cur_url->url->scheme == SCHEME_FTP)
opt.follow_ftp = 1;
status = retrieve_tree (parsed_url ? parsed_url : cur_url->url,
tmpiri);
opt.follow_ftp = old_follow_ftp;
}
else
status = retrieve_url (parsed_url ? parsed_url : cur_url->url,
cur_url->url->url, &filename,
&new_file, NULL, &dt, opt.recursive, tmpiri,
true);
free(proxy);
opt.follow_ftp = old_follow_ftp;
}
else
status = retrieve_url (parsed_url ? parsed_url : cur_url->url,
cur_url->url->url, &filename,
&new_file, NULL, &dt, opt.recursive, tmpiri,
true, NULL);
free(proxy);
if (parsed_url)
url_free (parsed_url);
if (parsed_url)
url_free (parsed_url);
if (filename && opt.delete_after && file_exists_p (filename))
{
DEBUGP (("\
if (filename && opt.delete_after && file_exists_p (filename))
{
DEBUGP (("\
Removing file due to --delete-after in retrieve_from_file():\n"));
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
if (unlink (filename))
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
dt &= ~RETROKF;
logprintf (LOG_VERBOSE, _("Removing %s.\n"), filename);
if (unlink (filename))
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
dt &= ~RETROKF;
}
xfree_null (new_file);
xfree_null (filename);
iri_free (tmpiri);
}
xfree_null (new_file);
xfree_null (filename);
iri_free (tmpiri);
/* Free the linked list of URL-s. */
free_urlpos (url_list);
#ifdef ENABLE_METALINK
}
/* Free the linked list of URL-s. */
free_urlpos (url_list);
#endif
iri_free (iri);

View File

@@ -58,7 +58,7 @@ char *fd_read_hunk (int, hunk_terminator_t, long, long);
char *fd_read_line (int);
uerr_t retrieve_url (struct url *, const char *, char **, char **,
const char *, int *, bool, struct iri *, bool);
const char *, int *, bool, struct iri *, bool, struct range *);
uerr_t retrieve_from_file (const char *, bool, int *);
const char *retr_rate (wgint, double);

View File

@@ -618,12 +618,12 @@ lowercase_str (char *str)
}
static const char *
init_seps (enum url_scheme scheme)
init_seps (enum url_scheme scheme, char *seps)
{
static char seps[8] = ":/";
char *p = seps + 2;
int flags = supported_schemes[scheme].flags;
strcpy (seps, ":/");
if (flags & scm_has_params)
*p++ = ';';
if (flags & scm_has_query)
@@ -676,6 +676,7 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
const char *params_b, *params_e;
const char *query_b, *query_e;
const char *fragment_b, *fragment_e;
char seps_b[8];
int port;
char *user = NULL, *passwd = NULL;
@@ -739,7 +740,7 @@ url_parse (const char *url, int *error, struct iri *iri, bool percent_encode)
/* Initialize separators for optional parts of URL, depending on the
scheme. For example, FTP has params, and HTTP and HTTPS have
query string and fragment. */
seps = init_seps (scheme);
seps = init_seps (scheme, seps_b);
host_b = p;
@@ -1791,10 +1792,11 @@ path_end (const char *url)
{
enum url_scheme scheme = url_scheme (url);
const char *seps;
char seps_b[8];
if (scheme == SCHEME_INVALID)
scheme = SCHEME_HTTP; /* use http semantics for rel links */
/* +2 to ignore the first two separators ':' and '/' */
seps = init_seps (scheme) + 2;
seps = init_seps (scheme, seps_b) + 2;
return strpbrk_or_eos (url, seps);
}

View File

@@ -2011,6 +2011,16 @@ run_with_timeout (double timeout, void (*fun) (void *), void *arg)
return false;
}
#ifdef ENABLE_THREADS
if (opt.jobs > 1)
{
/* XXX: FIXME. Support this functionality when there are
multiple threads. Do not translate the string. */
logputs (LOG_NOTQUIET, "\ntimeouts not (yet) supported with threads.\n");
abort ();
}
#endif
signal (SIGALRM, abort_run_with_timeout);
if (SETJMP (run_with_timeout_env) != 0)
{

View File

@@ -344,9 +344,18 @@ typedef enum
RETRBADPATTERN, PROXERR,
AUTHFAILED, QUOTEXC, WRITEFAILED, SSLINITFAILED, VERIFCERTERR,
UNLINKERR, NEWLOCATION_KEEP_POST, CLOSEFAILED, ATTRMISSING, UNKNOWNATTR,
WARC_ERR, WARC_TMP_FOPENERR, WARC_TMP_FWRITEERR
WARC_ERR, WARC_TMP_FOPENERR, WARC_TMP_FWRITEERR, THREADS_ERR, SEM_ERR
} uerr_t;
struct range {
wgint first_byte;
wgint last_byte;
wgint bytes_covered;
wgint is_assigned;
bool *resources;
uerr_t status_least_severe;
};
/* 2005-02-19 SMS.
Select an appropriate "orig" suffix and a separator character for
adding a unique suffix to a file name.

View File

@@ -1,3 +1,459 @@
2014-07-23 Darshit Shah <darnir@gmail.com>
* test/base_test.py (BaseTest.gen_cmd_line): Add support for running all
tests through valgrind if the relevant environment variable is set
* conf/expected_ret_code (ExpectedRetCode.__call__): Valgrind returns error
code 45 when it detects a memory leak.
* Readme: Update with details about valgrind tests
2014-07-22 Darshit Shah <darnir@gmail.com>
* (README): Remove old TODO and document SERVER_WAIT variable
2014-06-22 Darshit Shah <darnir@gmail.com>
* (conf.files_crawled): diff is a set object and needs explicit str
conversion.
2014-03-13 Zihang Chen <chsc4698@gmail.com>
* base_test.py:
(CommonMethods): Rename to BaseTest.
(BaseTest): Implement __init__ method where the class-wide variables are
initialized. Also variable names like `xxx_list` is renamed to its plural
form, e.g. `server_list` => `servers`.
(BaseTest.init_test_env): Remove name argument due to its unnecessarity.
(BaseTest.get_test_dir): Because the path of the test directory is needed
in multiple methods, this method is implemented.
(BaseTest.get_domain_addr): Rewrite the return statement utilizing str
formatting (which is more Pythonic).
(BaseTest.get_cmd_line): Rename to gen_cmd_line. Change the variables with
capitcal characters to lower ones. Also, the nested for loop is rewritten
to a plain loop using the zip function.
(BaseTest.__gen_local_filesys): Rename to gen_local_fs_snapshot. Move to
ExpectedFiles in conf/expected_files.py and is marked as a static
method. Refactor to a less verbose implementation.
(BaseTest._check_downloaded_files): Rename to __call__ to agree with the
invocation in test case classes. Move to ExpectedFiles in
conf/expected_files.py.
(BaseTest.get_server_rules): Refactor to a more Pythonic form utilizing
dict.items() and is marked static.
(BaseTest.stop_server): (new method) an abstract method which should stop
the currently using servers.
(BaseTest.instantiate_server_by): (new method) an abstract method which
should instantiate a server instance according to the given argument.
(BaseTest.__enter__): (new method) method which initialize the context
manager
(BaseTest.__exit__): (new method) method that finilize the context manager
and deal with the exceptions during the execution of the with statement,
subclasses can override this method for extensibility
* http_test.py:
(HTTPTest.__init__): Add call to super.__init__. Default values of
pre_hook, test_params, post_hook are set to None to avoid a subtle bug of
Python. Argument servers is renamed to protocols.
(HTTPTest.Server_setup): Move to BaseTest and rename to server_setup.
Calls to pre_hook_call, call_test, post_hook_call are removed.
(HTTPTest.hook_call, pre_hook_call, call_test, post_hook_call): Move to
BaseTest for that both HTTP test cases and FTP test cases may use these
methods.
(HTTPTest.init_HTTP_Server, init_HTTPS_Server): Merge and rename to
instantiate_server_by to implement the abstract method in BaseTest.
(HTTPTest.stop_HTTP_Server): Rename to stop_server to implement the
abstract method in BaseTest. Also, pull out the part where remaining
requests are gathered into a new method request_remaining.
(BaseTest.act_retcode): Rename to ret_code because ExpectedRetCode is
moved out from BaseTest, so the name act_retcode is actually a bit
verbose.
* conf/expected_ret_code.py:
(ExpectedRetCode.__call__): Rewrite the str into a more readable form.
* conf/files_crawled.py:
(FilesCrawled.__call__): Refactor this method into a more Pythonic form
utilizing the zip function.
* conf/local_files.py:
(LocalFiles__call__): Rewrite this method with the recommended with
statement.
* conf/server_conf.py:
(ServerConf.__call__): Rewrite this method due to BaseTest.server_list is
renamed to BaseTest.servers.
* conf/server_files.py:
(ServerFiles.__call__): Refactor the nested for loop into a plain one
utilizing the zip function.
* conf/urls.py:
(URLs): Rename url_list to urls.
* conf/wget_commands.py:
(WgetCommands): Rename command_list to commands, rename test_obj.options
to test_obj.wget_options.
* Test--https.py, Test-Proto.py, Test-Parallel-Proto.py: Argument servers
is changed to protocols due to change in the signature of
HTTPTest.__init__.
2014-03-13 Zihang Chen <chsc4698@gmail.com>
* test: (new package) package for test case classes
* WgetTest.py: Split into test/base_test.py and test/http_test.py.
* Test-*.py: Optimize the imports according to changes of WgetTest.py
2014-03-13 Zihang Chen <chsc4698@gmail.com>
* server: (new package) package for the server classes
* server.http: (new package) package for HTTP server
* server.ftp: (new package) package for FTP server
* HTTPServer.py: Move to server/http/http_server.py. Also change the
CERTFILE to '../certs/wget-cert.pem'.
* FTPServer.py: Move to server/ftp/ftp_server.py.
* WgetTest.py: Optimize import respect to the server classes.
2014-03-13 Zihang Chen <chsc4698@gmail.com>
* conf: (new package) package for rule classes and hook methods
* WgetTest.py:
(CommonMethods.Authentication): Move to conf/authentication.py.
(CommonMethods.ExpectHeader): Move to conf/expect_header.py.
(CommonMethods.RejectHeader): Move to conf/reject_header.py.
(CommonMethods.Response): Move to conf/response.py.
(CommonMethods.SendHeader): Move to conf/send_header.py.
(CommonMethods.ServerFiles): Move to conf/server_files.py.
(CommonMethods.LocalFiles): Move to conf/local_files.py.
(CommonMethods.ServerConf): Move to conf/server_conf.py.
(CommonMethods.WgetCommands): Move to conf/wget_commands.py.
(CommonMethods.Urls): Move to conf/urls.py.
(CommonMethods.ExpectedRetcode): Move to conf/expected_retcode.py.
(CommonMethods.ExpectedFiles): Move to conf/expected_files.py.
(CommonMethods.FilesCrawled): Move to conf/files_crawled.py.
(CommonMethods.__check_downloaded_files): Rename to
_check_downloaded_files, so that the method is callable from outside the
class.
(CommomMethods.get_server_rules): Modify so that it utilizes the conf
package.
(HTTPTest): Add a method hook_call(configs, name) to reduce duplications
in pre_hook_call, call_test and post_hook_call utilizing the conf package.
* conf/hook_sample.py: (new file) sample for hooks
* conf/rule_sample.py: (new file) sample for rules
* REAMDE: Update sections about customizing rules and hooks.
2014-03-13 Zihang Chen <chsc4698@gmail.com>
* exc: (new package) package for miscellaneous exceptions
* WgetTest.py: Move TestFailed to exc/test_failed.py.
2014-03-13 Zihang Chen <chsc4698@gmail.com>
* Test-Proto.py: Fix a typo (line 71: server to servers).
2014-03-13 Zihang Chen <chsc4698@gmail.com>
* WgetTest.py: Move WgetFile to package misc.
* README: Modify documentation respect to WgetFile.
* Test-*.py: Optimize imports about WgetFile.
2014-03-13 Zihang Chen <chsc4698@gmail.com>
* misc: (new package) package for miscellaneous modules
* ColourTerm.py: Move to package misc and rename to colour_terminal.py,
add print_color functions to reduce the use of string literals like
"BLUE", "RED" etc.
* WgetTest.py:
(CommonMethods.Server_setup): Change invocation to printer to print_blue.
(CommonMethods.FilesCrawled): Change invocation to printer to print_red.
(HTTPTest.__init__): Change invocations to printer to print_red and
print_green respectively.
2014-01-02 Darshit Shah <darnir@gmail.com>
* Makefile.am: Add new Test--https.py to list of tests and EXTRA_DIST.
Also replace all tabs with spaces in file for conformity.
* Test--https.py: New test to check if Wget works correctly with HTTPS
servers
* HTTPServer.py: Import new modules for use in HTTPS Servers
(HTTPSServer): New class that generates a SSL-wrapped socket for use in a
HTTPS Server.
(HTTPSd): HTTPS daemon class. Analogous to the HTTPd class
* WgetTest.py: Define global variables HTTP and HTTPS to reflect Server
types
(CommonMethods.exec_wget): Add the protocol information to the URL before
passing it to wget
(HTTPTest.__init__): Edit syntax. The servers variable now accepts a list of
servers defined by their type. E.g. HTTP, HTTPS.
(HTTPTest.Server_setup): Reflect change in type of variable servers.
However, we maintin the value of self.servers to allow most of the code to
remain unchanged.
(HTTPTest.init_HTTPS_Server): Initialize a HTTPS Server
* Test-Parallel-Proto.py: Edit to reflect slight change in Test Fiel Syntax.
* Test-Proto.py: Same
2014-01-02 Darshit Shah <darnir@gmail.com>
* WgetTest.py (CommonMentods.exec_wget): Wait for n seconds before calling
the Wget executable.
2013-12-27 Darshit Shah <darnir@gmail.com>
* WgetTest.py: Add modeline
(CommonMethods.ServerConf): New pre-test hook that sets
BaseHTTPRequestHandler class variables in all available servers
* HTTPServer.py (HTTPd.ServerConf): Call the respective method in the Server
to set the class variables
(StoppableHTTPServer.server_sett): Set the handler class variables
2013-12-26 Darshit Shah <darnir@gmail.com>
* WgetTest.py (HTTPTest.call_test): Correct the call to stop_HTTP_Server.
2013-12-25 Darshit Shah <darnir@gmail.com>
* WgetTest.py (CommonMehtods.exec_wget): Catch and handle exception if the
Wget executable is not found at src/wget
(HTTPTest.call_test): In case of error during execution, remove all existing
servers before quitting
2013-12-15 Darshit Shah <darnir@gmail.com>
* WgetTest.py (HTTPTest.HTTP_setup): Rename to Server_setup so it can be
easily reused for other non-HTTP servers.
(HTTPTest.__init__): Call Server_setup instead of HTTP_setup
(HTTPTest.Server_setup): Split into three more functions, that handle
pre-hooks, test execution and post-hooks respectively.
(HTTPTest.pre_hook_call): Set up and execute the pre-test hooks. Code split
from HTTPTest.Server_setup
(HTTPTest.call_test): Execute wget and log exit code. Code split from
HTTPTest.Server_setup
(HTTPTest.post_hook_call): Set up and execute post-test hooks. Code split
from HTTPTest.Server_setup
2013-12-04 Darshit Shah <darnir@gmail.com>
* Makefile.am [RACE_CHECKING_IS_ENABLED]: Define `RACE_FAIL' and
RACE_TESTS'.
2013-10-14 Giuseppe Scrivano <gscrivan@redhat.com>
* Makefile.am (XFAIL_TESTS): Remove Test--spider-r.py.
2013-10-06 Giuseppe Scrivano <gscrivan@redhat.com>
* Makefile.am (EXTRA_DIST): Distribute test files.
2013-09-16 Darshit Shah <darnir@gmail.com>
* README: Update documentation
2013-09-14 Darshit Shah <darnir@gmail.com>
* HTTPServer.py (StoppableHTTPServer): Define object variable
request_headers which stores a list of requests received by the server
(StoppableHTTPServer.get_req_headers): Return the list of Request
Headers stored by the server
(_Handler.do_HEAD): Send the Request MEthod string for identification
(_Handler.do_GET): Same
(_Handler.__log_request): Log the request in Request_Headers list
(_Handler.send_head): Make a call to __log_request
* Test--spider-r.py: Add new list, Request_List, which contains all
the requests that Wget is expected to send. This will allow for
fine-grained tests on recursive downloading.
* WgetTest.py (CommonMethods.FilesCrawled): New Post-Test Hook, that
ensures that all the expected Files on the server were accessed as
expected.
(HTTPTest.stop_HTTP_server): On stopping server, asks it to respond
with list of all requests it received.
2013-09-13 Darshit Shah <darnir@gmail.com>
* Test--spider-r.py: Test retrieval in recursive spider mode.
* Makefile.am: add new file
2013-09-13 Darshit Shah <darnir@gmail.com>
* HTTPServer.py (_Handler.do_HEAD): If requested path is /, respond
with /index.html
(_Handler.do_HEAD): Smartly guess value of Content-Type Header from
file extension
(_Handler.guess_type): Use a preset list of extensions and
Content-Type strings. If the extension matches one in the list, use
that string, else default to "text/plain"
2013-09-13 Darshit Shah <darnir@gmail.com>
* WgetTest.py (CommonMethods._replace_substring): New method that will
replace a substring delimited by {{ }} characters by the value of
self.<substring> variable
(CommonMethods.WgetCommands): Use the _replace_substring () call to
replace the substrings in the the command line.
(CommonMethods.ServerFiles): Run the _replace_substring () method on
the File contents too.
2013-09-11 Darshit Shah <darnir@gmail.com>
* WgetTest.py (CommonMethods.exec_wget): Expect domain_list instead of
domain.
(CommonMethods.get_cmd_line): Same. Generate command line by
prepending to each file it's respective domain string
(CommonMethods.ServerFiles): Generate file_list and server_rules for
each Server and set the config details
(HTTPTest): New named parameter, servers which signifies number of
servers to spawn
(HTTPTest.HTTP_setup): This method now takes servers as a new
parameter. Instead of storing server and domain, we now store
server_list and domain_list. Each server must be initialized through a
loop.
(HTTPTest.stop_HTTP_server): Stop all servers in a loop.
* Test-Parallel-Proto.py: Prototype test file for multiple servers.
2013-09-10 Darshit Shah <darnir@gmail.com>
* WgetTest.py (HTTPTest.stop_HTTP_server): With the threaded servers,
we can simply use the socketserver.shutdown() method to close the
server instead of sending a QUIT command
* HTTPServer.py (StoppabelHTTPServer.serve_forever): Delete method. No
need to override this method anymore.
(WgetHTTPRequestHandler.do_QUIT): No longer required
(HTTPd): Rename self.server to self.server_inst to reduce ambiguity
when referenced from WgetTest
2013-09-08 Darshit Shah <darnir@gmail.com>
* README (File Structure): Add explanation about various variables
used consistently across all tests.
2013-09-07 Darshit Shah <darnir@gmail.com>
* HTTPServer.py: Remove bunch of old code artefacts
* WgetTest.py: Same
2013-09-07 Darshit Shah <darnir@gmail.com>
* HTTPServer.py (StoppableHTTPServer.server_conf): Change global
variable fileSys to an object variable. This is good programming
practice and required for parallel-wget support.
(StoppableHTTPServer.server_forever): Edit overridden method to remove
the global queue variable. No longer required under the new working
(WgetHTTPRequestHandler.do_QUIT): Don't push fileSys through the queue
(_Handler): Rename class __Handler to _Handler to match Python's
encapsulation rules
(_Handler.do_POST): fileSys is now an object variable of the server
(_Handler.do_PUT): Same
(_Handler.send_put): Same
(_Handler.send_head): Same
(HTTPd): New class that wraps around the server for Threading
(create_server): Make new object of HTTPd.
(spawn_server): Start the thread created through create_server
(ret_fileSys): Removed method. No longer required.
* WgetTest.py (HTTPTest.__init__): Don't explicitly set
self.act_retcode. Instead toggle tests_passed boolean to set the
correct return code.
(HTTPTest.HTTP_setup): We no longer call HTTPServer.spawn_server to
start a new instance of the server.
(HTTPTest.init_HTTP_server): We no longer call the old
create_server(), spawn_server() methods. Instead use the new HTTPd
class interface to create new instances of the server
(HTTPTest.stop_HTTP_server): Don't ask server to return fileSys.
2013-09-07 Darshit Shah <darnir@gmail.com>
* Test-Post.py: Test basic functionality for sending HTTP POST
requests using the --method command
* Makefile.am: Add new test
2013-09-06 Darshit Shah <darnir@gmail.com>
* WgetTest.py (CommonMethods.__check_downloaded_files): Print a
unified diff in case there is a mismatch in the file contents
2013-09-06 Darshit Shah <darnir@gmail.com>
* HTTPServer.py (WgetHTTPRequestHandler.test_cookies): Comment out the
old test_cookies code. This is no longer used and was causing problems
with expected cookies. The code will soon be removed anyways
* Test-cookie.py: Add new test for basic cookie functionality
* Test-cookie-401.py: Ensure cookies are saved during a 401 response
* Test-cookie-expires.py: Ensure that the Expires field is correctly
handled
* Test-cookies-domain-mismatch.py: Ensure that mismatched domains are
handled by Wget
* Makefile.am: Add the new tests
2013-09-06 Darshit Shah <darnir@gmail.com>
* README: New section on pending work. Will keep updating this to keep
track of work that remains to be done on this implementation
2013-09-05 Darshit Shah <darnir@gmail.com>
* Test-auth-with-content-disposition.py: Add test that ensures Content
Disposition works alongwith authentication
* Makefile.am: Add new test
2013-09-04 Darshit Shah <darnir@gmail.com>
* Test-c-full.py: Test Continue options
* Makefile.am: Add Test-c-full.py and Test-O
2013-09-02 Darshit Shah <darnir@gmail.com>
* Makefile.am: Add new Test
* Test-Head.py: New Test to ensure HEAD requests are handled correctly
2013-08-31 Darshit Shah <darnir@gmail.com>
* README: Explain that TEST_NAME needs to be unique
* Test-auth-no-challenge.py: Edit non-unique TEST_NAME
2013-08-31 Darshit Shah <darnir@gmail.com>
* HTTPTest.py (ServerError): Define new Exception for handling
internal control flow.
(StoppableHTTPServer.SendHeader): Simply pass. Do nothing. Adding
functionality here seems to crash for no apparent reason.
(stoppableHTTPServer.send_cust_headers): Minor optimization. No need
for extra variable.
(__Handler.Response): Handle explicit Response Code Rules
(__Handler.Authentication): Handle Authentication rules
(__Handler.handle_auth): Actual worker method for authentication
(__Handler.ExpectHeader): Ensure Expected Headers are received
(__Handler.RejectHeader): Ensure Blacklisted Headers are NOT received
(__Handler.send_HEAD): Dynamically call server rule functions based on
the self.rules list. This feature will later be added to POST/PUT, etc
2013-08-31 Darshit Shah <darnir@gmail.com>
* WgetTest.py: Remove import module defaultdict.
(CommonMethods.get_server_rules): server_rules should be a dict, not a
defaultdict (list).
* HTTPServer.py (WgetHTTPRequestHandler.get_rule_list): If rule does
not exist, return None. Not an emppty list.
(WgetHTTPRequestHandler.test_cookies): Rule variable is not a list
(__Handler.send_cust_headers): Same
(__Handler.custom_response): Same
(__Handler.is_authorized): Same
(__Handler.expect_headers): Same
(__Handler.reject_headers): Same
2013-08-31 Darshit Shah <darnir@gmail.com>
* README: (newfile) Simple help / instructions about using the Test
Environment.
* Makefile.am: (newfile) Makefile for the Test Environment. Uses the
Automake Parallel Test Harness
* WgetTest.py: (newfile) Base module that executes the Test.
* HTTPServer.py: (newfile) Contains the custom HTTP Server for the
Test Environment. Creates an instance of http.server in Python3.
* FTPServer.py: (newfile) Overrides methods from pyftpdlib for use in
the Test Environment. ** Work under progress **.
* ColourTerm.py: (newfile) A custom module to output coloured text to
the terminal. Known to work on POSIX shells.
* Test-Proto.py: (newfile) A prototype Test File. This should be
copied when writing a new Test Case.
* Test-Content-disposition-2.py: Test Content Disposition clobbering
* Test-Content-disposition.py: Test Content Disposition Headers
* Test-O.py: Test Output filename command
* Test-auth-basic-fail.py: Test returncode on auth failure
* Test-auth-basic.py: Test Basic Auth negotiation
* Test-auth-both.py: Test handling of Multiple auth providers. This
test currently fails.
* Test-auth-digest.py: Test Digest Auth Negotiation
* Test-auth-no-challenge-url.py: Ensure --auth-no-challenge is handled
when auth details are in-URL.
* Test-auth-no-challenge.py: Ensure --auth-no-challenge is honoured
* Test-auth-retcode.py: Ensure correct return code after 403 Forbidden
response.
2014-08-08 Darshit Shah <darnir@gmail.com>
* conf/__init__.py: Add extra newline according to PEP8

View File

@@ -28,6 +28,12 @@
AUTOMAKE_OPTIONS = parallel-tests
AM_TESTS_ENVIRONMENT = MAKE_CHECK=True; export MAKE_CHECK;
if RACE_CHECKING_IS_ENABLED
RACE_FAIL = Test--spider-r.py
RACE_TESTS =
endif
TESTS = Test-auth-basic-fail.py \
Test-auth-basic.py \
Test-auth-both.py \
@@ -43,13 +49,15 @@ TESTS = Test-auth-basic-fail.py \
Test-cookie-domain-mismatch.py \
Test-cookie-expires.py \
Test-cookie.py \
$(RACE_TESTS) \
Test-Head.py \
Test--https.py \
Test-O.py \
Test-Post.py \
Test--spider-r.py
XFAIL_TESTS = Test-auth-both.py
XFAIL_TESTS = Test-auth-both.py \
$(RACE_FAIL)
LOG_COMPILER = python3

View File

@@ -0,0 +1,11 @@
from conf import hook
@hook()
class ServerConf:
def __init__(self, server_settings):
self.server_settings = server_settings
def __call__(self, test_obj):
for server in test_obj.servers:
server.server_sett(self.server_settings)

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -183,6 +183,10 @@
* HTTPServer.pm: added check for must-not-match request-header
* Test-cookies.px: check cookie deletion and cookie domain matching
2012-12-02 Domenico Chierico <spaghetty@gmail.com>
* Makefile.am (LDADD): Remove $(LIBS).
2012-06-16 Giuseppe Scrivano <gscrivano@gnu.org>
* Makefile.am (EXTRA_DIST): Add Test-stdouterr.px.

View File

@@ -147,6 +147,6 @@ EXTRA_DIST = FTPServer.pm FTPTest.pm HTTPServer.pm HTTPTest.pm \
check_PROGRAMS = unit-tests
unit_tests_SOURCES =
LDADD = ../src/libunittest.a ../lib/libgnu.a $(LIBS)
LDADD = ../src/libunittest.a ../lib/libgnu.a
CLEANFILES = *~ *.bak core core.[0-9]*