Commit 3495d0c4 authored by Guido van Rossum's avatar Guido van Rossum

One fix by sjoerd and one suggested by him. Bumped __version__ to 1.5.

Fix 1: add a method geturl() to the file-like object returned by urlopen().
Fix 2: treat http error 301 the same as error 302.
parent 8b9ca8c5
...@@ -20,7 +20,7 @@ import regex ...@@ -20,7 +20,7 @@ import regex
import os import os
__version__ = '1.4' __version__ = '1.5'
# Helper for non-unix systems # Helper for non-unix systems
if os.name == 'mac': if os.name == 'mac':
...@@ -115,6 +115,7 @@ class URLopener: ...@@ -115,6 +115,7 @@ class URLopener:
fullurl = unwrap(fullurl) fullurl = unwrap(fullurl)
type, url = splittype(fullurl) type, url = splittype(fullurl)
if not type: type = 'file' if not type: type = 'file'
self.openedurl = '%s:%s' % (type, url)
if self.proxies.has_key(type): if self.proxies.has_key(type):
proxy = self.proxies[type] proxy = self.proxies[type]
type, proxy = splittype(proxy) type, proxy = splittype(proxy)
...@@ -204,7 +205,7 @@ class URLopener: ...@@ -204,7 +205,7 @@ class URLopener:
errcode, errmsg, headers = h.getreply() errcode, errmsg, headers = h.getreply()
fp = h.getfile() fp = h.getfile()
if errcode == 200: if errcode == 200:
return addinfo(fp, headers) return addinfourl(fp, headers, self.openedurl)
else: else:
return self.http_error(url, return self.http_error(url,
fp, errcode, errmsg, headers) fp, errcode, errmsg, headers)
...@@ -241,7 +242,7 @@ class URLopener: ...@@ -241,7 +242,7 @@ class URLopener:
fp = gopherlib.send_query(selector, query, host) fp = gopherlib.send_query(selector, query, host)
else: else:
fp = gopherlib.send_selector(selector, host) fp = gopherlib.send_selector(selector, host)
return addinfo(fp, noheaders()) return addinfourl(fp, noheaders(), self.openedurl)
# Use local file or FTP depending on form of URL # Use local file or FTP depending on form of URL
def open_file(self, url): def open_file(self, url):
...@@ -253,12 +254,12 @@ class URLopener: ...@@ -253,12 +254,12 @@ class URLopener:
# Use local file # Use local file
def open_local_file(self, url): def open_local_file(self, url):
host, file = splithost(url) host, file = splithost(url)
if not host: return addinfo(open(url2pathname(file), 'r'), noheaders()) if not host: return addinfourl(open(url2pathname(file), 'r'), noheaders(), self.openedurl)
host, port = splitport(host) host, port = splitport(host)
if not port and socket.gethostbyname(host) in ( if not port and socket.gethostbyname(host) in (
localhost(), thishost()): localhost(), thishost()):
file = unquote(file) file = unquote(file)
return addinfo(open(url2pathname(file), 'r'), noheaders()) return addinfourl(open(url2pathname(file), 'r'), noheaders(), self.openedurl)
raise IOError, ('local file error', 'not on local host') raise IOError, ('local file error', 'not on local host')
# Use FTP protocol # Use FTP protocol
...@@ -290,8 +291,8 @@ class URLopener: ...@@ -290,8 +291,8 @@ class URLopener:
if string.lower(attr) == 'type' and \ if string.lower(attr) == 'type' and \
value in ('a', 'A', 'i', 'I', 'd', 'D'): value in ('a', 'A', 'i', 'I', 'd', 'D'):
type = string.upper(value) type = string.upper(value)
return addinfo(self.ftpcache[key].retrfile(file, type), return addinfourl(self.ftpcache[key].retrfile(file, type),
noheaders()) noheaders(), self.openedurl)
except ftperrors(), msg: except ftperrors(), msg:
raise IOError, ('ftp error', msg) raise IOError, ('ftp error', msg)
...@@ -305,9 +306,9 @@ class FancyURLopener(URLopener): ...@@ -305,9 +306,9 @@ class FancyURLopener(URLopener):
# Default error handling -- don't raise an exception # Default error handling -- don't raise an exception
def http_error_default(self, url, fp, errcode, errmsg, headers): def http_error_default(self, url, fp, errcode, errmsg, headers):
return addinfo(fp, headers) return addinfourl(fp, headers, self.openedurl)
# Error 302 -- relocated # Error 302 -- relocated (temporarily)
def http_error_302(self, url, fp, errcode, errmsg, headers): def http_error_302(self, url, fp, errcode, errmsg, headers):
# XXX The server can force infinite recursion here! # XXX The server can force infinite recursion here!
if headers.has_key('location'): if headers.has_key('location'):
...@@ -320,6 +321,9 @@ class FancyURLopener(URLopener): ...@@ -320,6 +321,9 @@ class FancyURLopener(URLopener):
fp.close() fp.close()
return self.open(newurl) return self.open(newurl)
# Error 301 -- also relocated (permanently)
http_error_301 = http_error_302
# Error 401 -- authentication required # Error 401 -- authentication required
# See this URL for a description of the basic authentication scheme: # See this URL for a description of the basic authentication scheme:
# http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt # http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt
...@@ -507,6 +511,17 @@ class addinfo(addbase): ...@@ -507,6 +511,17 @@ class addinfo(addbase):
def info(self): def info(self):
return self.headers return self.headers
# class to add info() and geturl() methods to an open file
class addinfourl(addbase):
def __init__(self, fp, headers, url):
addbase.__init__(self, fp)
self.headers = headers
self.url = url
def info(self):
return self.headers
def geturl(self):
return self.url
# Utility to combine a URL with a base URL to form a new URL # Utility to combine a URL with a base URL to form a new URL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment