1 | /*
|
2 | * Copyright 2018 Adobe. All rights reserved.
|
3 | * This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
4 | * you may not use this file except in compliance with the License. You may obtain a copy
|
5 | * of the License at http://www.apache.org/licenses/LICENSE-2.0
|
6 | *
|
7 | * Unless required by applicable law or agreed to in writing, software distributed under
|
8 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
9 | * OF ANY KIND, either express or implied. See the License for the specific language
|
10 | * governing permissions and limitations under the License.
|
11 | */
|
12 |
|
13 | ;
|
14 |
|
15 | const { getObject, NotFoundError } = require('./git');
|
16 | const { resolveRepositoryPath } = require('./utils');
|
17 |
|
18 | /**
|
19 | * Export the api handler (express middleware) through a parameterizable function
|
20 | *
|
21 | * @param {object} options configuration hash
|
22 | * @returns {function(*, *, *)} handler function
|
23 | */
|
24 | function createMiddleware(options) {
|
25 | /**
|
26 | * Express middleware handling Git API Blob requests
|
27 | *
|
28 | * Only a small subset will be implemented
|
29 | *
|
30 | * @param {Request} req Request object
|
31 | * @param {Response} res Response object
|
32 | * @param {callback} next next middleware in chain
|
33 | *
|
34 | * @see https://developer.github.com/v3/git/blobs/#get-a-blob
|
35 | */
|
36 | return (req, res, next) => {
|
37 | // GET /repos/:owner/:repo/git/blobs/:file_sha
|
38 | const { owner } = req.params;
|
39 | const repoName = req.params.repo;
|
40 | const sha = req.params.file_sha;
|
41 | const host = req.mappedSubDomain ? `localhost:${options.listen[req.protocol].port}` : req.headers.host;
|
42 |
|
43 | const repPath = resolveRepositoryPath(options, owner, repoName);
|
44 |
|
45 | if (sha.match(/[0-9a-f]/g).length !== 40) {
|
46 | // invalid sha format
|
47 | res.status(422).json({
|
48 | message: 'The sha parameter must be exactly 40 characters and contain only [0-9a-f].',
|
49 | documentation_url: 'https://developer.github.com/v3/git/blobs/#get-a-blob',
|
50 | });
|
51 | return;
|
52 | }
|
53 | getObject(repPath, sha)
|
54 | .then(({ object: content }) => {
|
55 | res.json({
|
56 | sha,
|
57 | size: content.length,
|
58 | url: `${req.protocol}://${host}${req.path}`,
|
59 | content: `${content.toString('base64')}\n`,
|
60 | encoding: 'base64',
|
61 | });
|
62 | })
|
63 | .catch((err) => {
|
64 | // TODO: use generic errors
|
65 | if (err instanceof NotFoundError) {
|
66 | options.logger.debug(`[blobHandler] resource not found: ${err.message}`);
|
67 | res.status(404).json({
|
68 | message: 'Not Found',
|
69 | documentation_url: 'https://developer.github.com/v3/git/blobs/#get-a-blob',
|
70 | });
|
71 | } else {
|
72 | options.logger.debug(`[blobHandler] code: ${err.code} message: ${err.message} stack: ${err.stack}`);
|
73 | next(err);
|
74 | }
|
75 | });
|
76 | };
|
77 | }
|
78 | module.exports = createMiddleware;
|