equal
deleted
inserted
replaced
6 |
6 |
7 from __future__ import absolute_import |
7 from __future__ import absolute_import |
8 |
8 |
9 import abc |
9 import abc |
10 import cgi |
10 import cgi |
|
11 import contextlib |
11 import struct |
12 import struct |
12 import sys |
13 import sys |
13 |
14 |
14 from .i18n import _ |
15 from .i18n import _ |
15 from . import ( |
16 from . import ( |
69 The file is in the form:: |
70 The file is in the form:: |
70 |
71 |
71 (<chunk-size>\n<chunk>)+0\n |
72 (<chunk-size>\n<chunk>)+0\n |
72 |
73 |
73 chunk size is the ascii version of the int. |
74 chunk size is the ascii version of the int. |
|
75 """ |
|
76 |
|
77 @abc.abstractmethod |
|
78 def mayberedirectstdio(self): |
|
79 """Context manager to possibly redirect stdio. |
|
80 |
|
81 The context manager yields a file-object like object that receives |
|
82 stdout and stderr output when the context manager is active. Or it |
|
83 yields ``None`` if no I/O redirection occurs. |
|
84 |
|
85 The intent of this context manager is to capture stdio output |
|
86 so it may be sent in the response. Some transports support streaming |
|
87 stdio to the client in real time. For these transports, stdio output |
|
88 won't be captured. |
74 """ |
89 """ |
75 |
90 |
76 @abc.abstractmethod |
91 @abc.abstractmethod |
77 def redirect(self): |
92 def redirect(self): |
78 """may setup interception for stdout and stderr |
93 """may setup interception for stdout and stderr |
148 # If httppostargs is used, we need to read Content-Length |
163 # If httppostargs is used, we need to read Content-Length |
149 # minus the amount that was consumed by args. |
164 # minus the amount that was consumed by args. |
150 length -= int(self._req.env.get(r'HTTP_X_HGARGS_POST', 0)) |
165 length -= int(self._req.env.get(r'HTTP_X_HGARGS_POST', 0)) |
151 for s in util.filechunkiter(self._req, limit=length): |
166 for s in util.filechunkiter(self._req, limit=length): |
152 fp.write(s) |
167 fp.write(s) |
|
168 |
|
169 @contextlib.contextmanager |
|
170 def mayberedirectstdio(self): |
|
171 oldout = self._ui.fout |
|
172 olderr = self._ui.ferr |
|
173 |
|
174 out = util.stringio() |
|
175 |
|
176 try: |
|
177 self._ui.fout = out |
|
178 self._ui.ferr = out |
|
179 yield out |
|
180 finally: |
|
181 self._ui.fout = oldout |
|
182 self._ui.ferr = olderr |
153 |
183 |
154 def redirect(self): |
184 def redirect(self): |
155 self._oldio = self._ui.fout, self._ui.ferr |
185 self._oldio = self._ui.fout, self._ui.ferr |
156 self._ui.ferr = self._ui.fout = stringio() |
186 self._ui.ferr = self._ui.fout = stringio() |
157 |
187 |
391 count = int(self._fin.readline()) |
421 count = int(self._fin.readline()) |
392 while count: |
422 while count: |
393 fpout.write(self._fin.read(count)) |
423 fpout.write(self._fin.read(count)) |
394 count = int(self._fin.readline()) |
424 count = int(self._fin.readline()) |
395 |
425 |
|
426 @contextlib.contextmanager |
|
427 def mayberedirectstdio(self): |
|
428 yield None |
|
429 |
396 def redirect(self): |
430 def redirect(self): |
397 pass |
431 pass |
398 |
432 |
399 def _client(self): |
433 def _client(self): |
400 client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0] |
434 client = encoding.environ.get('SSH_CLIENT', '').split(' ', 1)[0] |