def __call__(self, environ, start_response):
        """
        WSGI Response producer for HTTP POST Git Smart HTTP requests.
        Reads commands and data from HTTP POST's body.
        returns an iterator obj with contents of git command's response to stdout
        """
        # 1. Determine git_command, repo_path
        # 2. Determine IN content (encoding)
        # 3. prepare OUT content (encoding, header)

        dataObj = {}
        answer = self.basic_checks(dataObj, environ, start_response)
        if answer:
            # this is a WSGI "trick". basic_checks have already prepared the headers,
            # and a response body (which is the 'answer') returned here.
            # presense of anything of truthiness in 'answer' = some ERROR have
            # already prepared a response and all I need to do is let go of the response.
            return answer

        git_command = dataObj['git_command']
        repo_path = dataObj['repo_path']

        try:
            _l = int(environ.get('CONTENT_LENGTH',''))
        except:
            _l = None

        # Note, depending on the WSGI server, the following handlings of chunked
        # request bodies are possible:
        # 1. This is WSGI 1.0-only compliant server. wsgi.input.read() is bottomless
        #    and Content-Length is absent.
        #    If WSGI app is assuming no size header = size header is Zero, app will respond with wrong data.
        #    (this code is not assuming None = zero data. We look deeper)
        #    If WSGI app is chunked-aware, but respects WSGI 1.0 only,
        #    it will reply with "501 Not Implemented"
        # 2. This is WSGI 1.0-compliant server that tries to accommodate Transfer-Encoding: chunked
        #    requests by caching the body and presenting it as wsgi.input file-like.
        #    Content-Length header is set to captured size and Transfer-Encoding
        #    header is removed. This is not per WSGI 1.0 spec, but is a good thing to do.
        #    All WSGI 1.x apps are happy.
        # 3. This is WSGI 1.1-compliant server that presents Transfer-Encoding: chunked
        #    requests as a file-like that yields an EOF at the end.
        #    Content-Length header is NOT set.
        #    Only WSGI 1.1 apps are happy. WSGI 1.0 apps are confused by lack of
        #    content-length header and blow up. (We are WSGI 1.1 app)

        # any WSGI server that claims to be HTTP/1.1 compliant must deal with chunked
        # If not #3 above, then #2 would be done by a self-respecting HTTP/1.1 server.

        wsgi_version = environ.get('wsgi.version',(1,0))
        if wsgi_version[0] >= 1 and wsgi_version[1] >= 1: # if it's 1.1 or higher.
            wsgi_input_has_EOF = True
        else:
            wsgi_input_has_EOF = False
            if _l is None or _l < 0: # signs of transfer-encoding: chunked
                # So, no usable Content-Length value and the server is not WSGI 1.1 and above?
                # Normal thought process:
                # Is the server WSGI 1.1-compliant?
                #  (I.e HTTP/1.1 + Chunked support + wsgi.input will send EOF
                #   at the end and we don't have to think about Content-Length)
                #  Yes - we forget about _l and just read from wsgi.input until EOF
                #  No - We check if "Transfer-Encoding" header is set.
                #       Yes, we send back 501 Not Implemented.
                #       No, What error code? TBD. No point sending zero data as a pack to git.
                # Note: There is another, tricky possibility:
                #  The server is not advertized to be WSGI 1.1 compliant, but is advertized
                #  to be HTTP/1.1 compliant, which would assume that it deals with chunked
                #  body, and LIKELY caches it into a local file-like that will LIKELY emit EOF
                #  However, in accordance with WSGI 1.0, the server would not set Content-Length.
                #  This is dumb. How would we know it's safe to .read() wsgi.input to EOF?
                #  If we assume HTTP/1.1 = "chunked body exposed
                #  as wsgi.input that has EOF" and turn out to be wrong,
                #  we will be trying to read from the wsgi.input indefinitely.
                #  Ugh! I don't want to be guessing based on SERVER_PROTOCOL = HTTP/1.1 header.
                #  Thus, only servers officially proclaiming WSGI v. > 1.0 compliance are
                #  safely supported for Content-Length-less request reading.
                return self.canned_handlers(environ, start_response, 'not_implemented')

        _i = environ.get('wsgi.input')
        if wsgi_input_has_EOF: # this is approximately equal "if server is WSGI 1.1 and above"
            stdin = _i
        else:
            if _l > self.bufsize: # too large to be a string in memory
                bs = self.bufsize
                btr = _l
                stdin = tempfile.TemporaryFile()
                while btr >= bs:
                    stdin.write(_i.read(bs))
                    btr -= bs
                stdin.write(_i.read(btr))
                stdin.flush()
                stdin.seek(0)
            else: # between zero and max memory buffer size = string or bytes
                stdin = _i.read(_l)

        try:
            out = subprocessio.SubprocessIOChunker(
                r'git %s --stateless-rpc "%s"' % (git_command[4:], repo_path),
                inputstream = stdin
                )
        except (EnvironmentError) as e:
            environ['wsgi.errors'].write(str(e))
            return self.canned_handlers(environ, start_response, 'execution_failed')

        if git_command == u'git-receive-pack':
            # updating refs manually after each push. Needed for pre-1.7.0.4 git clients using regular HTTP mode.
            subprocess.call(u'git --git-dir "%s" update-server-info' % repo_path, shell=True)

        headers = [('Content-type', 'application/x-%s-result' % git_command.encode('utf8'))]
        return self.package_response(
            out,
            environ,
            start_response,
            headers)
def __call__ ( self , environ , start_response ) : dataObj = { } answer = self . basic_checks ( dataObj , environ , start_response ) if answer : return answer git_command = dataObj [ 'git_command' ] repo_path = dataObj [ 'repo_path' ] try : _l = int ( environ . get ( 'CONTENT_LENGTH' , '' ) ) except : _l = None wsgi_version = environ . get ( 'wsgi.version' , ( 1 , 0 ) ) if wsgi_version [ 0 ] >= 1 and wsgi_version [ 1 ] >= 1 : wsgi_input_has_EOF = True else : wsgi_input_has_EOF = False if _l is None or _l < 0 : return self . canned_handlers ( environ , start_response , 'not_implemented' ) _i = environ . get ( 'wsgi.input' ) if wsgi_input_has_EOF : stdin = _i else : if _l > self . bufsize : bs = self . bufsize btr = _l stdin = tempfile . TemporaryFile ( ) while btr >= bs : stdin . write ( _i . read ( bs ) ) btr -= bs stdin . write ( _i . read ( btr ) ) stdin . flush ( ) stdin . seek ( 0 ) else : stdin = _i . read ( _l ) try : out = subprocessio . SubprocessIOChunker ( r'git %s --stateless-rpc "%s"' % ( git_command [ 4 : ] , repo_path ) , inputstream = stdin ) except ( EnvironmentError ) as e : environ [ 'wsgi.errors' ] . write ( str ( e ) ) return self . canned_handlers ( environ , start_response , 'execution_failed' ) if git_command == u'git-receive-pack' : subprocess . call ( u'git --git-dir "%s" update-server-info' % repo_path , shell = True ) headers = [ ( 'Content-type' , 'application/x-%s-result' % git_command . encode ( 'utf8' ) ) ] return self . package_response ( out , environ , start_response , headers )
WSGI Response producer for HTTP POST Git Smart HTTP requests.
        Reads commands and data from HTTP POST's body.
        returns an iterator obj with contents of git command's response to stdout