From f985c75b4dd4a136157fc9c36b6e6b8507f510fb Mon Sep 17 00:00:00 2001 From: paulr Date: Mon, 7 Nov 2011 04:05:58 +1100 Subject: [PATCH] pushed and pulled the first branch.. yes, i pushed, i pushed hard. but theres a problem, unless the git inside out website has a branch, things get very weird. I dont really get whats going on here - need to understand git a little better --- gwvplib/gwvpgitcontrol.php | 172 ++++++++++++++++++++++++++++++++++++++++++++ gwvplib/gwvplib.php | 2 +- 2 files changed, 173 insertions(+), 1 deletions(-) diff --git a/gwvplib/gwvpgitcontrol.php b/gwvplib/gwvpgitcontrol.php index 68935a2..4622f27 100644 --- a/gwvplib/gwvpgitcontrol.php +++ b/gwvplib/gwvpgitcontrol.php @@ -31,6 +31,7 @@ function gwvp_gitBackendInterface() { global $repo_base, $BASE_URL; + $repo = ""; $newloc = "/"; if(isset($_REQUEST["q"])) { @@ -101,6 +102,21 @@ function gwvp_gitBackendInterface() // now we need to rebuild the actual request or do we? //$basegit = "$BASE_URL/git/something.git"; //$newloc = preg_replace("/^$basegit/", "", $_SERVER["REQUEST_URI"]); + if($_SERVER["REQUEST_METHOD"] == "POST") { + gwvp_AskForBasicAuth(); + gwvp_callGitBackend($repo); + return; + } + + if(isset($_REQUEST["service"])) { + if($_REQUEST["service"] == "git-receive-pack") { + // we are a write call - we need auth and we're going to the backend proper + gwvp_AskForBasicAuth(); + gwvp_callGitBackend($repo); + return; + } + } + if(file_exists("$repo_base/$repo/$newloc")) { error_log("would ask $repo,$actual_repo_name for $repo/$newloc from $repo_base/$repo/$newloc"); @@ -118,6 +134,162 @@ function gwvp_gitBackendInterface() } +function gwvp_callGitBackend($repo) +{ + // this is where things become a nightmare + $fh = fopen('php://input', "r"); + + $ruri = $_SERVER["REQUEST_URI"]; + $strrem = "git/$repo"; + $euri = str_replace($strrem, "", $_REQUEST["q"]); + //$euri = preg_replace("/^git\/$repo\.git/", "", $_REQUEST["q"]); + + + + $rmeth = $_SERVER["REQUEST_METHOD"]; + + $qs = ""; + foreach($_REQUEST as $key => $var) { + if($key != "q") { + //error_log("adding, $var from $key"); + if($qs == "") $qs.="$key=$var"; + else $qs.="&$key=$var"; + } + } + + //sleep(2); + + + + // this is where the fun, it ends. + $myoutput = ""; + unset($myoutput); + + // this be nasty! + + // setup env + if(isset($procenv)) unset($procenv); + $procenv["GATEWAY_INTERFACE"] = "CGI/1.1"; + $procenv["PATH_TRANSLATED"] = "/tmp/$repo/$euri"; + $procenv["REQUEST_METHOD"] = "$rmeth"; + $procenv["GIT_HTTP_EXPORT_ALL"] = "1"; + $procenv["QUERY_STRING"] = "$qs"; + $procenv["HTTP_USER_AGENT"] = "git/1.7.1"; + $procenv["REMOTE_USER"] = "user"; + $procenv["REMOTE_ADDR"] = "1.2.3.4"; + $procenv["AUTH_TYPE"] = "Basic"; + + if(isset($_SERVER["CONTENT_TYPE"])) { + $procenv["CONTENT_TYPE"] = $_SERVER["CONTENT_TYPE"]; + } else { + //$procenv["CONTENT_TYPE"] = ""; + } + if(isset($_SERVER["CONTENT_LENGTH"])) { + $procenv["CONTENT_LENGTH"] = $_SERVER["CONTENT_LENGTH"]; + } + + error_log("path trans'd is /tmp/$repo/$euri from $ruri with ".$_REQUEST["q"]." $strrem"); + + + $pwd = "/tmp/"; + + $proc = proc_open("/usr/lib/git-core/git-http-backend", array(array("pipe","rb"),array("pipe","wb"),array("file","/tmp/err", "a")), $pipes, $pwd, $procenv); + + $untilblank = false; + while(!$untilblank&&!feof($pipes[1])) { + $lines_t = fgets($pipes[1]); + $lines = trim($lines_t); + error_log("got line: $lines"); + if($lines_t == "\r\n") { + $untilblank = true; + error_log("now blank"); + } else header($lines); + if($lines === false) { + error_log("got an unexpexted exit..."); + exit(0); + } + + } + + + $firstline = true; + $continue = true; + + if(!stream_set_blocking($fh,0)) { + error_log("cant set input non-blocking"); + } + + if(!stream_set_blocking($pipes[1],0)) { + error_log("cant set pipe1 non-blocking"); + } + + // i was going to use stream_select, but i feel this works better like this + while($continue) { + // do client + if(!feof($fh)) { + $from_client_data = fread($fh,8192); + if($from_client_data !== false) fwrite($pipes[0], $from_client_data); + fflush($pipes[0]); + //fwrite($fl, $from_client_data); + $client_len = strlen($from_client_data); + } else { + error_log("client end"); + $client_len = 0; + } + + // do cgi + // sometimes, we get a \r\n from the cgi, i do not know why she swallowed the fly, + // but i do know that the fgets for the headers above should have comsued that + if(!feof($pipes[1])) { + $from_cgi_data_t = fread($pipes[1],8192); + $from_cgi_data = $from_cgi_data_t; + + // i dont know if this will solve it... it coudl cause some serious issues elsewhere + // TODO: this is a hack, i need to know why the fgets above doesn consume the \r\n even tho it reads it + // i.e. why the pointer doesnt increment over it, cause the freads above then get them again. + if($firstline) { + if(strlen($from_cgi_data_t)>0) { + $from_cgi_data = preg_replace("/^\r\n/", "", $from_cgi_data_t); + if(strlen($from_cgi_data)!=strlen($from_cgi_data_t)) { + error_log("MOOOKS - we did trunc"); + } + $firstline = false; + } + } + + if($from_cgi_data !== false) { + echo $from_cgi_data; + flush(); + } + $cgi_len = strlen($from_cgi_data); + } else { + error_log("cgi end"); + $cgi_len = 0; + } + + if(feof($pipes[1])) $continue = false; + else { + if($client_len == 0 && $cgi_len == 0) { + usleep(200000); + error_log("sleep tick"); + } else { + error_log("sizes: $client_len, $cgi_len"); + if($cgi_len > 0) { + error_log("from cgi: \"$from_cgi_data\""); + } + } + } + + } + + + //fclose($fl); + fclose($fh); + fclose($pipes[1]); + fclose($pipes[0]); +} + + function gwvp_repoExists($name) { diff --git a/gwvplib/gwvplib.php b/gwvplib/gwvplib.php index d70dc3f..824e4c4 100644 --- a/gwvplib/gwvplib.php +++ b/gwvplib/gwvplib.php @@ -17,7 +17,7 @@ require_once("gwvpemail.php"); require_once("gwvppluginloader.php"); // only enable this if you need it: -require_once("gwvpdebug.php"); +// require_once("gwvpdebug.php"); ?> \ No newline at end of file -- 1.7.0.4