mercurial/wireprotoserver.py
changeset 36066 2ad145fbde54
parent 36065 bf676267f64f
child 36067 caca3ac2ac04
equal deleted inserted replaced
36065:bf676267f64f 36066:2ad145fbde54
     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]