70 for s in util.filechunkiter(self.inp, limit=length): |
70 for s in util.filechunkiter(self.inp, limit=length): |
71 pass |
71 pass |
72 |
72 |
73 def respond(self, status, type, filename=None, length=None): |
73 def respond(self, status, type, filename=None, length=None): |
74 if self._start_response is not None: |
74 if self._start_response is not None: |
75 |
75 self.headers.append(('Content-Type', type)) |
76 self.httphdr(type, filename, length) |
76 if filename: |
|
77 filename = (filename.split('/')[-1] |
|
78 .replace('\\', '\\\\').replace('"', '\\"')) |
|
79 self.headers.append(('Content-Disposition', |
|
80 'inline; filename="%s"' % filename)) |
|
81 if length is not None: |
|
82 self.headers.append(('Content-Length', str(length))) |
77 |
83 |
78 for k, v in self.headers: |
84 for k, v in self.headers: |
79 if not isinstance(v, str): |
85 if not isinstance(v, str): |
80 raise TypeError('header value must be string: %r' % v) |
86 raise TypeError('header value must be string: %r' % (v,)) |
81 |
87 |
82 if isinstance(status, ErrorResponse): |
88 if isinstance(status, ErrorResponse): |
83 self.header(status.headers) |
89 self.headers.extend(status.headers) |
84 if status.code == HTTP_NOT_MODIFIED: |
90 if status.code == HTTP_NOT_MODIFIED: |
85 # RFC 2616 Section 10.3.5: 304 Not Modified has cases where |
91 # RFC 2616 Section 10.3.5: 304 Not Modified has cases where |
86 # it MUST NOT include any headers other than these and no |
92 # it MUST NOT include any headers other than these and no |
87 # body |
93 # body |
88 self.headers = [(k, v) for (k, v) in self.headers if |
94 self.headers = [(k, v) for (k, v) in self.headers if |
118 return None |
124 return None |
119 |
125 |
120 def close(self): |
126 def close(self): |
121 return None |
127 return None |
122 |
128 |
123 def header(self, headers=[('Content-Type','text/html')]): |
|
124 self.headers.extend(headers) |
|
125 |
|
126 def httphdr(self, type, filename=None, length=None, headers={}): |
|
127 headers = headers.items() |
|
128 headers.append(('Content-Type', type)) |
|
129 if filename: |
|
130 filename = (filename.split('/')[-1] |
|
131 .replace('\\', '\\\\').replace('"', '\\"')) |
|
132 headers.append(('Content-Disposition', |
|
133 'inline; filename="%s"' % filename)) |
|
134 if length is not None: |
|
135 headers.append(('Content-Length', str(length))) |
|
136 self.header(headers) |
|
137 |
|
138 def wsgiapplication(app_maker): |
129 def wsgiapplication(app_maker): |
139 '''For compatibility with old CGI scripts. A plain hgweb() or hgwebdir() |
130 '''For compatibility with old CGI scripts. A plain hgweb() or hgwebdir() |
140 can and should now be used as a WSGI application.''' |
131 can and should now be used as a WSGI application.''' |
141 application = app_maker() |
132 application = app_maker() |
142 def run_wsgi(env, respond): |
133 def run_wsgi(env, respond): |