-
Notifications
You must be signed in to change notification settings - Fork 0
/
GitRepositoryAdaptor.php
143 lines (124 loc) · 4.26 KB
/
GitRepositoryAdaptor.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php namespace Netcarver;
require_once 'FileCache.php';
/**
*
*/
class GitRepositoryAdaptor {
// Per-instance data...
protected $cache = null;
protected $remote = null;
protected $owner = null;
protected $repo = null;
protected $http = null;
protected $tags = null;
protected $debug = false;
protected $headers = [];
protected $encoded_owner = null;
protected $encoded_repo = null;
public function debug($newvalue = null) {
if (null !== $newvalue) {
$this->debug = (bool) $newvalue;
}
return $this->debug;
}
/**
* This is called after the remote is read for whatever reason.
*
* Override in descendants to provide specific funtionality - like recording rate limits from reply headers.
*/
protected function postRead(array $data) {
if ($this->debug && class_exists('\TD')) {
\TD::barDump($data, 'Read Summary');
}
}
/**
* Reads from the Remote Repository - or from a cached result (if any).
*
* @param string $url Input: URL of the resource to be accessed.
* @param mixed &$http_code Output: The http code of the remote http response.
* @param bool $json Input: (Optional) If the reply from the remote is JSON (true - the default) or RAW (false)
* @return mixed Either null, the actual reply, or the cached reply.
*/
protected function RepositoryRead($url, &$http_code, $json = true) {
$reply = null;
$etag = null;
$last_mod = null;
$headers = $this->headers;
$key = $this->cache->urlToKey($url);
$entry = $this->cache->getEntryForKey($key);
if ($entry) {
$reply = $entry['reply'];
$etag = $entry['etag'];
$last_mod = $entry['last_mod'];
}
if ($etag === '404') {
// Cached 404 - see if it is beyond the retry time...
if (time() < $last_mod) {
$http_code = false; // Indicate a no-remote-read condition.
return null;
}
} elseif ($etag) {
$headers['If-None-Match'] = $etag;
} elseif ($last_mod) {
$headers['If-Modified-Since'] = $last_mod;
}
$this->http->setHeaders($headers);
$new_reply = ($json) ? $this->http->getJson($url) : $this->http->get($url);
$http_code = $this->http->getHttpCode();
$response_headers = $this->http->getResponseHeaders();
$data = [
'url' => $url,
'key' => $key,
'entry' => $entry,
'code' => $http_code,
'request_headers' => $headers,
'reply_headers' => $response_headers,
'reply' => $new_reply,
];
$this->postRead($data);
switch ($http_code) {
case 200:
/**
* Cache miss, but we now have the values from the headers and body that we can store in the cache.
*/
$entry['etag'] = @$response_headers['etag'];
$entry['last_mod'] = @$response_headers['Last-Modified'];
$entry['reply'] = $new_reply;
$this->cache->setEntryForKey($key, $entry);
$reply = $new_reply;
break;
case 301:
/**
* Permanent redirect from GH.
*/
//$new_url = $response_headers['Location'];
break;
case 302:
case 307:
/**
* Temporary redirect from GH. Try again - once.
*/
//$new_url = $response_headers['Location'];
break;
case 304:
/**
* Cache hit! File contents are already in the cache!
*/
break;
case 403:
break;
case 404:
/**
* No such resource.
*/
$cache_for = 15;
$reply = null;
$entry['etag'] = '404';
$entry['last_mod'] = time() + ($cache_for * 60); // Cache 404s for n minutes
$entry['reply'] = null;
$this->cache->setEntryForKey($key, $entry);
break;
}
return $reply;
}
}