Last active
January 28, 2016 09:30
-
-
Save dmpayton/2fc0c5353c5a54c7c624 to your computer and use it in GitHub Desktop.
Django+Git server proof of concept
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import itertools | |
from django.conf import settings | |
from django.conf.urls import url | |
from django.http import HttpResponse | |
from django.utils.decorators import classonlymethod | |
from django.views.decorators.csrf import csrf_exempt | |
from django.views.generic import View | |
from dulwich.repo import Repo | |
from dulwich.server import DictBackend | |
from dulwich.web import HTTPGitApplication | |
class GitWeb(View): | |
prefix = None | |
@classonlymethod | |
def mount(cls, prefix, name=None): | |
regex = r'^{0}'.format(prefix.lstrip('/')) | |
return url(regex, csrf_exempt(cls.as_view(prefix=prefix)), name=name) | |
def dispatch(self, request, *args, **kwargs): | |
self.patch_request(request) | |
self.app = self.make_wsgi_app() | |
return self.generate_response() | |
def make_wsgi_app(self): | |
gitdir = settings.BASE_DIR | |
backend = DictBackend({'/': Repo(gitdir)}) | |
app = HTTPGitApplication(backend) | |
return app | |
def generate_response(self): | |
response_data = {} | |
buffer = [] | |
def start_response(status, headers, exc_info=None): | |
if exc_info is not None: | |
raise exc_info[0], exc_info[1], exc_info[2] | |
response_data['status'] = int(status.split()[0]) | |
response_data['headers'] = headers | |
return buffer.append | |
response = self.app(self.request.environ, start_response) | |
response = HttpResponse(itertools.chain(buffer, list(response)), | |
status=response_data['status']) | |
for key, value in response_data['headers']: | |
response[key] = value | |
return response | |
def patch_request(self, request): | |
patched = request.environ['PATH_INFO'][len(self.prefix):] | |
original_script_name = request.environ.get('SCRIPT_NAME', '') | |
request.environ['PATH_INFO'] = patched | |
request.environ['SCRIPT_NAME'] = original_script_name + self.prefix | |
request.environ['wsgi.input'] = request._stream |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment