gPodder 3.7.0 for Harmattan
[gpodder.git] / tools / test-auth-server.py
blob91b17f852e87e2934a175f563b3a5bfeed162fe7
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # Simple HTTP web server for testing HTTP Authentication (see bug 1539)
4 # from our crappy-but-does-the-job department
5 # Thomas Perl <thp.io/about>; 2012-01-20
7 import BaseHTTPServer
8 import sys
9 import re
10 import hashlib
11 import datetime
13 USERNAME = 'user@example.com' # Username used for HTTP Authentication
14 PASSWORD = 'secret' # Password used for HTTP Authentication
16 HOST, PORT = 'localhost', 8000 # Hostname and port for the HTTP server
18 # When the script contents change, the feed's episodes each get a new GUID
19 GUID = hashlib.sha1(open(__file__).read()).hexdigest()
21 URL = 'http://%(HOST)s:%(PORT)s' % locals()
23 FEEDNAME = sys.argv[0] # The title of the RSS feed
24 FEEDFILE = 'feed.rss' # The "filename" of the feed on the server
25 EPISODES = 'episode' # Base name for the episode files
26 EPISODES_EXT = '.mp3' # Extension for the episode files
27 EPISODES_MIME = 'audio/mpeg' # Mime type for the episode files
28 EP_COUNT = 7 # Number of episodes in the feed
29 SIZE = 500000 # Size (in bytes) of the episode downloads)
31 def mkpubdates(items):
32 """Generate fake pubDates (one each day, recently)"""
33 current = datetime.datetime.now() - datetime.timedelta(days=items+3)
34 for i in range(items):
35 yield current.ctime()
36 current += datetime.timedelta(days=1)
38 def mkrss(items=EP_COUNT):
39 """Generate a dumm RSS feed with a given number of items"""
40 ITEMS = '\n'.join("""
41 <item>
42 <title>Episode %(INDEX)s</title>
43 <guid>tag:test.gpodder.org,2012:%(GUID)s,%(URL)s,%(INDEX)s</guid>
44 <pubDate>%(PUBDATE)s</pubDate>
45 <enclosure
46 url="%(URL)s/%(EPISODES)s%(INDEX)s%(EPISODES_EXT)s"
47 type="%(EPISODES_MIME)s"
48 length="%(SIZE)s"/>
49 </item>
50 """ % dict(locals().items()+globals().items())
51 for INDEX, PUBDATE in enumerate(mkpubdates(items)))
53 return """
54 <rss>
55 <channel><title>%(FEEDNAME)s</title><link>%(URL)s</link>
56 %(ITEMS)s
57 </channel>
58 </rss>
59 """ % dict(locals().items()+globals().items())
61 def mkdata(size=SIZE):
62 """Generate dummy data of a given size (in bytes)"""
63 return ''.join(chr(32+(i%(127-32))) for i in range(size))
65 class AuthRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
66 FEEDFILE_PATH = '/%s' % FEEDFILE
67 EPISODES_PATH = '/%s' % EPISODES
69 def do_GET(self):
70 authorized = False
71 is_feed = False
72 is_episode = False
74 auth_header = self.headers.get('authorization', '')
75 m = re.match(r'^Basic (.*)$', auth_header)
76 if m is not None:
77 auth_data = m.group(1).decode('base64').split(':', 1)
78 if len(auth_data) == 2:
79 username, password = auth_data
80 print 'Got username:', username
81 print 'Got password:', password
82 if (username, password) == (USERNAME, PASSWORD):
83 print 'Valid credentials provided.'
84 authorized = True
86 if self.path == self.FEEDFILE_PATH:
87 print 'Feed request.'
88 is_feed = True
89 elif self.path.startswith(self.EPISODES_PATH):
90 print 'Episode request.'
91 is_episode = True
93 if not authorized:
94 print 'Not authorized - sending WWW-Authenticate header.'
95 self.send_response(401)
96 self.send_header('WWW-Authenticate',
97 'Basic realm="%s"' % sys.argv[0])
98 self.end_headers()
99 self.wfile.close()
100 return
102 self.send_response(200)
103 self.send_header('Content-type',
104 'application/xml' if is_feed else 'audio/mpeg')
105 self.end_headers()
106 self.wfile.write(mkrss() if is_feed else mkdata())
107 self.wfile.close()
110 if __name__ == '__main__':
111 httpd = BaseHTTPServer.HTTPServer((HOST, PORT), AuthRequestHandler)
112 print """
113 Feed URL: %(URL)s/%(FEEDFILE)s
114 Username: %(USERNAME)s
115 Password: %(PASSWORD)s
116 """ % locals()
117 while True:
118 httpd.handle_request()