Skip to content

Commit de614b1

Browse files
committed
Allow passing a Request instance for the url parameter
1 parent 3686013 commit de614b1

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

Lib/test/test_robotparser.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,65 @@ def testPasswordProtectedSite(self):
346346
self.assertFalse(parser.can_fetch("*", robots_url))
347347

348348

349+
class UserAgentRobotHandler(BaseHTTPRequestHandler):
350+
351+
def do_GET(self):
352+
if self.headers.get('User-Agent').startswith('Python-urllib'):
353+
self.send_error(403, "Forbidden access")
354+
else:
355+
self.send_response(200)
356+
self.end_headers()
357+
self.wfile.write(b"User-agent: *\nDisallow:")
358+
359+
def log_message(self, format, *args):
360+
pass
361+
362+
363+
@unittest.skipUnless(
364+
support.has_socket_support,
365+
"Socket server requires working socket."
366+
)
367+
class UserAgentSiteTestCase(unittest.TestCase):
368+
369+
def setUp(self):
370+
# clear _opener global variable
371+
self.addCleanup(urllib.request.urlcleanup)
372+
373+
self.server = HTTPServer((socket_helper.HOST, 0), UserAgentRobotHandler)
374+
375+
self.t = threading.Thread(
376+
name='HTTPServer serving',
377+
target=self.server.serve_forever,
378+
# Short poll interval to make the test finish quickly.
379+
# Time between requests is short enough that we won't wake
380+
# up spuriously too many times.
381+
kwargs={'poll_interval':0.01})
382+
self.t.daemon = True # In case this function raises.
383+
self.t.start()
384+
385+
def tearDown(self):
386+
self.server.shutdown()
387+
self.t.join()
388+
self.server.server_close()
389+
390+
@threading_helper.reap_threads
391+
def testUserAgentFilteringSite(self):
392+
addr = self.server.server_address
393+
url = 'http://' + socket_helper.HOST + ':' + str(addr[1])
394+
robots_url = url + "/robots.txt"
395+
file_url = url + "/document"
396+
parser = urllib.robotparser.RobotFileParser()
397+
parser.set_url(robots_url)
398+
parser.read()
399+
self.assertTrue(parser.disallow_all)
400+
self.assertFalse(parser.can_fetch("*", file_url))
401+
parser = urllib.robotparser.RobotFileParser()
402+
parser.set_url(urllib.request.Request(robots_url, headers={'User-Agent': 'cybermapper'}))
403+
parser.read()
404+
self.assertFalse(parser.disallow_all)
405+
self.assertTrue(parser.can_fetch("*", file_url))
406+
407+
349408
@support.requires_working_socket()
350409
class NetworkTestCase(unittest.TestCase):
351410

Lib/urllib/robotparser.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ def modified(self):
5454
def set_url(self, url):
5555
"""Sets the URL referring to a robots.txt file."""
5656
self.url = url
57-
self.host, self.path = urllib.parse.urlparse(url)[1:3]
57+
58+
if isinstance(url, urllib.request.Request):
59+
self.host = url.host
60+
self.path = url.selector
61+
else:
62+
self.host, self.path = urllib.parse.urlparse(url)[1:3]
5863

5964
def read(self):
6065
"""Reads the robots.txt URL and feeds it to the parser."""

0 commit comments

Comments
 (0)