Skip to content

Commit 321a63b

Browse files
committed
fix(github): download of files larger than 1MB
1 parent 2ec1604 commit 321a63b

File tree

1 file changed

+48
-18
lines changed

1 file changed

+48
-18
lines changed

src/modules/github.xql

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ declare function github:commit-ref-url($config as map(*), $per-page as xs:intege
3333
: Clone defines Version repo
3434
:)
3535
declare function github:get-archive($config as map(*), $sha as xs:string) as xs:base64Binary {
36-
github:request(
36+
github:download-file(
3737
github:repo-url($config) || "/zipball/" || $sha, $config?token)
3838
};
3939

@@ -206,14 +206,35 @@ declare function github:get-commit-files($config as map(*), $sha as xs:string) a
206206
return $commit?files
207207
};
208208

209+
(: TODO: make raw url configurable :)
210+
declare variable $github:raw-usercontent-endpoint := "https://raw.githubusercontent.com";
211+
209212
(:~
210213
: Get blob of a file
214+
: https://raw.githubusercontent.com/<owner>/<repo>/<sha>/<path>
211215
:)
212-
declare function github:get-blob($config as map(*), $filename as xs:string, $sha as xs:string) as xs:string {
213-
let $blob-url := github:repo-url($config) || "/contents/" || escape-html-uri($filename) || "?ref=" || $sha
214-
let $content := github:request-json($blob-url, $config?token)?content
215-
216-
return util:base64-decode($content)
216+
declare %private function github:get-blob($config as map(*), $filename as xs:string, $sha as xs:string) {
217+
if (not(starts-with($config?base-url, "https://api.github.com"))) then (
218+
(: for GitHub enterprise we have to query for the download url, this might return the contents directly :)
219+
let $blob-url := github:repo-url($config) || "/contents/" || escape-html-uri($filename) || "?ref=" || $sha
220+
let $json := github:request-json($blob-url, $config?token)
221+
let $content := $json?content
222+
223+
return
224+
if ($json?content = "") (: endpoint did not return base64 encoded contents :)
225+
then github:download-file($json?download_url, $config?token)
226+
else util:base64-decode($content)
227+
) else (
228+
(: for github.com we can construct the download url :)
229+
let $blob-url := string-join((
230+
$github:raw-usercontent-endpoint,
231+
$config?owner,
232+
$config?repo,
233+
$sha,
234+
escape-html-uri($filename)
235+
), "/")
236+
return github:download-file($blob-url, $config?token)
237+
)
217238
};
218239

219240
(:~
@@ -282,8 +303,14 @@ declare %private function github:has-next-page($response as element(http:respons
282303
return contains($link-header, 'rel="next"')
283304
};
284305

306+
(: api calls :)
285307
declare %private function github:request-json($url as xs:string, $token as xs:string?) {
286-
let $response := app:request-json(github:build-request($url, $token))
308+
let $response :=
309+
app:request-json(
310+
github:build-request($url, (
311+
<http:header name="Accept" value="application/vnd.github.v3+json" />,
312+
github:auth-header($token))
313+
))
287314

288315
return (
289316
if (github:has-next-page($response[1]))
@@ -293,17 +320,20 @@ declare %private function github:request-json($url as xs:string, $token as xs:st
293320
)
294321
};
295322

296-
declare %private function github:request($url as xs:string, $token as xs:string?) {
297-
app:request(github:build-request($url, $token))[2]
323+
(: raw file downloads :)
324+
declare %private function github:download-file ($url as xs:string, $token as xs:string?) {
325+
app:request(
326+
github:build-request($url,
327+
github:auth-header($token)))[2]
298328
};
299329

300-
declare %private function github:build-request($url as xs:string, $token as xs:string?) as element(http:request) {
301-
<http:request http-version="1.1" href="{$url}" method="get">
302-
<http:header name="Accept" value="application/vnd.github.v3+json" />
303-
{
304-
if (empty($token) or $token = "")
305-
then ()
306-
else <http:header name="Authorization" value="token {$token}"/>
307-
}
308-
</http:request>
330+
declare %private function github:auth-header($token as xs:string?) as element(http:header)? {
331+
if (empty($token) or $token = "")
332+
then ()
333+
else <http:header name="Authorization" value="token {$token}"/>
334+
};
335+
336+
declare %private function github:build-request($url as xs:string, $headers as element(http:header)*) as element(http:request) {
337+
<http:request http-version="1.1" href="{$url}" method="get">{ $headers }</http:request>
309338
};
339+

0 commit comments

Comments
 (0)