├── .gitignore
├── LICENSE
├── README.md
├── app.php
├── cache
└── .gitkeep
├── composer.json
├── composer.lock
├── config.ini.dist
├── console.php
├── logs
└── .gitkeep
├── views
└── index.html.twig
└── web
├── .htaccess
├── index.php
├── proxy
└── .gitkeep
└── top.jpg
/.gitignore:
--------------------------------------------------------------------------------
1 | config.ini
2 | vendor
3 | web/proxy
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2014 Shogo Kawahara
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Composer Proxy
2 | ==============
3 |
4 | composer-proxy can cache package information for composer repository.
5 | It's an effective way to use composer when central repository
6 | (packagist.org) server is too far.
7 |
8 | There is an available server in Japan.
9 | (http://composer-proxy.jp/)
10 |
11 | System Requirement
12 | ------------------
13 |
14 | - PHP5.3+
15 |
16 | How to install
17 | --------------
18 |
19 | Clone it.
20 |
21 | $ git clone https://github.com/kawahara/composer-proxy
22 |
23 | Resolve dependencies with composer (See https://getcomposer.org/)
24 |
25 | $ cd /path/to/app
26 | $ composer install
27 |
28 | Change permission for cache directories
29 |
30 | $ cd /path/to/app
31 | $ chmod 777 cache
32 | $ chmod 777 web/proxy
33 |
34 | Copy configuration file and modify for your needs
35 |
36 | cp config.ini.dist config.ini
37 |
38 | Example: Configure web server (Apache)
39 |
40 |
41 | Options -MultiViews
42 |
43 | RewriteEngine On
44 | RewriteBase /path/to/app/web
45 | RewriteCond %{REQUEST_FILENAME} !-f
46 | RewriteRule ^ index.php [QSA,L]
47 |
48 |
49 | Example: Configure web server (Nginx)
50 |
51 | server {
52 | listen 80;
53 | listen [::]:80 default_server ipv6only=on;
54 |
55 | root /path/to/app/web;
56 | server_name localhost;
57 |
58 | location / {
59 | index index.php index.html index.htm;
60 | try_files $uri @rewriteapp;
61 | }
62 |
63 | location @rewriteapp {
64 | rewrite ^(.*)$ /index.php/$1 last;
65 | }
66 |
67 | location ~ \.php(/|$) {
68 | fastcgi_pass unix:/var/run/php5-fpm.sock;
69 | fastcgi_split_path_info ^(.+\.php)(/.*)$;
70 | include fastcgi_params;
71 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
72 | fastcgi_param HTTPS off;
73 | }
74 | }
75 |
76 | Register the script to crontab
77 |
78 | php /path/to/app/console.php cache:clear-old-file
79 |
80 | `cache:clear-old-file` command can delete old cache file. `packages.json` (the root file to define packages) is deleted every 5 minutes (default) by this command. Other file TTL is 6 months.
81 |
82 | - --ttl (-t) : TTL of `packages.json`. default is 300 seconds.
83 | - --dry-run : Show the action without real remove operations.
84 | - --without-hashed-file : You can ignore to delete package definition file.
85 | - --hashed-file-ttl : TTL of package definition file. default is 15,552,000 seconds. (6 months)
86 |
87 |
88 | You can change TTL by options of this command.
89 |
90 | If you need to delete all of the cache information, you can delete by following command.
91 |
92 | php /path/to/app/console.php cache:clear-all
93 |
94 |
--------------------------------------------------------------------------------
/app.php:
--------------------------------------------------------------------------------
1 | 'https://packagist.org'
14 | );
15 |
16 | $app['cache_dir'] = __DIR__.'/web/proxy';
17 |
18 | # Read additional configs from a "config.ini" file.
19 | # See config.ini.dist for an example.
20 | $config_file = __DIR__ . '/config.ini';
21 | if (is_file($config_file)) {
22 | $config = parse_ini_file($config_file);
23 | foreach ($config as $key => $value) {
24 | if (is_array($value)) {
25 | foreach ($value as $arr_key => $arr_value) {
26 | $app[$key][$arr_key] = $arr_value;
27 | }
28 | } else {
29 | $app[$key] = $value;
30 | }
31 | }
32 | }
33 |
34 | $app['browser'] = $app->share(function() {
35 | $client = new Buzz\Client\Curl();
36 | $client->setTimeout(20);
37 |
38 | return new Buzz\Browser($client);
39 | });
40 |
41 | $app->register(new Silex\Provider\HttpCacheServiceProvider(), array(
42 | 'http_cache.cache_dir' => __DIR__.'/cache/'
43 | ));
44 |
45 |
46 | $app->register(new Silex\Provider\TwigServiceProvider(), array(
47 | 'twig.path' => __DIR__.'/views'
48 | ));
49 |
50 | $app->get('/', function() use ($app) {
51 | $body = $app['twig']->render('index.html.twig', array(
52 | 'app' => $app
53 | ));
54 |
55 | return new Response($body, 200, array('Cache-Control' => 's-maxage=3600,public'));
56 | });
57 |
58 | $app->get('/proxy/{rep}/', function($rep) use ($app) {
59 | return $app->redirect("/proxy/${rep}/packages.json");
60 | });
61 |
62 | $app->get('/proxy/{rep}/packages.json', function($rep) use ($app) {
63 | if (!isset($app['repositories'][$rep])) {
64 | $app->abort(404, "Not Found");
65 | }
66 |
67 | $url = $app['repositories'][$rep]."/packages.json";
68 | $response = $app['browser']->get($url);
69 | if (!$response->isOk()) {
70 | $app->abort($response->getStatusCode(), "");
71 | }
72 |
73 | $responseJson = json_decode($response->getContent(), true);
74 |
75 | // convert
76 | if (isset($responseJson['notify']) && $responseJson['notify'][0] === '/') {
77 | $responseJson['notify'] = $app['repositories'][$rep] . $responseJson['notify'];
78 | }
79 | if (isset($responseJson['notify-batch']) && $responseJson['notify-batch'][0] === '/') {
80 | $responseJson['notify-batch'] = $app['repositories'][$rep] . $responseJson['notify-batch'];
81 | }
82 | if (isset($responseJson['search']) && $responseJson['search'][0] === '/') {
83 | $responseJson['search'] = $app['repositories'][$rep] . $responseJson['search'];
84 | }
85 |
86 | $responseJson['providers-url'] = "/proxy/".$rep."/p/%package%$%hash%.json";
87 |
88 | $dir = $app['cache_dir']."/".$rep;
89 | if (!is_dir($dir)) {
90 | @mkdir($dir, 0777, true);
91 | }
92 |
93 | file_put_contents($app['cache_dir']."/".$rep."/packages.json", json_encode($responseJson));
94 |
95 | return $app->json($responseJson);
96 | });
97 |
98 | $app->get('/proxy/{rep}/p/{p}${hash}.json', function($rep, $p, $hash) use ($app) {
99 | if (!isset($app['repositories'][$rep])) {
100 | $app->abort(404, "Not Found");
101 | }
102 |
103 | $path = "/p/";
104 | $file = $p."$".$hash.".json";
105 |
106 | $url = $app['repositories'][$rep].$path.$file;
107 | $response = $app['browser']->get($url);
108 | if (!$response->isOk()) {
109 | $app->abort($response->getStatusCode(), "");
110 | }
111 |
112 | $contents = $response->getContent();
113 | $gethash = hash('sha256', $contents, false);
114 |
115 | if ($gethash != $hash) {
116 | $app->abort(500, "Cannot fetch file correctly.");
117 | }
118 |
119 | $responseJson = json_decode($contents, true);
120 |
121 | $dir = $app['cache_dir']."/".$rep.$path;
122 | if (!is_dir($dir)) {
123 | @mkdir($dir, 0777, true);
124 | }
125 |
126 | file_put_contents($dir.$file, json_encode($responseJson));
127 |
128 | return $app->json($responseJson);
129 | });
130 |
131 | $app->get('/proxy/{rep}/p/{namespace}/{package}${hash}.json', function($rep, $namespace, $package, $hash) use ($app) {
132 | if (!isset($app['repositories'][$rep])) {
133 | $app->abort(404, "Not Found");
134 | }
135 |
136 | $path = "/p/".$namespace."/";
137 | $file = $package."$".$hash.".json";
138 |
139 | $url = $app['repositories'][$rep].$path.$file;
140 | $response = $app['browser']->get($url);
141 | if (!$response->isOk()) {
142 | $app->abort($response->getStatusCode(), "");
143 | }
144 |
145 | $contents = $response->getContent();
146 | $gethash = hash('sha256', $contents, false);
147 |
148 | // Check hash
149 | if ($gethash != $hash) {
150 | $app->abort(500, "Cannot fetch file correctly.");
151 | }
152 |
153 | $responseJson = json_decode($contents, true);
154 |
155 | $dir = $app['cache_dir']."/".$rep.$path;
156 | if (!is_dir($dir)) {
157 | @mkdir($dir, 0777, true);
158 | }
159 |
160 | // Save cache
161 | file_put_contents($dir.$file, json_encode($responseJson));
162 |
163 | return $app->json($responseJson);
164 | });
165 |
166 | $app->get('/proxy/{rep}/p/{namespace}/{package}.json', function($rep, $namespace, $package) use ($app) {
167 | if (!isset($app['repositories'][$rep])) {
168 | $app->abort(404, "Not Found");
169 | }
170 |
171 | $path = "/p/".$namespace."/";
172 | $file = $package.".json";
173 |
174 | $url = $app['repositories'][$rep].$path.$file;
175 | $response = $app['browser']->get($url);
176 | if (!$response->isOk()) {
177 | $app->abort($response->getStatusCode(), "");
178 | }
179 |
180 | $responseJson = json_decode($response->getContent(), true);
181 |
182 | $dir = $app['cache_dir']."/".$rep.$path;
183 | if (!is_dir($dir)) {
184 | @mkdir($dir, 0777, true);
185 | }
186 |
187 | file_put_contents($dir.$file, json_encode($responseJson));
188 |
189 | return $app->json($responseJson);
190 | });
191 |
192 | return $app;
193 |
--------------------------------------------------------------------------------
/cache/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kawahara/composer-proxy/6a5f6831d2e995c56f8139b51d9afbc9f9efb5b3/cache/.gitkeep
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kawahara/composer-proxy",
3 | "description": "The composer proxy",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Shogo Kawahara",
8 | "email": "kawahara@bucyou.net"
9 | }
10 | ],
11 | "require": {
12 | "ext-curl": "*",
13 | "silex/silex": "1.*",
14 | "symfony/console": "2.3.*",
15 | "symfony/finder": "2.3.*",
16 | "symfony/filesystem": "2.3.*",
17 | "react/react": "0.3.*",
18 | "kriswallsmith/buzz": "0.*",
19 | "twig/twig": ">=1.8,<2.0-dev"
20 | },
21 | "autoload": {
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
5 | ],
6 | "hash": "610674e92f1015f725c66a9be8137d32",
7 | "packages": [
8 | {
9 | "name": "evenement/evenement",
10 | "version": "v1.0.0",
11 | "source": {
12 | "type": "git",
13 | "url": "https://github.com/igorw/evenement",
14 | "reference": "v1.0.0"
15 | },
16 | "dist": {
17 | "type": "zip",
18 | "url": "https://github.com/igorw/evenement/zipball/v1.0.0",
19 | "reference": "v1.0.0",
20 | "shasum": ""
21 | },
22 | "require": {
23 | "php": ">=5.3.0"
24 | },
25 | "type": "library",
26 | "autoload": {
27 | "psr-0": {
28 | "Evenement": "src"
29 | }
30 | },
31 | "notification-url": "https://packagist.org/downloads/",
32 | "license": [
33 | "MIT"
34 | ],
35 | "authors": [
36 | {
37 | "name": "Igor Wiedler",
38 | "email": "igor@wiedler.ch",
39 | "homepage": "http://wiedler.ch/igor/"
40 | }
41 | ],
42 | "description": "Événement is a very simple event dispatching library for PHP 5.3",
43 | "keywords": [
44 | "event-dispatcher"
45 | ],
46 | "time": "2012-05-30 08:01:08"
47 | },
48 | {
49 | "name": "guzzle/parser",
50 | "version": "v3.7.1",
51 | "target-dir": "Guzzle/Parser",
52 | "source": {
53 | "type": "git",
54 | "url": "https://github.com/guzzle/parser.git",
55 | "reference": "v3.7.1"
56 | },
57 | "dist": {
58 | "type": "zip",
59 | "url": "https://api.github.com/repos/guzzle/parser/zipball/v3.7.1",
60 | "reference": "v3.7.1",
61 | "shasum": ""
62 | },
63 | "require": {
64 | "php": ">=5.3.2"
65 | },
66 | "type": "library",
67 | "extra": {
68 | "branch-alias": {
69 | "dev-master": "3.7-dev"
70 | }
71 | },
72 | "autoload": {
73 | "psr-0": {
74 | "Guzzle\\Parser": ""
75 | }
76 | },
77 | "notification-url": "https://packagist.org/downloads/",
78 | "license": [
79 | "MIT"
80 | ],
81 | "description": "Interchangeable parsers used by Guzzle",
82 | "homepage": "http://guzzlephp.org/",
83 | "keywords": [
84 | "URI Template",
85 | "cookie",
86 | "http",
87 | "message",
88 | "url"
89 | ],
90 | "time": "2013-06-11 00:24:07"
91 | },
92 | {
93 | "name": "kriswallsmith/buzz",
94 | "version": "v0.10",
95 | "source": {
96 | "type": "git",
97 | "url": "https://github.com/kriswallsmith/Buzz.git",
98 | "reference": "v0.10"
99 | },
100 | "dist": {
101 | "type": "zip",
102 | "url": "https://api.github.com/repos/kriswallsmith/Buzz/zipball/v0.10",
103 | "reference": "v0.10",
104 | "shasum": ""
105 | },
106 | "require": {
107 | "php": ">=5.3.0"
108 | },
109 | "require-dev": {
110 | "phpunit/phpunit": "3.7.*"
111 | },
112 | "suggest": {
113 | "ext-curl": "*"
114 | },
115 | "type": "library",
116 | "autoload": {
117 | "psr-0": {
118 | "Buzz": "lib/"
119 | }
120 | },
121 | "notification-url": "https://packagist.org/downloads/",
122 | "license": [
123 | "MIT"
124 | ],
125 | "authors": [
126 | {
127 | "name": "Kris Wallsmith",
128 | "email": "kris.wallsmith@gmail.com",
129 | "homepage": "http://kriswallsmith.net/"
130 | }
131 | ],
132 | "description": "Lightweight HTTP client",
133 | "homepage": "https://github.com/kriswallsmith/Buzz",
134 | "keywords": [
135 | "curl",
136 | "http client"
137 | ],
138 | "time": "2013-05-19 03:41:15"
139 | },
140 | {
141 | "name": "pimple/pimple",
142 | "version": "v1.0.2",
143 | "source": {
144 | "type": "git",
145 | "url": "https://github.com/fabpot/Pimple.git",
146 | "reference": "v1.0.2"
147 | },
148 | "dist": {
149 | "type": "zip",
150 | "url": "https://api.github.com/repos/fabpot/Pimple/zipball/v1.0.2",
151 | "reference": "v1.0.2",
152 | "shasum": ""
153 | },
154 | "require": {
155 | "php": ">=5.3.0"
156 | },
157 | "type": "library",
158 | "extra": {
159 | "branch-alias": {
160 | "dev-master": "1.0.x-dev"
161 | }
162 | },
163 | "autoload": {
164 | "psr-0": {
165 | "Pimple": "lib/"
166 | }
167 | },
168 | "notification-url": "https://packagist.org/downloads/",
169 | "license": [
170 | "MIT"
171 | ],
172 | "authors": [
173 | {
174 | "name": "Fabien Potencier",
175 | "email": "fabien@symfony.com"
176 | }
177 | ],
178 | "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
179 | "homepage": "http://pimple.sensiolabs.org",
180 | "keywords": [
181 | "container",
182 | "dependency injection"
183 | ],
184 | "time": "2013-03-08 08:21:40"
185 | },
186 | {
187 | "name": "psr/log",
188 | "version": "1.0.0",
189 | "source": {
190 | "type": "git",
191 | "url": "https://github.com/php-fig/log",
192 | "reference": "1.0.0"
193 | },
194 | "dist": {
195 | "type": "zip",
196 | "url": "https://github.com/php-fig/log/archive/1.0.0.zip",
197 | "reference": "1.0.0",
198 | "shasum": ""
199 | },
200 | "type": "library",
201 | "autoload": {
202 | "psr-0": {
203 | "Psr\\Log\\": ""
204 | }
205 | },
206 | "notification-url": "https://packagist.org/downloads/",
207 | "license": [
208 | "MIT"
209 | ],
210 | "authors": [
211 | {
212 | "name": "PHP-FIG",
213 | "homepage": "http://www.php-fig.org/"
214 | }
215 | ],
216 | "description": "Common interface for logging libraries",
217 | "keywords": [
218 | "log",
219 | "psr",
220 | "psr-3"
221 | ],
222 | "time": "2012-12-21 11:40:51"
223 | },
224 | {
225 | "name": "react/promise",
226 | "version": "v1.0.4",
227 | "source": {
228 | "type": "git",
229 | "url": "https://github.com/reactphp/promise.git",
230 | "reference": "v1.0.4"
231 | },
232 | "dist": {
233 | "type": "zip",
234 | "url": "https://api.github.com/repos/reactphp/promise/zipball/v1.0.4",
235 | "reference": "v1.0.4",
236 | "shasum": ""
237 | },
238 | "require": {
239 | "php": ">=5.3.3"
240 | },
241 | "type": "library",
242 | "extra": {
243 | "branch-alias": {
244 | "dev-master": "1.0-dev"
245 | }
246 | },
247 | "autoload": {
248 | "psr-0": {
249 | "React\\Promise": "src/"
250 | }
251 | },
252 | "notification-url": "https://packagist.org/downloads/",
253 | "license": [
254 | "MIT"
255 | ],
256 | "authors": [
257 | {
258 | "name": "Jan Sorgalla",
259 | "email": "jsorgalla@googlemail.com",
260 | "homepage": "http://sorgalla.com",
261 | "role": "maintainer"
262 | }
263 | ],
264 | "description": "A lightweight implementation of CommonJS Promises/A for PHP",
265 | "time": "2013-04-03 14:05:55"
266 | },
267 | {
268 | "name": "react/react",
269 | "version": "v0.3.3",
270 | "source": {
271 | "type": "git",
272 | "url": "https://github.com/reactphp/react.git",
273 | "reference": "v0.3.3"
274 | },
275 | "dist": {
276 | "type": "zip",
277 | "url": "https://api.github.com/repos/reactphp/react/zipball/v0.3.3",
278 | "reference": "v0.3.3",
279 | "shasum": ""
280 | },
281 | "require": {
282 | "evenement/evenement": "1.0.*",
283 | "guzzle/parser": "~3.0",
284 | "php": ">=5.3.3",
285 | "react/promise": "~1.0"
286 | },
287 | "replace": {
288 | "react/cache": "self.version",
289 | "react/dns": "self.version",
290 | "react/event-loop": "self.version",
291 | "react/http": "self.version",
292 | "react/http-client": "self.version",
293 | "react/socket": "self.version",
294 | "react/socket-client": "self.version",
295 | "react/stream": "self.version"
296 | },
297 | "suggest": {
298 | "ext-libev": "*",
299 | "ext-libevent": "*"
300 | },
301 | "type": "library",
302 | "extra": {
303 | "branch-alias": {
304 | "dev-master": "0.3-dev"
305 | }
306 | },
307 | "autoload": {
308 | "psr-0": {
309 | "React": "src"
310 | }
311 | },
312 | "notification-url": "https://packagist.org/downloads/",
313 | "license": [
314 | "MIT"
315 | ],
316 | "description": "Nuclear Reactor written in PHP.",
317 | "keywords": [
318 | "event-loop",
319 | "reactor"
320 | ],
321 | "time": "2013-07-09 01:55:25"
322 | },
323 | {
324 | "name": "silex/silex",
325 | "version": "v1.1.0",
326 | "source": {
327 | "type": "git",
328 | "url": "https://github.com/fabpot/Silex.git",
329 | "reference": "v1.1.0"
330 | },
331 | "dist": {
332 | "type": "zip",
333 | "url": "https://api.github.com/repos/fabpot/Silex/zipball/v1.1.0",
334 | "reference": "v1.1.0",
335 | "shasum": ""
336 | },
337 | "require": {
338 | "php": ">=5.3.3",
339 | "pimple/pimple": "1.*",
340 | "symfony/event-dispatcher": ">=2.3,<2.4-dev",
341 | "symfony/http-foundation": ">=2.3,<2.4-dev",
342 | "symfony/http-kernel": ">=2.3,<2.4-dev",
343 | "symfony/routing": ">=2.3,<2.4-dev"
344 | },
345 | "require-dev": {
346 | "doctrine/dbal": ">=2.2.0,<2.4.0-dev",
347 | "monolog/monolog": "~1.4,>=1.4.1",
348 | "phpunit/phpunit": "~3.7",
349 | "swiftmailer/swiftmailer": "5.*",
350 | "symfony/browser-kit": ">=2.3,<2.4-dev",
351 | "symfony/config": ">=2.3,<2.4-dev",
352 | "symfony/css-selector": ">=2.3,<2.4-dev",
353 | "symfony/dom-crawler": ">=2.3,<2.4-dev",
354 | "symfony/finder": ">=2.3,<2.4-dev",
355 | "symfony/form": ">=2.3,<2.4-dev",
356 | "symfony/locale": ">=2.3,<2.4-dev",
357 | "symfony/monolog-bridge": ">=2.3,<2.4-dev",
358 | "symfony/options-resolver": ">=2.3,<2.4-dev",
359 | "symfony/process": ">=2.3,<2.4-dev",
360 | "symfony/security": ">=2.3,<2.4-dev",
361 | "symfony/serializer": ">=2.3,<2.4-dev",
362 | "symfony/translation": ">=2.3,<2.4-dev",
363 | "symfony/twig-bridge": ">=2.3,<2.4-dev",
364 | "symfony/validator": ">=2.3,<2.4-dev",
365 | "twig/twig": ">=1.8.0,<2.0-dev"
366 | },
367 | "suggest": {
368 | "symfony/browser-kit": ">=2.3,<2.4-dev",
369 | "symfony/css-selector": ">=2.3,<2.4-dev",
370 | "symfony/dom-crawler": ">=2.3,<2.4-dev",
371 | "symfony/form": ">=2.3,<2.4-dev"
372 | },
373 | "type": "library",
374 | "extra": {
375 | "branch-alias": {
376 | "dev-master": "1.1.x-dev"
377 | }
378 | },
379 | "autoload": {
380 | "psr-0": {
381 | "Silex": "src/"
382 | }
383 | },
384 | "notification-url": "https://packagist.org/downloads/",
385 | "license": [
386 | "MIT"
387 | ],
388 | "authors": [
389 | {
390 | "name": "Fabien Potencier",
391 | "email": "fabien@symfony.com"
392 | },
393 | {
394 | "name": "Igor Wiedler",
395 | "email": "igor@wiedler.ch",
396 | "homepage": "http://wiedler.ch/igor/"
397 | }
398 | ],
399 | "description": "The PHP micro-framework based on the Symfony2 Components",
400 | "homepage": "http://silex.sensiolabs.org",
401 | "keywords": [
402 | "microframework"
403 | ],
404 | "time": "2013-07-04 07:15:36"
405 | },
406 | {
407 | "name": "symfony/console",
408 | "version": "v2.3.1",
409 | "target-dir": "Symfony/Component/Console",
410 | "source": {
411 | "type": "git",
412 | "url": "https://github.com/symfony/Console.git",
413 | "reference": "v2.3.1"
414 | },
415 | "dist": {
416 | "type": "zip",
417 | "url": "https://api.github.com/repos/symfony/Console/zipball/v2.3.1",
418 | "reference": "v2.3.1",
419 | "shasum": ""
420 | },
421 | "require": {
422 | "php": ">=5.3.3"
423 | },
424 | "require-dev": {
425 | "symfony/event-dispatcher": ">=2.1,<3.0"
426 | },
427 | "suggest": {
428 | "symfony/event-dispatcher": ""
429 | },
430 | "type": "library",
431 | "extra": {
432 | "branch-alias": {
433 | "dev-master": "2.3-dev"
434 | }
435 | },
436 | "autoload": {
437 | "psr-0": {
438 | "Symfony\\Component\\Console\\": ""
439 | }
440 | },
441 | "notification-url": "https://packagist.org/downloads/",
442 | "license": [
443 | "MIT"
444 | ],
445 | "authors": [
446 | {
447 | "name": "Fabien Potencier",
448 | "email": "fabien@symfony.com"
449 | },
450 | {
451 | "name": "Symfony Community",
452 | "homepage": "http://symfony.com/contributors"
453 | }
454 | ],
455 | "description": "Symfony Console Component",
456 | "homepage": "http://symfony.com",
457 | "time": "2013-06-11 07:15:14"
458 | },
459 | {
460 | "name": "symfony/debug",
461 | "version": "v2.3.1",
462 | "target-dir": "Symfony/Component/Debug",
463 | "source": {
464 | "type": "git",
465 | "url": "https://github.com/symfony/Debug.git",
466 | "reference": "v2.3.1"
467 | },
468 | "dist": {
469 | "type": "zip",
470 | "url": "https://api.github.com/repos/symfony/Debug/zipball/v2.3.1",
471 | "reference": "v2.3.1",
472 | "shasum": ""
473 | },
474 | "require": {
475 | "php": ">=5.3.3"
476 | },
477 | "require-dev": {
478 | "symfony/http-foundation": ">=2.1,<3.0",
479 | "symfony/http-kernel": ">=2.1,<3.0"
480 | },
481 | "suggest": {
482 | "symfony/class-loader": "",
483 | "symfony/http-foundation": "",
484 | "symfony/http-kernel": ""
485 | },
486 | "type": "library",
487 | "extra": {
488 | "branch-alias": {
489 | "dev-master": "2.3-dev"
490 | }
491 | },
492 | "autoload": {
493 | "psr-0": {
494 | "Symfony\\Component\\Debug\\": ""
495 | }
496 | },
497 | "notification-url": "https://packagist.org/downloads/",
498 | "license": [
499 | "MIT"
500 | ],
501 | "authors": [
502 | {
503 | "name": "Fabien Potencier",
504 | "email": "fabien@symfony.com"
505 | },
506 | {
507 | "name": "Symfony Community",
508 | "homepage": "http://symfony.com/contributors"
509 | }
510 | ],
511 | "description": "Symfony Debug Component",
512 | "homepage": "http://symfony.com",
513 | "time": "2013-06-02 11:58:44"
514 | },
515 | {
516 | "name": "symfony/event-dispatcher",
517 | "version": "v2.3.1",
518 | "target-dir": "Symfony/Component/EventDispatcher",
519 | "source": {
520 | "type": "git",
521 | "url": "https://github.com/symfony/EventDispatcher.git",
522 | "reference": "v2.3.1"
523 | },
524 | "dist": {
525 | "type": "zip",
526 | "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.1",
527 | "reference": "v2.3.1",
528 | "shasum": ""
529 | },
530 | "require": {
531 | "php": ">=5.3.3"
532 | },
533 | "require-dev": {
534 | "symfony/dependency-injection": ">=2.0,<3.0"
535 | },
536 | "suggest": {
537 | "symfony/dependency-injection": "",
538 | "symfony/http-kernel": ""
539 | },
540 | "type": "library",
541 | "extra": {
542 | "branch-alias": {
543 | "dev-master": "2.3-dev"
544 | }
545 | },
546 | "autoload": {
547 | "psr-0": {
548 | "Symfony\\Component\\EventDispatcher\\": ""
549 | }
550 | },
551 | "notification-url": "https://packagist.org/downloads/",
552 | "license": [
553 | "MIT"
554 | ],
555 | "authors": [
556 | {
557 | "name": "Fabien Potencier",
558 | "email": "fabien@symfony.com"
559 | },
560 | {
561 | "name": "Symfony Community",
562 | "homepage": "http://symfony.com/contributors"
563 | }
564 | ],
565 | "description": "Symfony EventDispatcher Component",
566 | "homepage": "http://symfony.com",
567 | "time": "2013-05-13 14:36:40"
568 | },
569 | {
570 | "name": "symfony/filesystem",
571 | "version": "v2.3.1",
572 | "target-dir": "Symfony/Component/Filesystem",
573 | "source": {
574 | "type": "git",
575 | "url": "https://github.com/symfony/Filesystem.git",
576 | "reference": "v2.3.1"
577 | },
578 | "dist": {
579 | "type": "zip",
580 | "url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.3.1",
581 | "reference": "v2.3.1",
582 | "shasum": ""
583 | },
584 | "require": {
585 | "php": ">=5.3.3"
586 | },
587 | "type": "library",
588 | "extra": {
589 | "branch-alias": {
590 | "dev-master": "2.3-dev"
591 | }
592 | },
593 | "autoload": {
594 | "psr-0": {
595 | "Symfony\\Component\\Filesystem\\": ""
596 | }
597 | },
598 | "notification-url": "https://packagist.org/downloads/",
599 | "license": [
600 | "MIT"
601 | ],
602 | "authors": [
603 | {
604 | "name": "Fabien Potencier",
605 | "email": "fabien@symfony.com"
606 | },
607 | {
608 | "name": "Symfony Community",
609 | "homepage": "http://symfony.com/contributors"
610 | }
611 | ],
612 | "description": "Symfony Filesystem Component",
613 | "homepage": "http://symfony.com",
614 | "time": "2013-06-04 15:02:05"
615 | },
616 | {
617 | "name": "symfony/finder",
618 | "version": "v2.3.1",
619 | "target-dir": "Symfony/Component/Finder",
620 | "source": {
621 | "type": "git",
622 | "url": "https://github.com/symfony/Finder.git",
623 | "reference": "v2.3.1"
624 | },
625 | "dist": {
626 | "type": "zip",
627 | "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.3.1",
628 | "reference": "v2.3.1",
629 | "shasum": ""
630 | },
631 | "require": {
632 | "php": ">=5.3.3"
633 | },
634 | "type": "library",
635 | "extra": {
636 | "branch-alias": {
637 | "dev-master": "2.3-dev"
638 | }
639 | },
640 | "autoload": {
641 | "psr-0": {
642 | "Symfony\\Component\\Finder\\": ""
643 | }
644 | },
645 | "notification-url": "https://packagist.org/downloads/",
646 | "license": [
647 | "MIT"
648 | ],
649 | "authors": [
650 | {
651 | "name": "Fabien Potencier",
652 | "email": "fabien@symfony.com"
653 | },
654 | {
655 | "name": "Symfony Community",
656 | "homepage": "http://symfony.com/contributors"
657 | }
658 | ],
659 | "description": "Symfony Finder Component",
660 | "homepage": "http://symfony.com",
661 | "time": "2013-06-02 12:05:51"
662 | },
663 | {
664 | "name": "symfony/http-foundation",
665 | "version": "v2.3.1",
666 | "target-dir": "Symfony/Component/HttpFoundation",
667 | "source": {
668 | "type": "git",
669 | "url": "https://github.com/symfony/HttpFoundation.git",
670 | "reference": "v2.3.1"
671 | },
672 | "dist": {
673 | "type": "zip",
674 | "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.3.1",
675 | "reference": "v2.3.1",
676 | "shasum": ""
677 | },
678 | "require": {
679 | "php": ">=5.3.3"
680 | },
681 | "type": "library",
682 | "extra": {
683 | "branch-alias": {
684 | "dev-master": "2.3-dev"
685 | }
686 | },
687 | "autoload": {
688 | "psr-0": {
689 | "Symfony\\Component\\HttpFoundation\\": ""
690 | },
691 | "classmap": [
692 | "Symfony/Component/HttpFoundation/Resources/stubs"
693 | ]
694 | },
695 | "notification-url": "https://packagist.org/downloads/",
696 | "license": [
697 | "MIT"
698 | ],
699 | "authors": [
700 | {
701 | "name": "Fabien Potencier",
702 | "email": "fabien@symfony.com"
703 | },
704 | {
705 | "name": "Symfony Community",
706 | "homepage": "http://symfony.com/contributors"
707 | }
708 | ],
709 | "description": "Symfony HttpFoundation Component",
710 | "homepage": "http://symfony.com",
711 | "time": "2013-05-10 06:00:03"
712 | },
713 | {
714 | "name": "symfony/http-kernel",
715 | "version": "v2.3.1",
716 | "target-dir": "Symfony/Component/HttpKernel",
717 | "source": {
718 | "type": "git",
719 | "url": "https://github.com/symfony/HttpKernel.git",
720 | "reference": "v2.3.1"
721 | },
722 | "dist": {
723 | "type": "zip",
724 | "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/v2.3.1",
725 | "reference": "v2.3.1",
726 | "shasum": ""
727 | },
728 | "require": {
729 | "php": ">=5.3.3",
730 | "psr/log": ">=1.0,<2.0",
731 | "symfony/debug": ">=2.3,<3.0",
732 | "symfony/event-dispatcher": ">=2.1,<3.0",
733 | "symfony/http-foundation": ">=2.2,<3.0"
734 | },
735 | "require-dev": {
736 | "symfony/browser-kit": "2.2.*",
737 | "symfony/class-loader": ">=2.1,<3.0",
738 | "symfony/config": ">=2.0,<3.0",
739 | "symfony/console": "2.2.*",
740 | "symfony/dependency-injection": ">=2.0,<3.0",
741 | "symfony/finder": ">=2.0,<3.0",
742 | "symfony/process": ">=2.0,<3.0",
743 | "symfony/routing": ">=2.2,<3.0",
744 | "symfony/stopwatch": ">=2.2,<3.0"
745 | },
746 | "suggest": {
747 | "symfony/browser-kit": "",
748 | "symfony/class-loader": "",
749 | "symfony/config": "",
750 | "symfony/console": "",
751 | "symfony/dependency-injection": "",
752 | "symfony/finder": ""
753 | },
754 | "type": "library",
755 | "extra": {
756 | "branch-alias": {
757 | "dev-master": "2.3-dev"
758 | }
759 | },
760 | "autoload": {
761 | "psr-0": {
762 | "Symfony\\Component\\HttpKernel\\": ""
763 | }
764 | },
765 | "notification-url": "https://packagist.org/downloads/",
766 | "license": [
767 | "MIT"
768 | ],
769 | "authors": [
770 | {
771 | "name": "Fabien Potencier",
772 | "email": "fabien@symfony.com"
773 | },
774 | {
775 | "name": "Symfony Community",
776 | "homepage": "http://symfony.com/contributors"
777 | }
778 | ],
779 | "description": "Symfony HttpKernel Component",
780 | "homepage": "http://symfony.com",
781 | "time": "2013-06-11 11:46:38"
782 | },
783 | {
784 | "name": "symfony/routing",
785 | "version": "v2.3.1",
786 | "target-dir": "Symfony/Component/Routing",
787 | "source": {
788 | "type": "git",
789 | "url": "https://github.com/symfony/Routing.git",
790 | "reference": "v2.3.1"
791 | },
792 | "dist": {
793 | "type": "zip",
794 | "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.3.1",
795 | "reference": "v2.3.1",
796 | "shasum": ""
797 | },
798 | "require": {
799 | "php": ">=5.3.3"
800 | },
801 | "require-dev": {
802 | "doctrine/common": ">=2.2,<3.0",
803 | "psr/log": ">=1.0,<2.0",
804 | "symfony/config": ">=2.2,<3.0",
805 | "symfony/yaml": ">=2.0,<3.0"
806 | },
807 | "suggest": {
808 | "doctrine/common": "",
809 | "symfony/config": "",
810 | "symfony/yaml": ""
811 | },
812 | "type": "library",
813 | "extra": {
814 | "branch-alias": {
815 | "dev-master": "2.3-dev"
816 | }
817 | },
818 | "autoload": {
819 | "psr-0": {
820 | "Symfony\\Component\\Routing\\": ""
821 | }
822 | },
823 | "notification-url": "https://packagist.org/downloads/",
824 | "license": [
825 | "MIT"
826 | ],
827 | "authors": [
828 | {
829 | "name": "Fabien Potencier",
830 | "email": "fabien@symfony.com"
831 | },
832 | {
833 | "name": "Symfony Community",
834 | "homepage": "http://symfony.com/contributors"
835 | }
836 | ],
837 | "description": "Symfony Routing Component",
838 | "homepage": "http://symfony.com",
839 | "time": "2013-05-20 08:57:26"
840 | },
841 | {
842 | "name": "twig/twig",
843 | "version": "v1.13.1",
844 | "source": {
845 | "type": "git",
846 | "url": "https://github.com/fabpot/Twig.git",
847 | "reference": "v1.13.1"
848 | },
849 | "dist": {
850 | "type": "zip",
851 | "url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.13.1",
852 | "reference": "v1.13.1",
853 | "shasum": ""
854 | },
855 | "require": {
856 | "php": ">=5.2.4"
857 | },
858 | "type": "library",
859 | "extra": {
860 | "branch-alias": {
861 | "dev-master": "1.13-dev"
862 | }
863 | },
864 | "autoload": {
865 | "psr-0": {
866 | "Twig_": "lib/"
867 | }
868 | },
869 | "notification-url": "https://packagist.org/downloads/",
870 | "license": [
871 | "BSD-3"
872 | ],
873 | "authors": [
874 | {
875 | "name": "Fabien Potencier",
876 | "email": "fabien@symfony.com"
877 | },
878 | {
879 | "name": "Armin Ronacher",
880 | "email": "armin.ronacher@active-4.com"
881 | }
882 | ],
883 | "description": "Twig, the flexible, fast, and secure template language for PHP",
884 | "homepage": "http://twig.sensiolabs.org",
885 | "keywords": [
886 | "templating"
887 | ],
888 | "time": "2013-06-06 06:06:01"
889 | }
890 | ],
891 | "packages-dev": [
892 |
893 | ],
894 | "aliases": [
895 |
896 | ],
897 | "minimum-stability": "stable",
898 | "stability-flags": [
899 |
900 | ],
901 | "platform": {
902 | "ext-curl": "*"
903 | },
904 | "platform-dev": [
905 |
906 | ]
907 | }
908 |
--------------------------------------------------------------------------------
/config.ini.dist:
--------------------------------------------------------------------------------
1 | title="Composer Proxy JP"
2 | base_url="http://composer-proxy.jp/"
3 |
4 | ; Additional repositories
5 | ; repositories[packagist] = https://packagist.org
6 |
--------------------------------------------------------------------------------
/console.php:
--------------------------------------------------------------------------------
1 | register('cache:clear-old-file')
20 | ->setDefinition(array(
21 | new InputOption('ttl', 't', InputOption::VALUE_OPTIONAL, 'ttl', 300), // 5 minutes
22 | new InputOption('dry-run', null, InputOption::VALUE_NONE, ''),
23 | new InputOption('without-hashed-file', null, InputOption::VALUE_NONE, ''),
24 | new InputOption('hashed-file-ttl', null, InputOption::VALUE_OPTIONAL, '', 60*60*24*30*6) //6 months
25 | ))
26 | ->setDescription('Clear old cache files')
27 | ->setCode(function (InputInterface $input, OutputInterface $output) use ($app) {
28 | $ttl = $input->getOption('ttl');
29 | $dryRun = $input->getOption('dry-run');
30 | $dryRunText = '';
31 | if ($dryRun) {
32 | $dryRunText = ' (dry-run)';
33 | }
34 |
35 | $finder = new Finder();
36 | $fs = new Filesystem();
37 | $finder->files()
38 | ->notName('/\$[0-9a-f]+\.json$/')
39 | ->date('until '.$ttl.' sec ago')
40 | ->in($app['cache_dir']);
41 | foreach ($finder as $file) {
42 | $output->writeln('Remove '.$file->getRealpath().$dryRunText.'');
43 | if (!$dryRun) {
44 | $fs->remove($file);
45 | }
46 | }
47 |
48 | if (!$input->getOption('without-hashed-file')) {
49 | $hashedFileFinder = new Finder();
50 | $hashedFileTtl = $input->getOption('hashed-file-ttl');
51 | $hashedFileFinder->files()
52 | ->name('/\$[0-9a-f]+\.json$/')
53 | ->date('until '.$hashedFileTtl.' sec ago')
54 | ->in($app['cache_dir']);
55 | foreach ($hashedFileFinder as $file) {
56 | $output->writeln('Remove '.$file->getRealpath().$dryRunText.'');
57 | if (!$dryRun) {
58 | $fs->remove($file);
59 | }
60 | }
61 | }
62 | });
63 |
64 | $console
65 | ->register('cache:clear-all')
66 | ->setDefinition(array(
67 | new InputOption('dry-run', null, InputOption::VALUE_NONE, ''),
68 | ))
69 | ->setDescription('Clear all cache files')
70 | ->setCode(function (InputInterface $input, OutputInterface $output) use ($app) {
71 | $dryRun = $input->getOption('dry-run');
72 | $dryRunText = '';
73 | if ($dryRun) {
74 | $dryRunText = ' (dry-run)';
75 | }
76 | $finder = new Finder();
77 | $fs = new Filesystem();
78 | $finder->files()->in($app['cache_dir']);
79 | foreach ($finder as $file) {
80 | $output->writeln('Remove '.$file->getRealpath().$dryRunText.'');
81 | if (!$dryRun) {
82 | $fs->remove($file);
83 | }
84 | }
85 | });
86 |
87 | $console->run();
88 |
--------------------------------------------------------------------------------
/logs/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kawahara/composer-proxy/6a5f6831d2e995c56f8139b51d9afbc9f9efb5b3/logs/.gitkeep
--------------------------------------------------------------------------------
/views/index.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ app.title }}
6 |
7 |
8 |
9 |
17 |
18 |
19 |
47 |
48 |
49 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/web/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Options -MultiViews
3 |
4 | RewriteEngine On
5 | RewriteBase /
6 | RewriteCond %{REQUEST_FILENAME} !-f
7 | RewriteRule ^ index.php [QSA,L]
8 |
9 |
--------------------------------------------------------------------------------
/web/index.php:
--------------------------------------------------------------------------------
1 | run();
16 | } else {
17 | $app['http_cache']->run();
18 | }
19 |
--------------------------------------------------------------------------------
/web/proxy/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kawahara/composer-proxy/6a5f6831d2e995c56f8139b51d9afbc9f9efb5b3/web/proxy/.gitkeep
--------------------------------------------------------------------------------
/web/top.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kawahara/composer-proxy/6a5f6831d2e995c56f8139b51d9afbc9f9efb5b3/web/top.jpg
--------------------------------------------------------------------------------