1#!/usr/bin/env python3
2import socket
3from sys import exit
4from test.http_test import HTTPTest
5from test.base_test import SKIP_TEST
6from test.base_test import HTTP
7from misc.wget_file import WgetFile
8
9"""
10    This test ensures, that domains with and without leftmost dot defined in
11    no_proxy environment variable are accepted by wget. The idea is to use
12    non-existing proxy server address and detect whether files are downloaded
13    when proxy settings are omitted based on no_proxy environment variable
14    value.
15
16    current wget's behavior:
17    - "no_proxy=.mit.edu"
18      - will match the domain and subdomains e.g. "www.mit.edu" or "www.subdomain.mit.edu" (Case #4)
19      - will NOT match the host "mit.edu" (Case #3)
20    - "no_proxy=mit.edu"
21      - will match the domain and subdomains e.g. "www.mit.edu" or "www.subdomain.mit.edu" (Case #2)
22      - will match the host "mit.edu" (Case #1)
23    - downside: can not match only the host
24"""
25
26# Check whether the system supports translating localhost subdomains
27# to localhost address and if not, skip it.
28hostnames_to_check = [
29    "working1.localhost",
30    "working2.localhost",
31    "www.working1.localhost",
32    "www.working2.localhost",
33]
34for hostname in hostnames_to_check:
35    try:
36        ip = socket.gethostbyname(hostname)
37    except socket.gaierror as _:
38        # resolution of the name fails
39        # return value 77 -> SKIP
40        exit(SKIP_TEST)
41
42# File Definitions
43File1 = "Would you like some Tea?"
44File2 = "With lemon or cream?"
45
46A_File = WgetFile ("File1", File1)
47B_File = WgetFile ("File2", File2)
48
49WGET_URLS = [["File1", "File2"]]
50WGET_ENVS = {
51    "http_proxy": "nonexisting.localhost:8080",
52    "no_proxy": "working1.localhost,.working2.localhost"
53}
54
55Servers = [HTTP]
56Files = [[A_File, B_File]]
57
58ExpectedReturnCodeWorking = 0
59ExpectedReturnCodeNotWorking = 4  # network error (non-existing proxy address)
60
61ExpectedDownloadedFilesWorking = [A_File, B_File]
62
63# Pre and Post Test Hooks
64test_options = {
65    "Urls"                : WGET_URLS,
66    "EnvironmentVariables": WGET_ENVS
67}
68post_test_working = {
69    "ExpectedFiles"     : ExpectedDownloadedFilesWorking,
70    "ExpectedRetcode"   : ExpectedReturnCodeWorking
71}
72post_test_not_working = {
73    "ExpectedRetcode"   : ExpectedReturnCodeNotWorking
74}
75
76# Case #1:
77# - Requested domain matches exactly the domain definition in no_proxy.
78# - Domain definition in no_proxy is NOT dot-prefixed
79# Expected result: proxy settings don't apply and files are downloaded.
80pre_case_1 = {
81    "ServerFiles"       : Files,
82    "Domains"           : ["working1.localhost"]
83}
84
85err_case_1 = HTTPTest (
86    pre_hook=pre_case_1,
87    test_params=test_options,
88    post_hook=post_test_working,
89    protocols=Servers
90).begin ()
91
92# Case #2:
93# - Requested domain is sub-domain of a domain definition in no_proxy.
94# - Domain definition in no_proxy is NOT dot-prefixed
95# Expected result: proxy settings don't apply and files are downloaded.
96pre_case_2 = {
97    "ServerFiles"       : Files,
98    "Domains"           : ["www.working1.localhost"]
99}
100
101err_case_2 = HTTPTest (
102    pre_hook=pre_case_2,
103    test_params=test_options,
104    post_hook=post_test_working,
105    protocols=Servers
106).begin ()
107
108# Case #3:
109# - Requested domain matches exactly the domain definition in no_proxy,
110#   except for the leftmost dot (".") in no_proxy domain definition.
111# - Domain definition in no_proxy IS dot-prefixed
112# Expected result: proxy settings apply and files are downloaded. This is
113#                  due to the mismatch in leftmost dot.
114# NOTE: This is inconsistent with curl's behavior, but has less drawbacks.
115pre_case_3 = {
116    "ServerFiles"       : Files,
117    "Domains"           : ["working2.localhost"]
118}
119
120err_case_3 = HTTPTest (
121    pre_hook=pre_case_3,
122    test_params=test_options,
123    post_hook=post_test_not_working,
124    protocols=Servers
125).begin ()
126
127# Case #4:
128# - Requested domain is sub-domain of a domain definition in no_proxy.
129# - Domain definition in no_proxy IS dot-prefixed
130# Expected result: proxy settings don't apply and files are downloaded.
131pre_case_4 = {
132    "ServerFiles"       : Files,
133    "Domains"           : ["www.working2.localhost"]
134}
135
136err_case_4 = HTTPTest (
137    pre_hook=pre_case_4,
138    test_params=test_options,
139    post_hook=post_test_working,
140    protocols=Servers
141).begin ()
142
143# Case #5
144# - Requested domain does not match a domain definition in no_proxy.
145# - Requested domain is NOT sub-domain of a domain definition in no_proxy.
146# Expected result: proxy settings apply and files are NOT downloaded due to
147#                  network error when using proxy with non-existing URL.
148pre_case_5 = {
149    "ServerFiles"       : Files,
150    "Domains"           : ["www.example.localhost"]
151}
152
153err_case_5 = HTTPTest (
154    pre_hook=pre_case_5,
155    test_params=test_options,
156    post_hook=post_test_not_working,
157    protocols=Servers
158).begin ()
159
160# Combine error codes from all test cases
161exit (max(err_case_1, err_case_2, err_case_3, err_case_4, err_case_5))
162