1#!/usr/bin/env python
2#
3# spyne - Copyright (C) Spyne contributors.
4#
5# This library is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 2.1 of the License, or (at your option) any later version.
9#
10# This library is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public
16# License along with this library; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
18#
19
20# The MIT License
21#
22# Copyright (c) Val Neekman @ Neekware Inc. http://neekware.com
23#
24# Permission is hereby granted, free of charge, to any person obtaining a copy
25# of this software and associated documentation files (the "Software"), to deal
26# in the Software without restriction, including without limitation the rights
27# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28# copies of the Software, and to permit persons to whom the Software is
29# furnished to do so, subject to the following conditions:
30#
31# The above copyright notice and this permission notice shall be included in
32# all copies or substantial portions of the Software.
33#
34# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40# THE SOFTWARE.
41#
42
43from unittest import TestCase
44
45
46from spyne.util.address import set_address_parser_settings
47
48set_address_parser_settings(trusted_proxies=['177.139.233.100'])
49
50from spyne.util.address import address_parser
51
52
53class IPv4TestCase(TestCase):
54    """IP address Test"""
55
56    def test_meta_none(self):
57        request = {
58        }
59        ip = address_parser.get_real_ip(request)
60        self.assertIsNone(ip)
61
62    def test_http_x_forwarded_for_multiple(self):
63        request = {
64            'HTTP_X_FORWARDED_FOR': '192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139',
65            'HTTP_X_REAL_IP': '177.139.233.132',
66            'REMOTE_ADDR': '177.139.233.133',
67        }
68        ip = address_parser.get_real_ip(request)
69        self.assertEqual(ip, "198.84.193.157")
70
71    def test_http_x_forwarded_for_multiple_left_most_ip(self):
72        request = {
73            'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
74            'HTTP_X_REAL_IP': '177.139.233.132',
75            'REMOTE_ADDR': '177.139.233.133',
76        }
77        ip = address_parser.get_real_ip(request)
78        self.assertEqual(ip, "198.84.193.157")
79
80    def test_http_x_forwarded_for_multiple_right_most_ip(self):
81        request = {
82            'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
83            'HTTP_X_REAL_IP': '177.139.233.132',
84            'REMOTE_ADDR': '177.139.233.133',
85        }
86        ip = address_parser.get_real_ip(request, right_most_proxy=True)
87        self.assertEqual(ip, "177.139.233.139")
88
89    def test_http_x_forwarded_for_multiple_right_most_ip_private(self):
90        request = {
91            'HTTP_X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
92            'HTTP_X_REAL_IP': '177.139.233.132',
93            'REMOTE_ADDR': '177.139.233.133',
94        }
95        ip = address_parser.get_real_ip(request, right_most_proxy=True)
96        self.assertEqual(ip, "177.139.233.139")
97
98    def test_http_x_forwarded_for_multiple_bad_address(self):
99        request = {
100            'HTTP_X_FORWARDED_FOR': 'unknown, 192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139',
101            'HTTP_X_REAL_IP': '177.139.233.132',
102            'REMOTE_ADDR': '177.139.233.133',
103        }
104        ip = address_parser.get_real_ip(request)
105        self.assertEqual(ip, "198.84.193.157")
106
107    def test_http_x_forwarded_for_singleton(self):
108        request = {
109            'HTTP_X_FORWARDED_FOR': '177.139.233.139',
110            'HTTP_X_REAL_IP': '177.139.233.132',
111            'REMOTE_ADDR': '177.139.233.133',
112        }
113        ip = address_parser.get_real_ip(request)
114        self.assertEqual(ip, "177.139.233.139")
115
116    def test_http_x_forwarded_for_singleton_private_address(self):
117        request = {
118            'HTTP_X_FORWARDED_FOR': '192.168.255.182',
119            'HTTP_X_REAL_IP': '177.139.233.132',
120            'REMOTE_ADDR': '177.139.233.133',
121        }
122        ip = address_parser.get_real_ip(request)
123        self.assertEqual(ip, "177.139.233.132")
124
125    def test_bad_http_x_forwarded_for_fallback_on_x_real_ip(self):
126        request = {
127            'HTTP_X_FORWARDED_FOR': 'unknown 177.139.233.139',
128            'HTTP_X_REAL_IP': '177.139.233.132',
129            'REMOTE_ADDR': '177.139.233.133',
130        }
131        ip = address_parser.get_real_ip(request)
132        self.assertEqual(ip, "177.139.233.132")
133
134    def test_empty_http_x_forwarded_for_fallback_on_x_real_ip(self):
135        request = {
136            'HTTP_X_FORWARDED_FOR': '',
137            'HTTP_X_REAL_IP': '177.139.233.132',
138            'REMOTE_ADDR': '177.139.233.133',
139        }
140        ip = address_parser.get_real_ip(request)
141        self.assertEqual(ip, "177.139.233.132")
142
143    def test_empty_http_x_forwarded_for_empty_x_real_ip_fallback_on_remote_addr(self):
144        request = {
145            'HTTP_X_FORWARDED_FOR': '',
146            'HTTP_X_REAL_IP': '',
147            'REMOTE_ADDR': '177.139.233.133',
148        }
149        ip = address_parser.get_real_ip(request)
150        self.assertEqual(ip, "177.139.233.133")
151
152    def test_empty_http_x_forwarded_for_private_x_real_ip_fallback_on_remote_addr(self):
153        request = {
154            'HTTP_X_FORWARDED_FOR': '',
155            'HTTP_X_REAL_IP': '192.168.255.182',
156            'REMOTE_ADDR': '177.139.233.133',
157        }
158        ip = address_parser.get_real_ip(request)
159        self.assertEqual(ip, "177.139.233.133")
160
161    def test_private_http_x_forward_for_ip_addr(self):
162        request = {
163            'HTTP_X_FORWARDED_FOR': '127.0.0.1',
164            'HTTP_X_REAL_IP': '',
165            'REMOTE_ADDR': '',
166        }
167        ip = address_parser.get_real_ip(request)
168        self.assertEqual(ip, None)
169
170    def test_private_remote_addr_for_ip_addr(self):
171        request = {
172            'HTTP_X_FORWARDED_FOR': '',
173            'REMOTE_ADDR': '127.0.0.1',
174        }
175        ip = address_parser.get_real_ip(request)
176        self.assertEqual(ip, None)
177
178    def test_missing_x_forwarded(self):
179        request = {
180            'REMOTE_ADDR': '177.139.233.133',
181        }
182        ip = address_parser.get_real_ip(request)
183        self.assertEqual(ip, "177.139.233.133")
184
185    def test_missing_x_forwarded_missing_real_ip(self):
186        request = {
187            'REMOTE_ADDR': '177.139.233.133',
188        }
189        ip = address_parser.get_real_ip(request)
190        self.assertEqual(ip, "177.139.233.133")
191
192    def test_best_matched_real_ip(self):
193        request = {
194            'HTTP_X_REAL_IP': '127.0.0.1',
195            'REMOTE_ADDR': '172.31.233.133',
196        }
197        ip = address_parser.get_ip(request)
198        self.assertEqual(ip, "172.31.233.133")
199
200    def test_best_matched_private_ip(self):
201        request = {
202            'HTTP_X_REAL_IP': '127.0.0.1',
203            'REMOTE_ADDR': '192.31.233.133',
204        }
205        ip = address_parser.get_ip(request)
206        self.assertEqual(ip, "192.31.233.133")
207
208    def test_best_matched_private_ip_2(self):
209        request = {
210            'HTTP_X_REAL_IP': '192.31.233.133',
211            'REMOTE_ADDR': '127.0.0.1',
212        }
213        ip = address_parser.get_ip(request)
214        self.assertEqual(ip, "192.31.233.133")
215
216    def test_x_forwarded_for_multiple(self):
217        request = {
218            'X_FORWARDED_FOR': '192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139',
219            'REMOTE_ADDR': '177.139.233.133',
220        }
221        ip = address_parser.get_real_ip(request)
222        self.assertEqual(ip, "198.84.193.157")
223
224    def test_x_forwarded_for_multiple_left_most_ip(self):
225        request = {
226            'X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
227            'REMOTE_ADDR': '177.139.233.133',
228        }
229        ip = address_parser.get_real_ip(request)
230        self.assertEqual(ip, "198.84.193.157")
231
232    def test_x_forwarded_for_multiple_right_most_ip(self):
233        request = {
234            'X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
235            'REMOTE_ADDR': '177.139.233.133',
236        }
237        ip = address_parser.get_real_ip(request, right_most_proxy=True)
238        self.assertEqual(ip, "177.139.233.139")
239
240    def test_x_forwarded_for_multiple_right_most_ip_private(self):
241        request = {
242            'X_FORWARDED_FOR': '192.168.255.182, 198.84.193.157, 10.0.0.0, 127.0.0.1, 177.139.233.139',
243            'REMOTE_ADDR': '177.139.233.133',
244        }
245        ip = address_parser.get_real_ip(request, right_most_proxy=True)
246        self.assertEqual(ip, "177.139.233.139")
247
248    def test_x_forwarded_for_multiple_bad_address(self):
249        request = {
250            'X_FORWARDED_FOR': 'unknown, 192.168.255.182, 10.0.0.0, 127.0.0.1, 198.84.193.157, 177.139.233.139',
251            'REMOTE_ADDR': '177.139.233.133',
252        }
253        ip = address_parser.get_real_ip(request)
254        self.assertEqual(ip, "198.84.193.157")
255
256    def test_x_forwarded_for_singleton(self):
257        request = {
258            'X_FORWARDED_FOR': '177.139.233.139',
259            'REMOTE_ADDR': '177.139.233.133',
260        }
261        ip = address_parser.get_real_ip(request)
262        self.assertEqual(ip, "177.139.233.139")
263
264    def test_x_forwarded_for_singleton_private_address(self):
265        request = {
266            'X_FORWARDED_FOR': '192.168.255.182',
267            'REMOTE_ADDR': '177.139.233.133',
268        }
269        ip = address_parser.get_real_ip(request)
270        self.assertEqual(ip, "177.139.233.133")
271
272    def test_bad_x_forwarded_for_fallback_on_x_real_ip(self):
273        request = {
274            'X_FORWARDED_FOR': 'unknown 177.139.233.139',
275            'REMOTE_ADDR': '177.139.233.133',
276        }
277        ip = address_parser.get_real_ip(request)
278        self.assertEqual(ip, "177.139.233.133")
279
280    def test_empty_x_forwarded_for_fallback_on_x_real_ip(self):
281        request = {
282            'X_FORWARDED_FOR': '',
283            'REMOTE_ADDR': '177.139.233.133',
284        }
285        ip = address_parser.get_real_ip(request)
286        self.assertEqual(ip, "177.139.233.133")
287
288    def test_empty_x_forwarded_for_empty_x_real_ip_fallback_on_remote_addr(self):
289        request = {
290            'X_FORWARDED_FOR': '',
291            'REMOTE_ADDR': '177.139.233.133',
292        }
293        ip = address_parser.get_real_ip(request)
294        self.assertEqual(ip, "177.139.233.133")
295
296    def test_empty_x_forwarded_for_private_x_real_ip_fallback_on_remote_addr(self):
297        request = {
298            'X_FORWARDED_FOR': '',
299            'REMOTE_ADDR': '177.139.233.133',
300        }
301        ip = address_parser.get_real_ip(request)
302        self.assertEqual(ip, "177.139.233.133")
303
304    def test_private_x_forward_for_ip_addr(self):
305        request = {
306            'X_FORWARDED_FOR': '127.0.0.1',
307            'REMOTE_ADDR': '',
308        }
309        ip = address_parser.get_real_ip(request)
310        self.assertEqual(ip, None)
311
312    def test_x_forwarded_for_singleton_hyphen_as_delimiter(self):
313        request = {
314            'X-FORWARDED-FOR': '177.139.233.139',
315            'REMOTE-ADDR': '177.139.233.133',
316        }
317        ip = address_parser.get_real_ip(request)
318        self.assertEqual(ip, "177.139.233.139")
319
320
321class IPv4TrustedProxiesTestCase(TestCase):
322    """Trusted Proxies - IP address Test"""
323
324    def test_meta_none(self):
325        request = {
326        }
327        ip = address_parser.get_trusted_ip(request)
328        self.assertIsNone(ip)
329
330    def test_http_x_forwarded_for_conf_settings(self):
331        request = {
332            'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.100',
333        }
334
335        ip = address_parser.get_trusted_ip(request)
336        self.assertEqual(ip, "198.84.193.157")
337
338    def test_http_x_forwarded_for_no_proxy(self):
339        request = {
340            'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
341        }
342        ip = address_parser.get_trusted_ip(request, trusted_proxies=[])
343        self.assertIsNone(ip)
344
345    def test_http_x_forwarded_for_single_proxy(self):
346        request = {
347            'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
348        }
349        ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.139'])
350        self.assertEqual(ip, "198.84.193.157")
351
352    def test_http_x_forwarded_for_single_proxy_with_right_most(self):
353        request = {
354            'HTTP_X_FORWARDED_FOR': '177.139.233.139, 177.139.200.139, 198.84.193.157',
355        }
356        ip = address_parser.get_trusted_ip(request, right_most_proxy=True, trusted_proxies=['177.139.233.139'])
357        self.assertEqual(ip, "198.84.193.157")
358
359    def test_http_x_forwarded_for_multi_proxy(self):
360        request = {
361            'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
362        }
363        ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.138', '177.139.233.139'])
364        self.assertEqual(ip, "198.84.193.157")
365
366    def test_http_x_forwarded_for_all_proxies_in_subnet(self):
367        request = {
368            'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
369        }
370        ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233'])
371        self.assertEqual(ip, "198.84.193.157")
372
373    def test_http_x_forwarded_for_all_proxies_in_subnet_2(self):
374        request = {
375            'HTTP_X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
376        }
377        ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139'])
378        self.assertEqual(ip, "198.84.193.157")
379
380    def test_x_forwarded_for_single_proxy(self):
381        request = {
382            'X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
383        }
384        ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.139'])
385        self.assertEqual(ip, "198.84.193.157")
386
387    def test_x_forwarded_for_single_proxy_hyphens(self):
388        request = {
389            'X-FORWARDED-FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
390        }
391        ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.139'])
392        self.assertEqual(ip, "198.84.193.157")
393
394    def test_http_x_forwarded_for_and_x_forward_for_single_proxy(self):
395        request = {
396            'HTTP_X_FORWARDED_FOR': '198.84.193.156, 177.139.200.139, 177.139.233.139',
397            'X_FORWARDED_FOR': '198.84.193.157, 177.139.200.139, 177.139.233.139',
398        }
399        ip = address_parser.get_trusted_ip(request, trusted_proxies=['177.139.233.139'])
400        self.assertEqual(ip, "198.84.193.156")
401
402
403class IPv6TestCase(TestCase):
404    """IP address Test"""
405
406    def test_http_x_forwarded_for_multiple(self):
407        request = {
408            'HTTP_X_FORWARDED_FOR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba',
409            'HTTP_X_REAL_IP': '74dc::02ba',
410            'REMOTE_ADDR': '74dc::02ba',
411        }
412        ip = address_parser.get_real_ip(request)
413        self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
414
415    def test_http_x_forwarded_for_multiple_bad_address(self):
416        request = {
417            'HTTP_X_FORWARDED_FOR': 'unknown, ::1/128, 74dc::02ba',
418            'HTTP_X_REAL_IP': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
419            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
420        }
421        ip = address_parser.get_real_ip(request)
422        self.assertEqual(ip, "74dc::02ba")
423
424    def test_http_x_forwarded_for_singleton(self):
425        request = {
426            'HTTP_X_FORWARDED_FOR': '74dc::02ba',
427            'HTTP_X_REAL_IP': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
428            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
429        }
430        ip = address_parser.get_real_ip(request)
431        self.assertEqual(ip, "74dc::02ba")
432
433    def test_http_x_forwarded_for_singleton_private_address(self):
434        request = {
435            'HTTP_X_FORWARDED_FOR': '::1/128',
436            'HTTP_X_REAL_IP': '74dc::02ba',
437            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
438        }
439        ip = address_parser.get_real_ip(request)
440        self.assertEqual(ip, "74dc::02ba")
441
442    def test_bad_http_x_forwarded_for_fallback_on_x_real_ip(self):
443        request = {
444            'HTTP_X_FORWARDED_FOR': 'unknown ::1/128',
445            'HTTP_X_REAL_IP': '74dc::02ba',
446            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
447        }
448        ip = address_parser.get_real_ip(request)
449        self.assertEqual(ip, "74dc::02ba")
450
451    def test_empty_http_x_forwarded_for_fallback_on_x_real_ip(self):
452        request = {
453            'HTTP_X_FORWARDED_FOR': '',
454            'HTTP_X_REAL_IP': '74dc::02ba',
455            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
456        }
457        ip = address_parser.get_real_ip(request)
458        self.assertEqual(ip, "74dc::02ba")
459
460    def test_empty_http_x_forwarded_for_empty_x_real_ip_fallback_on_remote_addr(self):
461        request = {
462            'HTTP_X_FORWARDED_FOR': '',
463            'HTTP_X_REAL_IP': '',
464            'REMOTE_ADDR': '74dc::02ba',
465        }
466        ip = address_parser.get_real_ip(request)
467        self.assertEqual(ip, "74dc::02ba")
468
469    def test_empty_http_x_forwarded_for_private_x_real_ip_fallback_on_remote_addr(self):
470        request = {
471            'HTTP_X_FORWARDED_FOR': '',
472            'HTTP_X_REAL_IP': '::1/128',
473            'REMOTE_ADDR': '74dc::02ba',
474        }
475        ip = address_parser.get_real_ip(request)
476        self.assertEqual(ip, "74dc::02ba")
477
478    def test_private_http_x_forward_for_ip_addr(self):
479        request = {
480            'HTTP_X_FORWARDED_FOR': '::1/128',
481            'HTTP_X_REAL_IP': '',
482            'REMOTE_ADDR': '',
483        }
484        ip = address_parser.get_real_ip(request)
485        self.assertEqual(ip, None)
486
487    def test_private_real_ip_for_ip_addr(self):
488        request = {
489            'HTTP_X_FORWARDED_FOR': '',
490            'HTTP_X_REAL_IP': '::1/128',
491            'REMOTE_ADDR': '',
492        }
493        ip = address_parser.get_real_ip(request)
494        self.assertEqual(ip, None)
495
496    def test_private_remote_addr_for_ip_addr(self):
497        request = {
498            'HTTP_X_FORWARDED_FOR': '',
499            'HTTP_X_REAL_IP': '',
500            'REMOTE_ADDR': '::1/128',
501        }
502        ip = address_parser.get_real_ip(request)
503        self.assertEqual(ip, None)
504
505    def test_missing_x_forwarded(self):
506        request = {
507            'HTTP_X_REAL_IP': '74dc::02ba',
508            'REMOTE_ADDR': '74dc::02ba',
509        }
510        ip = address_parser.get_real_ip(request)
511        self.assertEqual(ip, "74dc::02ba")
512
513    def test_missing_x_forwarded_missing_real_ip(self):
514        request = {
515            'REMOTE_ADDR': '74dc::02ba',
516        }
517        ip = address_parser.get_real_ip(request)
518        self.assertEqual(ip, "74dc::02ba")
519
520    def test_missing_x_forwarded_missing_real_ip_mix_case(self):
521        request = {
522            'REMOTE_ADDR': '74DC::02BA',
523        }
524        ip = address_parser.get_real_ip(request)
525        self.assertEqual(ip, "74dc::02ba")
526
527    def test_private_remote_address(self):
528        request = {
529            'REMOTE_ADDR': 'fe80::02ba',
530        }
531        ip = address_parser.get_real_ip(request)
532        self.assertEqual(ip, None)
533
534    def test_best_matched_real_ip(self):
535        request = {
536            'HTTP_X_REAL_IP': '::1',
537            'REMOTE_ADDR': 'fe80::02ba',
538        }
539        ip = address_parser.get_ip(request)
540        self.assertEqual(ip, "fe80::02ba")
541
542    def test_x_forwarded_for_multiple(self):
543        request = {
544            'X_FORWARDED_FOR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba',
545            'REMOTE_ADDR': '74dc::02ba',
546        }
547        ip = address_parser.get_real_ip(request)
548        self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
549
550    def test_x_forwarded_for_multiple_bad_address(self):
551        request = {
552            'X_FORWARDED_FOR': 'unknown, ::1/128, 74dc::02ba',
553            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
554        }
555        ip = address_parser.get_real_ip(request)
556        self.assertEqual(ip, "74dc::02ba")
557
558    def test_x_forwarded_for_singleton(self):
559        request = {
560            'X_FORWARDED_FOR': '74dc::02ba',
561            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
562        }
563        ip = address_parser.get_real_ip(request)
564        self.assertEqual(ip, "74dc::02ba")
565
566    def test_x_forwarded_for_singleton_private_address(self):
567        request = {
568            'X_FORWARDED_FOR': '::1/128',
569            'HTTP_X_REAL_IP': '74dc::02ba',
570            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
571        }
572        ip = address_parser.get_real_ip(request)
573        self.assertEqual(ip, "74dc::02ba")
574
575    def test_bad_x_forwarded_for_fallback_on_x_real_ip(self):
576        request = {
577            'X_FORWARDED_FOR': 'unknown ::1/128',
578            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
579        }
580        ip = address_parser.get_real_ip(request)
581        self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
582
583    def test_empty_x_forwarded_for_fallback_on_x_real_ip(self):
584        request = {
585            'X_FORWARDED_FOR': '',
586            'REMOTE_ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
587        }
588        ip = address_parser.get_real_ip(request)
589        self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
590
591    def test_empty_x_forwarded_for_empty_x_real_ip_fallback_on_remote_addr(self):
592        request = {
593            'X_FORWARDED_FOR': '',
594            'REMOTE_ADDR': '74dc::02ba',
595        }
596        ip = address_parser.get_real_ip(request)
597        self.assertEqual(ip, "74dc::02ba")
598
599    def test_empty_x_forwarded_for_private_x_real_ip_fallback_on_remote_addr(self):
600        request = {
601            'X_FORWARDED_FOR': '',
602            'REMOTE_ADDR': '74dc::02ba',
603        }
604        ip = address_parser.get_real_ip(request)
605        self.assertEqual(ip, "74dc::02ba")
606
607    def test_private_x_forward_for_ip_addr(self):
608        request = {
609            'X_FORWARDED_FOR': '::1/128',
610            'REMOTE_ADDR': '',
611        }
612        ip = address_parser.get_real_ip(request)
613        self.assertEqual(ip, None)
614
615    def test_x_forwarded_for_singleton_hyphen_as_delimiter(self):
616        request = {
617            'X-FORWARDED-FOR': '74dc::02ba',
618            'REMOTE-ADDR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf',
619        }
620        ip = address_parser.get_real_ip(request)
621        self.assertEqual(ip, "74dc::02ba")
622
623
624class IPv6TrustedProxiesTestCase(TestCase):
625    """Trusted Proxies - IP address Test"""
626
627    def test_http_x_forwarded_for_no_proxy(self):
628        request = {
629            'HTTP_X_FORWARDED_FOR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba',
630        }
631        ip = address_parser.get_trusted_ip(request, trusted_proxies=[])
632        self.assertIsNone(ip)
633
634    def test_http_x_forwarded_for_single_proxy(self):
635        request = {
636            'HTTP_X_FORWARDED_FOR': '3ffe:1900:4545:3:200:f8ff:fe21:67cf, 74dc::02ba',
637        }
638        ip = address_parser.get_trusted_ip(request, trusted_proxies=['74dc::02ba'])
639        self.assertEqual(ip, "3ffe:1900:4545:3:200:f8ff:fe21:67cf")
640