]>
Commit | Line | Data |
---|---|---|
19a8d9a0 MT |
1 | #!/usr/bin/python |
2 | ||
16d373bc MT |
3 | import os |
4 | import random | |
5 | import urllib2 | |
6 | import urlparse | |
7 | import cgi | |
918e8b8c | 8 | import time |
16d373bc | 9 | from mimetypes import guess_type |
19a8d9a0 | 10 | |
1e299f1d | 11 | access = open("access.log", "a") |
4f4bd9b0 | 12 | error = open("error.log", "a") |
19a8d9a0 | 13 | |
16d373bc MT |
14 | hosts = ( |
15 | # PRIO SCHEME HOSTNAME PATH | |
2ad76ddf | 16 | ( 2, "http", "mirror1.ipfire.org", "/",), |
89fa8fa9 | 17 | (10, "http", "mirror2.ipfire.org", "/",), |
308d7835 | 18 | ( 4, "http", "mirror3.ipfire.org", "/",), |
837e3550 | 19 | ( 4, "http", "mirror5.ipfire.org", "/",), |
cf550d55 | 20 | (10, "http", "www.rowie.at", "/ipfire/",), |
2ad76ddf MT |
21 | ( 8, "http", "ipfire.earl-net.com", "/",), |
22 | ( 8, "http", "ipfire.kbarthel.de", "/",), | |
23 | ( 8, "http", "ipfire.1l0v3u.com", "/",), | |
9a2aca8d | 24 | ( 8, "http", "kraefte.net", "/ipfire",), |
9161dada | 25 | ( 8, "http", "ipfiremirror.wintertech.de", "/",), |
16d373bc MT |
26 | ) |
27 | ||
28 | def rnd(servers): | |
29 | return random.randint(0, len(servers)-1) | |
19a8d9a0 | 30 | |
16d373bc MT |
31 | def servefile(file): |
32 | mimetype = guess_type(file)[0] or "text/plain" | |
33 | f = open(file, "rb") | |
34 | size = os.fstat(f.fileno()).st_size | |
35 | print "Status: 200 OK" | |
36 | print "Content-Type:", mimetype | |
37 | if size: | |
38 | print "Content-Length:", size | |
19a8d9a0 | 39 | |
16d373bc | 40 | print f.read(), |
19a8d9a0 | 41 | f.close() |
16d373bc MT |
42 | |
43 | class Server: | |
44 | def __init__(self, scheme="http", hostname=None, path=None, priority=0): | |
45 | self.hostname = hostname | |
46 | self.path = path | |
47 | ||
48 | self.scheme = scheme | |
49 | self.priority = priority | |
50 | ||
51 | def url(self): | |
52 | return "%s://%s%s" % (self.scheme, self.hostname, self.path) | |
53 | ||
54 | def __str__(self): | |
55 | return self.url() | |
56 | ||
57 | def __repr__(self): | |
58 | return "<%s.%s %s>" % (__name__, __class__, self.__str__()) | |
59 | ||
60 | def noping(self): | |
61 | return os.system("ping -c1 -w1 %s &>/dev/null" % self.hostname) | |
62 | ||
63 | def file(self, file): | |
64 | ret = None | |
65 | try: | |
66 | f = urllib2.urlopen("%s" % urlparse.urljoin(self.url(), file)) | |
67 | except (urllib2.HTTPError, urllib2.URLError), e: | |
4f4bd9b0 | 68 | if error: |
918e8b8c | 69 | error.write("%s " % time.asctime()) |
4f4bd9b0 | 70 | error.write("ERR 500 - %s %s\n" % (self.url(), e)) |
19a8d9a0 | 71 | else: |
16d373bc MT |
72 | ret = f.geturl() |
73 | f.close() | |
74 | return ret | |
75 | ||
76 | class Servers: | |
77 | def __init__(self): | |
78 | self.servers = [] | |
79 | self.prio_servers = [] | |
80 | ||
81 | def __call__(self): | |
82 | return self.all() | |
83 | ||
84 | def all(self): | |
85 | return self.servers | |
19a8d9a0 | 86 | |
16d373bc MT |
87 | def shuffled(self): |
88 | tmp = [] | |
89 | for server in self.all(): | |
90 | for priority in range(0, server.priority): | |
91 | tmp.append(server) | |
92 | return tmp | |
19a8d9a0 | 93 | |
16d373bc MT |
94 | def one(self): |
95 | servers = self.shuffled() | |
96 | return servers[rnd(servers)] | |
19a8d9a0 | 97 | |
16d373bc MT |
98 | def add(self, server): |
99 | self.servers.append(server) | |
100 | ||
101 | def rem(self, server): | |
102 | tmp = [] | |
103 | for host in self.all(): | |
104 | if not host == server: | |
105 | tmp.append(host) | |
106 | self.servers = tmp | |
107 | ||
108 | # main() | |
109 | servers = Servers() | |
110 | for (priority, scheme, hostname, path) in hosts: | |
111 | servers.add(Server(scheme=scheme, hostname=hostname, path=path, priority=priority)) | |
112 | ||
113 | file = cgi.FieldStorage().getfirst("file") | |
114 | ||
115 | while servers.all(): | |
116 | server = servers.one() | |
117 | ||
118 | if server.noping(): | |
119 | servers.rem(server) | |
120 | continue | |
121 | ||
122 | url = server.file(file) | |
123 | if not url: | |
124 | servers.rem(server) | |
125 | continue | |
126 | ||
127 | print "Status: 302 Moved Temporarily" | |
128 | print "Location:", url | |
129 | print "Pragma: no-cache" | |
130 | ||
131 | ||
918e8b8c | 132 | access.write("%s " % time.asctime()) |
1e299f1d | 133 | access.write("%s\n" % url) |
16d373bc MT |
134 | |
135 | break | |
19a8d9a0 | 136 | else: |
070904cd MT |
137 | error.write("%s " % time.asctime()) |
138 | error.write("%s was not found on mirror servers. Trying local.\n" % file) | |
139 | filename = ".%s" % file | |
140 | if os.access(filename, os.R_OK): | |
141 | access.write("%s " % time.asctime()) | |
142 | access.write("(local) %s\n" % filename) | |
143 | servefile(filename) | |
16d373bc MT |
144 | else: |
145 | print "Status: 404 Not Found" | |
146 | print "Pragma: no-cache" | |
147 | ||
148 | ||
4f4bd9b0 | 149 | if error: |
918e8b8c | 150 | error.write("%s " % time.asctime()) |
4f4bd9b0 | 151 | error.write("ERR 404 - %s wasn't found on any server" % file) |
16d373bc | 152 | |
1e299f1d | 153 | access.close() |
4f4bd9b0 MT |
154 | if error: |
155 | error.close() |