@@ -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: *\n Disallow:" )
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 ()
350409class NetworkTestCase (unittest .TestCase ):
351410
0 commit comments