1#!/usr/bin/env python3 2from sys import exit 3from test.http_test import HTTPTest 4from misc.wget_file import WgetFile 5import hashlib 6from base64 import b64encode 7 8""" 9 This is to test Metalink/HTTP with Metalink/XML Link headers. 10 11 With --trust-server-names, trust the metalink:file names. 12 13 Without --trust-server-names, don't trust the metalink:file names: 14 use the basename of --input-metalink, and add a sequential number 15 (e.g. .#1, .#2, etc.). 16 17 Strip the directory from unsafe paths. 18""" 19 20############# File Definitions ############################################### 21bad = "Ouch!" 22bad_sha256 = hashlib.sha256 (bad.encode ('UTF-8')).hexdigest () 23 24File1 = "Would you like some Tea?" 25File1_lowPref = "Do not take this" 26File1_sha256 = hashlib.sha256 (File1.encode ('UTF-8')).hexdigest () 27 28File2 = "This is gonna be good" 29File2_lowPref = "Not this one too" 30File2_sha256 = hashlib.sha256 (File2.encode ('UTF-8')).hexdigest () 31 32File3 = "A little more, please" 33File3_lowPref = "That's just too much" 34File3_sha256 = hashlib.sha256 (File3.encode ('UTF-8')).hexdigest () 35 36File4 = "Maybe a biscuit?" 37File4_lowPref = "No, thanks" 38File4_sha256 = hashlib.sha256 (File4.encode ('UTF-8')).hexdigest () 39 40File5 = "More Tea...?" 41File5_lowPref = "I have to go..." 42File5_sha256 = hashlib.sha256 (File5.encode ('UTF-8')).hexdigest () 43 44MetaXml1 = \ 45"""<?xml version="1.0" encoding="utf-8"?> 46<metalink version="3.0" xmlns="http://www.metalinker.org/"> 47 <publisher> 48 <name>GNU Wget</name> 49 </publisher> 50 <license> 51 <name>GNU GPL</name> 52 <url>http://www.gnu.org/licenses/gpl.html</url> 53 </license> 54 <identity>Wget Test Files</identity> 55 <version>1.2.3</version> 56 <description>Wget Test Files description</description> 57 <files> 58 <file name="dir/File1"> 59 <verification> 60 <hash type="sha256">{{FILE1_HASH}}</hash> 61 </verification> 62 <resources> 63 <url type="http" preference="35">http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file</url> 64 <url type="http" preference="40">http://{{SRV_HOST}}:{{SRV_PORT}}/404</url> 65 <url type="http" preference="25">http://{{SRV_HOST}}:{{SRV_PORT}}/File1_lowPref</url> 66 <url type="http" preference="30">http://{{SRV_HOST}}:{{SRV_PORT}}/File1</url> 67 </resources> 68 </file> 69 <file name="dir/File2"> 70 <verification> 71 <hash type="sha256">{{FILE2_HASH}}</hash> 72 </verification> 73 <resources> 74 <url type="http" preference="35">http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file</url> 75 <url type="http" preference="40">http://{{SRV_HOST}}:{{SRV_PORT}}/404</url> 76 <url type="http" preference="25">http://{{SRV_HOST}}:{{SRV_PORT}}/File2_lowPref</url> 77 <url type="http" preference="30">http://{{SRV_HOST}}:{{SRV_PORT}}/File2</url> 78 </resources> 79 </file> 80 <file name="/dir/File3"> <!-- rejected by libmetalink --> 81 <verification> 82 <hash type="sha256">{{FILE3_HASH}}</hash> 83 </verification> 84 <resources> 85 <url type="http" preference="35">http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file</url> 86 <url type="http" preference="40">http://{{SRV_HOST}}:{{SRV_PORT}}/404</url> 87 <url type="http" preference="25">http://{{SRV_HOST}}:{{SRV_PORT}}/File3_lowPref</url> 88 <url type="http" preference="30">http://{{SRV_HOST}}:{{SRV_PORT}}/File3</url> 89 </resources> 90 </file> 91 <file name="dir/File4"> 92 <verification> 93 <hash type="sha256">{{FILE4_HASH}}</hash> 94 </verification> 95 <resources> 96 <url type="http" preference="35">http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file</url> 97 <url type="http" preference="40">http://{{SRV_HOST}}:{{SRV_PORT}}/404</url> 98 <url type="http" preference="25">http://{{SRV_HOST}}:{{SRV_PORT}}/File4_lowPref</url> 99 <url type="http" preference="30">http://{{SRV_HOST}}:{{SRV_PORT}}/File4</url> 100 </resources> 101 </file> 102 <file name="dir/File5"> 103 <verification> 104 <hash type="sha256">{{FILE5_HASH}}</hash> 105 </verification> 106 <resources> 107 <url type="http" preference="35">http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file</url> 108 <url type="http" preference="40">http://{{SRV_HOST}}:{{SRV_PORT}}/404</url> 109 <url type="http" preference="25">http://{{SRV_HOST}}:{{SRV_PORT}}/File5_lowPref</url> 110 <url type="http" preference="30">http://{{SRV_HOST}}:{{SRV_PORT}}/File5</url> 111 </resources> 112 </file> 113 </files> 114</metalink> 115""" 116 117MetaXml2 = \ 118"""<?xml version="1.0" encoding="utf-8"?> 119<metalink version="3.0" xmlns="http://www.metalinker.org/"> 120 <publisher> 121 <name>GNU Wget</name> 122 </publisher> 123 <license> 124 <name>GNU GPL</name> 125 <url>http://www.gnu.org/licenses/gpl.html</url> 126 </license> 127 <identity>Wget Test Files</identity> 128 <version>1.2.3</version> 129 <description>Wget Test Files description</description> 130 <files> 131 <file name="bad"> 132 <verification> 133 <hash type="sha256">{{BAD_HASH}}</hash> 134 </verification> 135 <resources> 136 <url type="http" preference="35">http://{{SRV_HOST}}:{{SRV_PORT}}/wrong_file</url> 137 <url type="http" preference="40">http://{{SRV_HOST}}:{{SRV_PORT}}/404</url> 138 <url type="http" preference="30">http://{{SRV_HOST}}:{{SRV_PORT}}/bad</url> 139 </resources> 140 </file> 141 </files> 142</metalink> 143""" 144 145LinkHeaders = [ 146 # This file has the lowest priority, and should go last 147 "<http://{{SRV_HOST}}:{{SRV_PORT}}/test1.metalink>; rel=describedby; pri=2; type=\"application/metalink4+xml\"", 148 # This file has the highest priority, and should go first 149 "<http://{{SRV_HOST}}:{{SRV_PORT}}/test2.metalink>; rel=describedby; pri=1; type=\"application/metalink4+xml\"" 150] 151 152# This will be filled as soon as we know server hostname and port 153MetaHTTPRules = {'SendHeader' : {}} 154 155MetaHTTP = WgetFile ("main.metalink", rules=MetaHTTPRules) 156 157wrong_file = WgetFile ("wrong_file", bad) 158 159File1_orig = WgetFile ("File1", File1) 160File1_down = WgetFile ("dir/File1", File1) 161File1_nono = WgetFile ("File1_lowPref", File1_lowPref) 162 163File2_orig = WgetFile ("File2", File2) 164File2_down = WgetFile ("dir/File2", File2) 165File2_nono = WgetFile ("File2_lowPref", File2_lowPref) 166 167# rejected by libmetalink 168File3_orig = WgetFile ("File3", File3) 169File3_nono = WgetFile ("File3_lowPref", File3_lowPref) 170 171File4_orig = WgetFile ("File4", File4) 172File4_down = WgetFile ("dir/File4", File4) 173File4_nono = WgetFile ("File4_lowPref", File4_lowPref) 174 175File5_orig = WgetFile ("File5", File5) 176File5_down = WgetFile ("dir/File5", File5) 177File5_nono = WgetFile ("File5_lowPref", File5_lowPref) 178 179MetaFile1 = WgetFile ("test1.metalink", MetaXml1) 180MetaFile1_down = WgetFile ("test1.metalink", MetaXml1) 181 182MetaFile2 = WgetFile ("test2.metalink", MetaXml2) 183 184WGET_OPTIONS = "--trust-server-names --metalink-over-http --metalink-index=2" 185WGET_URLS = [["main.metalink"]] 186 187RequestList = [[ 188 "HEAD /main.metalink", 189 "GET /404", 190 "GET /wrong_file", 191 "GET /test1.metalink", 192 "GET /File1", 193 "GET /File2", 194 "GET /File4", 195 "GET /File5" 196]] 197 198Files = [[ 199 MetaHTTP, 200 wrong_file, 201 MetaFile1, MetaFile2, 202 File1_orig, File1_nono, 203 File2_orig, File2_nono, 204 File3_orig, File3_nono, 205 File4_orig, File4_nono, 206 File5_orig, File5_nono 207]] 208Existing_Files = [] 209 210ExpectedReturnCode = 0 211ExpectedDownloadedFiles = [ 212 MetaFile1_down, 213 File1_down, 214 File2_down, 215 File4_down, 216 File5_down 217] 218 219################ Pre and Post Test Hooks ##################################### 220pre_test = { 221 "ServerFiles" : Files, 222 "LocalFiles" : Existing_Files 223} 224test_options = { 225 "WgetCommands" : WGET_OPTIONS, 226 "Urls" : WGET_URLS 227} 228post_test = { 229 "ExpectedFiles" : ExpectedDownloadedFiles, 230 "ExpectedRetcode" : ExpectedReturnCode, 231 "FilesCrawled" : RequestList 232} 233 234http_test = HTTPTest ( 235 pre_hook=pre_test, 236 test_params=test_options, 237 post_hook=post_test 238) 239 240http_test.server_setup() 241### Get and use dynamic server sockname 242srv_host, srv_port = http_test.servers[0].server_inst.socket.getsockname () 243 244MetaXml1 = MetaXml1.replace('{{FILE1_HASH}}', File1_sha256) 245MetaXml1 = MetaXml1.replace('{{FILE2_HASH}}', File2_sha256) 246MetaXml1 = MetaXml1.replace('{{FILE3_HASH}}', File3_sha256) 247MetaXml1 = MetaXml1.replace('{{FILE4_HASH}}', File4_sha256) 248MetaXml1 = MetaXml1.replace('{{FILE5_HASH}}', File5_sha256) 249MetaXml1 = MetaXml1.replace('{{SRV_HOST}}', srv_host) 250MetaXml1 = MetaXml1.replace('{{SRV_PORT}}', str (srv_port)) 251MetaFile1.content = MetaXml1 252MetaFile1_down.content = MetaXml1 253 254MetaXml2 = MetaXml2.replace('{{BAD_HASH}}', bad_sha256) 255MetaXml2 = MetaXml2.replace('{{SRV_HOST}}', srv_host) 256MetaXml2 = MetaXml2.replace('{{SRV_PORT}}', str (srv_port)) 257MetaFile2.content = MetaXml2 258 259# Helper function for hostname, port and digest substitution 260def SubstituteServerInfo (text, host, port): 261 text = text.replace('{{SRV_HOST}}', host) 262 text = text.replace('{{SRV_PORT}}', str (port)) 263 return text 264 265MetaHTTPRules["SendHeader"] = { 266 'Link': [ SubstituteServerInfo (LinkHeader, srv_host, srv_port) 267 for LinkHeader in LinkHeaders ] 268} 269 270err = http_test.begin () 271 272exit (err) 273