List of commits:
Subject Hash Author Date (UTC)
Some big fixes for push over http 56ebd277c71c50e40af9465cd3867dc885f054b9 Catalin(ux) M. BOIE 2017-04-26 20:00:53
Do not recursively set the rights - not needed a9edce3101ad2450b67a575265827aa69efd5c63 Catalin(ux) M. BOIE 2017-04-17 07:16:01
Cosmetic changes 4bb36da63972e7e152e4e476e84ed55baba02911 Catalin(ux) M. BOIE 2017-04-15 09:29:09
Add possibility for admin to limit the git log --patch limit 1865405c40ebe92aa1bc6fd4569dcbb0e3af476c Catalin(ux) M. BOIE 2017-04-15 09:28:46
Silent curl in API functional test e6808bc97d201fd4944de0ad2982c3090ae4743a Catalin(ux) M. BOIE 2017-04-15 06:31:04
Fixed a lot of tests which used time() for different fields and sometime lost the time race 6a61493189d07110d3c5fdbe34ea0725d5abbd3b Catalin(ux) M. BOIE 2017-04-15 06:25:40
Fixed the crash with big diffs by setting a limit 788e15942d8272685764a25b640eba2c07046437 Catalin(ux) M. BOIE 2017-04-15 06:24:30
Allow .well-known folder access 90519cd03bf64839d1a9fc2497e58bd63d8ce6f3 Catalin(ux) M. BOIE 2017-04-12 16:50:16
When an un-auth user is visiting a user page with no repo, do not invite to create a repo 6904e1eac3f46c281ae6b4757bcaa16d2acc6169 Catalin(ux) M. BOIE 2017-03-27 15:23:52
Added a 'push' target in Makefile to not forget to push tags... 92a9b78e26d8a3e7b466f5aa45678dd2db8d4310 Catalin(ux) M. BOIE 2017-03-26 14:29:55
Bump version to 0.67 6f1c9a6d7f7d40d65def54e23a3590556a346bb8 Catalin(ux) M. BOIE 2017-03-26 09:44:32
Cosmetic cb68f1921782a503675c592dc7484aa26b8815b6 Catalin(ux) M. BOIE 2017-03-26 09:37:41
Improve state handling: do not check for an old value; verify if table exists before doing a select 17d8eb4b4592dd96e62a8da74d87d3d3b26aeb86 Catalin(ux) M. BOIE 2017-03-26 09:37:01
Impoved debug for cache 4d6349f7143d61583e6d2d9612c89b55af4eea97 Catalin(ux) M. BOIE 2017-03-26 09:36:08
I cannot be sure if the data is stored only in Germany. And we do backups in Romania. 1610c997dbda53c0a21e301b51832d9285ecbcf2 Catalin(ux) M. BOIE 2017-03-26 08:24:46
Removed a not used variable 4d2bab105c6f7748ca53d9a8301a2da320153d53 Catalin(ux) M. BOIE 2017-03-21 20:15:29
tests: ignore some dirs 7260fc44f8d0197b917bc13a0ac19eb8c58d4534 Catalin(ux) M. BOIE 2017-03-21 20:01:03
Link to anon push doc 42dbfdc9ad5fad0157388f239f790f2e8f4de7c2 Catalin(ux) M. BOIE 2017-03-21 20:00:45
comparison: add red/green for css/js sizes and for pagespeed cbcda26a9d20c115eb0931ab2af69f3c2315ab7d Catalin(ux) M. BOIE 2017-03-21 19:44:47
Trim the hints for cloning the tree 59bc91f5229abf96f453d872a58a2c96cf18198c Catalin(ux) M. BOIE 2017-03-21 19:35:58
Commit 56ebd277c71c50e40af9465cd3867dc885f054b9 - Some big fixes for push over http
1. The push may generate a size bigger than 'post_max_size'.
2. Deal with http.postBuffer + apache + php-fpm.
PHP will return nothing as input!
Author: Catalin(ux) M. BOIE
Author date (UTC): 2017-04-26 20:00
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2017-04-26 20:00
Parent(s): a9edce3101ad2450b67a575265827aa69efd5c63
Signer:
Signing key:
Signing status: N
Tree: 3370fdd34f005a234ccfdc1438512a29a31172c8
File Lines added Lines deleted
inc/user.inc.php 89 29
inc/util.inc.php 36 3
samples/pool.conf 1 0
File inc/user.inc.php changed (mode: 100644) (index 041c8cd..cbb14f1)
... ... function rg_user_list_to_full_info($db, $list)
1849 1849 } }
1850 1850
1851 1851 /* /*
1852 * This function deals with incoming compressed input.
1852 * This function deals with incoming (compressed) input.
1853 1853 * Please note that if the webserver was configured without an input filter * Please note that if the webserver was configured without an input filter
1854 1854 * (like apache's SetInputFilter DEFLATE), this function will * (like apache's SetInputFilter DEFLATE), this function will
1855 1855 * take care of it. * take care of it.
1856 1856 * Returns the uncompressed stream. * Returns the uncompressed stream.
1857 1857 */ */
1858 function rg_process_gzip($content_length, $content_encoding)
1858 function rg_process_input($content_length, $content_encoding)
1859 1859 { {
1860 rg_log('DEBUG: process_gzip: cl=' . $content_length
1860 rg_log_enter('DEBUG: process_input: cl=' . $content_length
1861 1861 . ' content_encoding=' . $content_encoding); . ' content_encoding=' . $content_encoding);
1862 1862
1863 $data_in = @file_get_contents('php://input');
1864 if ($data_in === FALSE) {
1865 rg_log('Cannot get in stream (1)!');
1866 return FALSE;
1867 }
1863 while (1) {
1864 $ret = @file_get_contents('php://input');
1865 if (empty($ret)) {
1866 rg_log('DEBUG: php://input is empty!');
1867 $ret = FALSE;
1868 break;
1869 }
1868 1870
1869 rg_log('DEBUG: data_in: ' . substr($data_in, 0, 32));
1870 if (strcmp($content_encoding, 'gzip') == 0) {
1871 $data_in = @gzdecode($data_in);
1872 if ($data_in === FALSE) {
1873 rg_log('Cannot decompress!');
1874 return FALSE;
1871 if (0) { // maybe for nginx/lighttpd
1872 $f = @fopen('php://stdin', 'r');
1873 if ($f === FALSE) {
1874 rg_log('Cannot open stdin!');
1875 break;
1875 1876 } }
1876 rg_log('DEBUG: after decompress: ' . substr($data_in, 0, 32));
1877 while (1) {
1878 $x = @fread($f, 4);
1879 if ($x === FALSE) {
1880 rg_log('DEBUG: cannot read!');
1881 break;
1882 }
1883 rg_log('DEBUG: BLOCK: ' . $x);
1884 $ret = $x;
1885 break;
1886 }
1887 fclose($f);
1888 }
1889
1890 rg_log('DEBUG: data_in[0-31]: ' . substr($ret, 0, 32));
1891 if (strcmp($content_encoding, 'gzip') == 0) {
1892 $ret = @gzdecode($ret);
1893 if ($ret === FALSE) {
1894 rg_log('Cannot decompress!');
1895 break;
1896 }
1897 rg_log('DEBUG: after decompress[0-31]: '
1898 . substr($ret, 0, 32));
1899 }
1900
1901 break;
1877 1902 } }
1878 1903
1879 return $data_in;
1904 return $ret;
1880 1905 } }
1881 1906
1882 1907 /* /*
 
... ... function rg_user_http_git($db, $rg, $paras)
1926 1951 header('Expires: Fri, 01 Jan 1980 00:00:00 GMT'); header('Expires: Fri, 01 Jan 1980 00:00:00 GMT');
1927 1952 header('Pragma: no-cache'); header('Pragma: no-cache');
1928 1953 header('Cache-Control: no-cache, max-age=0, must-revalidate'); header('Cache-Control: no-cache, max-age=0, must-revalidate');
1954 header('Content-Type: text/plain');
1929 1955
1930 1956 // if user is valid, retry auth // if user is valid, retry auth
1931 1957 // if user is not valid, consider anonymous // if user is not valid, consider anonymous
 
... ... function rg_user_http_git($db, $rg, $paras)
2002 2028 header($protocol . ' 401 Unauthorized status'); header($protocol . ' 401 Unauthorized status');
2003 2029 header('WWW-Authenticate: Basic' header('WWW-Authenticate: Basic'
2004 2030 . ' realm="Use empty user if you have no account"'); . ' realm="Use empty user if you have no account"');
2031 echo 'RocketGit: Info: == Welcome to RocketGit! ==' . "\n";
2032 echo 'RocketGit: Info: you are connecting from IP ' . $rg['ip'] . '.' . "\n";
2033 echo 'RocketGit: Error: ' . $r['error'] . '!';
2005 2034 break; break;
2006 2035 } }
2007 2036
 
... ... function rg_user_http_git($db, $rg, $paras)
2012 2041 . ' push=' . $r['push']); . ' push=' . $r['push']);
2013 2042 if (($r['push'] === 1) && ($r['push_allowed'] !== 1)) { if (($r['push'] === 1) && ($r['push_allowed'] !== 1)) {
2014 2043 // We have only anon push rights at this point. // We have only anon push rights at this point.
2015 // If user is correct, but password not, we will ask
2044 // If user is correct, but password is not, we will ask
2016 2045 // the user to try again. If user is not correct, // the user to try again. If user is not correct,
2017 2046 // we will go on with anon push access. // we will go on with anon push access.
2018 2047 if ($empty_user if ($empty_user
 
... ... function rg_user_http_git($db, $rg, $paras)
2021 2050 header($protocol . ' 401 Unauthorized status'); header($protocol . ' 401 Unauthorized status');
2022 2051 header('WWW-Authenticate: Basic' header('WWW-Authenticate: Basic'
2023 2052 . ' realm="Use empty user if you have no account"'); . ' realm="Use empty user if you have no account"');
2053 echo 'RocketGit: Info: == Welcome to RocketGit! ==' . "\n";
2054 echo 'RocketGit: Info: you are connecting from IP ' . $rg['ip'] . '.' . "\n";
2024 2055 break; break;
2025 2056 } }
2026 2057 } else if ($r['push'] === 1) { } else if ($r['push'] === 1) {
 
... ... function rg_user_http_git($db, $rg, $paras)
2029 2060 rg_log('DEBUG: it is a fetch'); rg_log('DEBUG: it is a fetch');
2030 2061 } }
2031 2062
2032 $content_length = rg_var_str('CONTENT_LENGTH');
2063 $content_length = rg_var_int('CONTENT_LENGTH');
2033 2064 $content_encoding = rg_var_str('HTTP_CONTENT_ENCODING'); $content_encoding = rg_var_str('HTTP_CONTENT_ENCODING');
2034 2065 rg_log('DEBUG: cl=' . $content_length . ' ce=' . $content_encoding); rg_log('DEBUG: cl=' . $content_length . ' ce=' . $content_encoding);
2035 2066
 
... ... function rg_user_http_git($db, $rg, $paras)
2049 2080 $e = rg_exec($run, '', 'rg_echo', 'rg_git_band_2'); $e = rg_exec($run, '', 'rg_echo', 'rg_git_band_2');
2050 2081 if ($e['code'] != 0) if ($e['code'] != 0)
2051 2082 rg_log('Error executing command: ' . $e['errmsg']); rg_log('Error executing command: ' . $e['errmsg']);
2083 rg_log('Done!');
2052 2084 } else if (strcasecmp($rg['ct'], 'application/x-git-upload-pack-request') == 0) { } else if (strcasecmp($rg['ct'], 'application/x-git-upload-pack-request') == 0) {
2053 2085 rg_log('DEBUG: git-upload-pack...'); rg_log('DEBUG: git-upload-pack...');
2054 2086
 
... ... function rg_user_http_git($db, $rg, $paras)
2061 2093 rg_git_info_pack("\x02", '== Welcome to RocketGit! =='); rg_git_info_pack("\x02", '== Welcome to RocketGit! ==');
2062 2094 rg_git_info_pack("\x02", 'you are connecting from IP ' rg_git_info_pack("\x02", 'you are connecting from IP '
2063 2095 . $rg['ip'] . '.'); . $rg['ip'] . '.');
2064 // If user does not correct to the correct URL, correct them
2096 // If user does not connect to the correct URL, correct them
2065 2097 if (!empty($host) && (strcasecmp($host, $rg['rg_http_host_no_port']) != 0)) if (!empty($host) && (strcasecmp($host, $rg['rg_http_host_no_port']) != 0))
2066 2098 rg_git_info_pack("\x02", 'Please use ' . $rg['rg_http_host_no_port'] rg_git_info_pack("\x02", 'Please use ' . $rg['rg_http_host_no_port']
2067 2099 . ' instead of ' . $host . '.'); . ' instead of ' . $host . '.');
2068 2100 putenv('ROCKETGIT_SHOW_INFO=0'); putenv('ROCKETGIT_SHOW_INFO=0');
2069 2101 */ */
2070 2102
2071 $run = '/usr/libexec/git-core/git-upload-pack'
2072 . ' --stateless-rpc'
2073 . ' ' . escapeshellarg($repo_path);
2074
2075 $data_in = rg_process_gzip($content_length, $content_encoding);
2103 $data_in = rg_process_input($content_length,
2104 $content_encoding);
2076 2105 if ($data_in === FALSE) if ($data_in === FALSE)
2077 2106 break; break;
2078 2107
2108 $run = '/usr/libexec/git-core/git-upload-pack'
2109 . ' --stateless-rpc'
2110 . ' ' . escapeshellarg($repo_path);
2079 2111 $e = rg_exec($run, $data_in, 'rg_echo', 'rg_git_band_2'); $e = rg_exec($run, $data_in, 'rg_echo', 'rg_git_band_2');
2080 2112 if ($e['code'] != 0) if ($e['code'] != 0)
2081 2113 rg_log('Error executing command: ' . $e['errmsg']); rg_log('Error executing command: ' . $e['errmsg']);
2114 rg_log('Done!');
2082 2115 } else if (strcasecmp($rg['ct'], 'application/x-git-receive-pack-request') == 0) { } else if (strcasecmp($rg['ct'], 'application/x-git-receive-pack-request') == 0) {
2083 2116 rg_log('DEBUG: git-receive-pack...'); rg_log('DEBUG: git-receive-pack...');
2084 2117
 
... ... function rg_user_http_git($db, $rg, $paras)
2093 2126 . ' instead of ' . $host . '.'); . ' instead of ' . $host . '.');
2094 2127 putenv('ROCKETGIT_SHOW_INFO=0'); putenv('ROCKETGIT_SHOW_INFO=0');
2095 2128
2096 $run = '/usr/libexec/git-core/git-receive-pack'
2097 . ' --stateless-rpc'
2098 . ' ' . escapeshellarg($repo_path);
2129 $max_nice = ini_get('post_max_size');
2130 $max = rg_mega2bytes($max_nice);
2131 $max_nice = rg_1024($max);
2132 $content_length = 1000000000;
2133 if ($content_length > $max) {
2134 rg_git_info_pack("\x02", 'Your push size ('
2135 . rg_1024($content_length) . ')'
2136 . ' is bigger than the'
2137 . ' max allowed (' . $max_nice . ').');
2138 rg_git_info_pack("\x02", 'You may want to ask'
2139 . ' the admin to raise the limit.');
2140 echo rg_git_flush();
2141 break;
2142 }
2099 2143
2100 $data_in = rg_process_gzip($content_length, $content_encoding);
2101 if ($data_in === FALSE)
2144 $data_in = rg_process_input($content_length,
2145 $content_encoding);
2146 if ($data_in === FALSE) {
2147 // We have to send '200'.
2148 // Else, we cannot send the hints
2149 header($protocol . ' 200 Service unavailable');
2150 rg_git_info_pack("\x02", 'We could not process'
2151 . ' the data (chunked).');
2152 rg_git_info_pack("\x02", 'Try to run \'git'
2153 . ' config http.postBuffer 200000000\'.');
2154 rg_git_info_pack("\x02", 'The value must be'
2155 . ' bigger than the biggest file pushed.');
2156 echo rg_git_flush();
2102 2157 break; break;
2158 }
2103 2159
2160 $run = '/usr/libexec/git-core/git-receive-pack'
2161 . ' --stateless-rpc'
2162 . ' ' . escapeshellarg($repo_path);
2104 2163 $e = rg_exec($run, $data_in, 'rg_echo', 'rg_echo'); $e = rg_exec($run, $data_in, 'rg_echo', 'rg_echo');
2105 2164 if ($e['code'] != 0) if ($e['code'] != 0)
2106 2165 rg_log('Error executing command: ' . $e['errmsg']); rg_log('Error executing command: ' . $e['errmsg']);
2166 rg_log('Done!');
2107 2167 } else { } else {
2108 2168 rg_log('Unknown service!'); rg_log('Unknown service!');
2109 2169 // TODO: send some errors, also above // TODO: send some errors, also above
File inc/util.inc.php changed (mode: 100644) (index d0dee08..a05e052)
... ... function sha512($m)
43 43 return hash('sha512', $m); return hash('sha512', $m);
44 44 } }
45 45
46 /*
47 * TODO: 8192KiB must be 8MiB
48 */
46 49 function rg_1024($v) function rg_1024($v)
47 50 { {
48 51 if ($v <= 9999) if ($v <= 9999)
 
... ... function rg_1024($v)
64 67 return number_format($v) . "TiB"; return number_format($v) . "TiB";
65 68 } }
66 69
70 /*
71 * Transforms a kilo/mega/giga into bytes
72 * Example: 8M -> 8388608
73 */
74 function rg_mega2bytes($s)
75 {
76 $r = intval($s);
77 if (stristr($s, 'k'))
78 return $r * 1024;
79 if (stristr($s, 'm'))
80 return $r * 1024 * 1024;
81 if (stristr($s, 'g'))
82 return $r * 1024 * 1024 * 1024;
83
84 return $r;
85 }
86
67 87 /* /*
68 88 * Returns a binary string of random bytes * Returns a binary string of random bytes
69 89 */ */
 
... ... function rg_exec($cmd, $input, $cb_stdout, $cb_stderr)
1026 1046 $revents = $rx; $revents = $rx;
1027 1047 $wevents = $wx; $wevents = $wx;
1028 1048 $ex = NULL; $ex = NULL;
1029 $r = stream_select($revents, $wevents, $ex, 10, 0);
1049 $r = stream_select($revents, $wevents, $ex, 5, 0);
1030 1050 if ($r === FALSE) { if ($r === FALSE) {
1031 1051 $ret['errmsg'] = "cannot select"; $ret['errmsg'] = "cannot select";
1032 1052 break; break;
1033 1053 } }
1054
1055 if ($r === 0) {
1056 $ps = proc_get_status($a);
1057 rg_log_ml('ps: ' . print_r($ps, TRUE));
1058 //rg_log('DEBUG: No activity (conn status=' . connection_status() . ')!');
1059 if (connection_aborted()) {
1060 $ret['errmsg'] = 'connection aborted';
1061 break;
1062 }
1063 continue;
1064 }
1065
1034 1066 //rg_log('DEBUG: stream_select returned ' . $r //rg_log('DEBUG: stream_select returned ' . $r
1035 // . ', revents: ' . rg_array2string($revents)
1036 // . ', wevents: ' . rg_array2string($wevents));
1067 // . ' revents: ' . rg_array2string($revents)
1068 // . ' wevents: ' . rg_array2string($wevents)
1069 // . ' ex: ' . rg_array2string($ex));
1037 1070
1038 1071 foreach ($wevents as $fd) { foreach ($wevents as $fd) {
1039 1072 if (!empty($ret['errmsg'])) if (!empty($ret['errmsg']))
File samples/pool.conf changed (mode: 100644) (index 5cb76c3..c3388c5)
... ... request_slowlog_timeout = 2s
412 412 php_admin_value[error_log] = /var/log/php-fpm/rocketgit-error.log php_admin_value[error_log] = /var/log/php-fpm/rocketgit-error.log
413 413 php_admin_flag[log_errors] = on php_admin_flag[log_errors] = on
414 414 php_admin_value[memory_limit] = 128M php_admin_value[memory_limit] = 128M
415 php_admin_value[post_max_size] = 32M
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/catalinux/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/catalinux/rocketgit

Clone this repository using git:
git clone git://git.rocketgit.com/user/catalinux/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main