71 return os.stat(cl_path).st_mtime |
71 return os.stat(cl_path).st_mtime |
72 else: |
72 else: |
73 return os.stat(hg_path).st_mtime |
73 return os.stat(hg_path).st_mtime |
74 |
74 |
75 def staticfile(directory, fname): |
75 def staticfile(directory, fname): |
76 fname = os.path.realpath(os.path.join(directory, fname)) |
76 """return a file inside directory with guessed content-type header |
77 |
77 |
|
78 fname always uses '/' as directory separator and isn't allowed to |
|
79 contain unusual path components. |
|
80 Content-type is guessed using the mimetypes module. |
|
81 Return an empty string if fname is illegal or file not found. |
|
82 |
|
83 """ |
|
84 parts = fname.split('/') |
|
85 path = directory |
|
86 for part in parts: |
|
87 if (part in ('', os.curdir, os.pardir) or |
|
88 os.sep in part or os.altsep is not None and os.altsep in part): |
|
89 return "" |
|
90 path = os.path.join(path, part) |
78 try: |
91 try: |
79 # the static dir should be a substring in the real |
92 os.stat(path) |
80 # file path, if it is not, we have something strange |
93 ct = mimetypes.guess_type(path)[0] or "text/plain" |
81 # going on => security breach attempt? |
94 return "Content-type: %s\n\n%s" % (ct, file(path).read()) |
82 # |
95 except (TypeError, OSError): |
83 # This will either: |
96 # illegal fname or unreadable file |
84 # 1) find the `static' path at index 0 = success |
|
85 # 2) find the `static' path at other index = error |
|
86 # 3) not find the `static' path = ValueError generated |
|
87 if fname.index(directory) != 0: |
|
88 # generate ValueError manually |
|
89 raise ValueError() |
|
90 |
|
91 os.stat(fname) |
|
92 |
|
93 ct = mimetypes.guess_type(fname)[0] or "text/plain" |
|
94 return "Content-type: %s\n\n%s" % (ct, file(fname).read()) |
|
95 except ValueError: |
|
96 # security breach attempt |
|
97 return "" |
97 return "" |
98 except OSError, e: |
|
99 if e.errno == errno.ENOENT: |
|
100 return "" |
|
101 |
98 |
102 class hgrequest(object): |
99 class hgrequest(object): |
103 def __init__(self, inp=None, out=None, env=None): |
100 def __init__(self, inp=None, out=None, env=None): |
104 self.inp = inp or sys.stdin |
101 self.inp = inp or sys.stdin |
105 self.out = out or sys.stdout |
102 self.out = out or sys.stdout |