]> git.ipfire.org Git - ipfire.org.git/blame - source/dlhandler.py
Added pxe site.
[ipfire.org.git] / source / dlhandler.py
CommitLineData
818a4490 1#!/usr/bin/python
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5# Copyright (C) 2007 Michael Tremer & Christian Schmidt #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
22import os
23import cgi
516a72ab
MT
24import sys
25import sha
26from pysqlite2 import dbapi2 as sqlite
27
28sys.path.append(".")
29
818a4490 30from git import *
31
141ef101
MT
32SOURCE_BASE = "/srv/sources"
33
6a170c4e
MT
34def give_403():
35 print "Status: 403 Forbidden"
36 print "Pragma: no-cache"
37 print "Cache-control: no-cache"
38 print "Connection: close"
39 print
40 print
516a72ab 41 sys.exit()
6a170c4e 42
818a4490 43def give_404():
44 print "Status: 404 Not found"
45 print "Pragma: no-cache"
46 print "Cache-control: no-cache"
47 print "Connection: close"
48 print
6a170c4e 49 print
516a72ab 50 sys.exit()
818a4490 51
52def give_302():
53 print "Status: 302 Moved"
54 print "Location: /"
55 print "Pragma: no-cache"
56 print "Cache-control: no-cache"
57 print "Connection: close"
58 print
59 print
516a72ab 60 sys.exit()
818a4490 61
62class NotFoundError(Exception):
63 pass
64
65class SourceObject:
516a72ab
MT
66 def __init__(self, file):
67 self.file = file
68
69 self.db = sqlite.connect("hashes.db")
70 c = self.db.cursor()
71 c.execute("CREATE TABLE IF NOT EXISTS hashes(file, sha1)")
72 c.close()
73
74 def getHash(self, type="sha1"):
75 hash = None
76 c = self.db.cursor()
77 c.execute("SELECT %s FROM hashes WHERE file = '%s'" % (type, self.file,))
78 try:
79 hash = c.fetchone()[0]
80 except TypeError:
81 pass
82 c.close()
83
84 if not hash:
85 hash = sha.new(self.filedata).hexdigest()
86 c = self.db.cursor()
87 c.execute("INSERT INTO hashes(file, sha1) VALUES('%s', '%s')" % \
88 (self.file, hash,))
89 c.close()
90 self.db.commit()
91 return hash
92
93 def __call__(self):
94 print "Status: 200 - OK"
818a4490 95 print "Pragma: no-cache"
96 print "Cache-control: no-cache"
97 print "Connection: close"
516a72ab
MT
98 print "Content-type: " + self.getMimetype()
99 print "Content-length: %s" % len(self.filedata)
100 print "X-SHA1: " + self.getHash("sha1")
101 print "X-Object: %s" % str(self.__class__).split(".")[1]
102 print # An empty line ends the header
103 print self.filedata
104
818a4490 105
106class FileObject(SourceObject):
516a72ab
MT
107 def __init__(self, path, file):
108 SourceObject.__init__(self, file)
109 self.path = path
141ef101 110 self.filepath = "/%s/%s/%s" % (SOURCE_BASE, path, file,)
516a72ab 111
818a4490 112 try:
113 f = open(self.filepath, "rb")
114 except:
115 raise NotFoundError
116
117 self.filedata = f.read()
118 f.close()
119
516a72ab 120 def getMimetype(self):
818a4490 121 default_mimetype = "text/plain"
122 from mimetypes import guess_type
123 return guess_type(self.filepath)[0] or default_mimetype
124
818a4490 125
516a72ab
MT
126class PatchObject(SourceObject):
127 def __init__(self, file, url="/srv/git/patches.git"):
128 SourceObject.__init__(self, file)
818a4490 129 self.url = url
818a4490 130
818a4490 131 self.repo = Repository(self.url)
516a72ab 132 tree = self.repo.head.tree
818a4490 133 blob = None
516a72ab
MT
134
135 for directory in tree.keys():
136 if isinstance(tree[directory], Blob):
818a4490 137 continue
138 try:
516a72ab 139 blob = tree[directory][self.file]
818a4490 140 if blob:
141 break
142 except KeyError:
143 pass
516a72ab 144
818a4490 145 if not blob:
146 raise NotFoundError
147
148 blob._load()
149 self.filedata = blob._contents
520933d9 150 self.filedata += '\n'
818a4490 151
516a72ab
MT
152 def getMimetype(self):
153 return "text/plain"
818a4490 154
728dfc54 155
516a72ab
MT
156def main():
157 os.environ["QUERY_STRING"] = \
158 os.environ["QUERY_STRING"].replace("+", "%2b")
818a4490 159
516a72ab
MT
160 file = cgi.FieldStorage().getfirst("file")
161 path = cgi.FieldStorage().getfirst("path")
6a170c4e 162
516a72ab
MT
163 if not os.environ["HTTP_USER_AGENT"].startswith("IPFireSourceGrabber"):
164 give_403()
818a4490 165
516a72ab
MT
166 if not file:
167 give_302()
818a4490 168
afbaaece 169 if not path or path == "download":
516a72ab
MT
170 path = "source-3.x"
171
172 # At first, we assume that the requested object is a plain file:
818a4490 173 try:
516a72ab 174 object = FileObject(path=path, file=file)
818a4490 175 except NotFoundError:
516a72ab
MT
176 # Second, we assume that the requestet object is in the patch repo:
177 try:
178 object = PatchObject(file=file)
179 except NotFoundError:
180 give_404()
181 else:
182 object()
818a4490 183 else:
516a72ab
MT
184 object()
185
186try:
187 main()
188except SystemExit:
189 pass