Commit 748376976f9403a66ed5bd23db3852f68de0169f
Start implementing git dumb http protocol
Charles Lehner committed on 10/16/2016, 6:24:12 AMParent: 4fea9e457824fd965a913b00273827f2032f1731
Files changed
lib/repos/index.js | changed |
lib/repos/index.js | ||
---|---|---|
@@ -9,8 +9,9 @@ | ||
9 | 9 … | var u = require('../util') |
10 | 10 … | var paginate = require('../paginate') |
11 | 11 … | var markdown = require('../markdown') |
12 | 12 … | var forms = require('../forms') |
13 … | +var ssbRef = require('ssb-ref') | |
13 | 14 … | |
14 | 15 … | module.exports = function (web) { |
15 | 16 … | return new RepoRoutes(web) |
16 | 17 … | } |
@@ -134,8 +135,35 @@ | ||
134 | 135 … | case 'compare': |
135 | 136 … | return this.pulls.serveRepoCompare(req, repo) |
136 | 137 … | case 'comparing': |
137 | 138 … | return this.pulls.serveRepoComparing(req, repo) |
139 … | + case 'info': | |
140 … | + switch (path[1]) { | |
141 … | + case 'refs': | |
142 … | + return this.serveRepoRefs(req, repo) | |
143 … | + default: | |
144 … | + return this.web.serve404(req) | |
145 … | + } | |
146 … | + case 'objects': | |
147 … | + switch (path[1]) { | |
148 … | + case 'info': | |
149 … | + switch (path[2]) { | |
150 … | + case 'packs': | |
151 … | + return this.serveRepoPacksInfo(req, repo) | |
152 … | + default: | |
153 … | + return this.web.serve404(req) | |
154 … | + } | |
155 … | + case 'pack': | |
156 … | + return this.serveRepoPack(req, repo, filePath.join('/')) | |
157 … | + default: | |
158 … | + var hash = path[1] + path[2] | |
159 … | + if (hash.length === 40) { | |
160 … | + return this.serveRepoObject(req, repo, hash) | |
161 … | + } | |
162 … | + return this.web.serve404(req) | |
163 … | + } | |
164 … | + case 'HEAD': | |
165 … | + return this.serveRepoHead(req, repo) | |
138 | 166 … | default: |
139 | 167 … | return this.web.serve404(req) |
140 | 168 … | } |
141 | 169 … | } |
@@ -978,4 +1006,115 @@ | ||
978 | 1006 … | return issue.msg.value.content.type == 'pull-request' |
979 | 1007 … | ? this.pulls.serveRepoPullReq(req, repo, issue, path, id) |
980 | 1008 … | : this.issues.serveRepoIssue(req, repo, issue, path, id) |
981 | 1009 … | } |
1010 … | + | |
1011 … | +function getRepoLastMod(repo, cb) { | |
1012 … | + repo.getState(function (err, state) { | |
1013 … | + if (err) return cb(err) | |
1014 … | + var lastMod = new Date(Math.max.apply(Math, state.refs.map(function (ref) { | |
1015 … | + return ref.link.value.timestamp | |
1016 … | + }))) || new Date() | |
1017 … | + cb(null, lastMod) | |
1018 … | + }) | |
1019 … | +} | |
1020 … | + | |
1021 … | +R.serveRepoRefs = function (req, repo) { | |
1022 … | + var self = this | |
1023 … | + return u.readNext(function (cb) { | |
1024 … | + getRepoLastMod(repo, function (err, lastMod) { | |
1025 … | + if (err) return cb(null, self.web.serveError(req, err, 500)) | |
1026 … | + if (u.ifModifiedSince(req, lastMod)) { | |
1027 … | + return cb(null, pull.once([304])) | |
1028 … | + } | |
1029 … | + repo.getState(function (err, state) { | |
1030 … | + if (err) return cb(null, self.web.serveError(req, err, 500)) | |
1031 … | + var buf = state.refs.sort(function (a, b) { | |
1032 … | + return a.name > b.name ? 1 : a.name < b.name ? -1 : 0 | |
1033 … | + }).map(function (ref) { | |
1034 … | + return ref.hash + '\t' + ref.name + '\n' | |
1035 … | + }).join('') | |
1036 … | + cb(null, pull.values([[200, { | |
1037 … | + 'Content-Type': 'text/plain; charset=utf-8', | |
1038 … | + 'Content-Length': Buffer.byteLength(buf), | |
1039 … | + 'Last-Modified': lastMod.toGMTString() | |
1040 … | + }], buf])) | |
1041 … | + }) | |
1042 … | + }) | |
1043 … | + }) | |
1044 … | +} | |
1045 … | + | |
1046 … | +R.serveRepoObject = function (req, repo, sha1) { | |
1047 … | + var self = this | |
1048 … | + if (!/[0-9a-f]{20}/.test(sha1)) return pull.once([401]) | |
1049 … | + return u.readNext(function (cb) { | |
1050 … | + repo.getObjectFromAny(sha1, function (err, obj) { | |
1051 … | + if (err) return cb(null, | |
1052 … | + self.web.serveBuffer(404, req._t('error.BlobNotFound'))) | |
1053 … | + cb(null, pull(obj.read, self.web.serveRaw(obj.length))) | |
1054 … | + }) | |
1055 … | + }) | |
1056 … | +} | |
1057 … | + | |
1058 … | +R.serveRepoHead = function (req, repo) { | |
1059 … | + var self = this | |
1060 … | + return u.readNext(function (cb) { | |
1061 … | + repo.getHead(function (err, name) { | |
1062 … | + if (err) return cb(null, pull.once([500])) | |
1063 … | + return cb(null, self.web.serveBuffer(200, 'ref: ' + name)) | |
1064 … | + }) | |
1065 … | + }) | |
1066 … | +} | |
1067 … | + | |
1068 … | +R.serveRepoPacksInfo = function (req, repo) { | |
1069 … | + var self = this | |
1070 … | + return u.readNext(function (cb) { | |
1071 … | + getRepoLastMod(repo, function (err, lastMod) { | |
1072 … | + if (err) return cb(null, self.web.serveError(req, err, 500)) | |
1073 … | + if (u.ifModifiedSince(req, lastMod)) { | |
1074 … | + return cb(null, pull.once([304])) | |
1075 … | + } | |
1076 … | + cb(null, cat([ | |
1077 … | + pull.once([200, { | |
1078 … | + 'Content-Type': 'text/plain; charset=utf-8', | |
1079 … | + 'Last-Modified': lastMod.toGMTString() | |
1080 … | + }]), | |
1081 … | + pull( | |
1082 … | + repo.packs(), | |
1083 … | + pull.map(function (pack) { | |
1084 … | + return 'P ' + pack.packId + '-' + pack.idxId + '.pack\n' | |
1085 … | + }) | |
1086 … | + ) | |
1087 … | + ])) | |
1088 … | + }) | |
1089 … | + }) | |
1090 … | +} | |
1091 … | + | |
1092 … | +R.serveRepoPack = function (req, repo, name) { | |
1093 … | + var m = name.match(/(.*)-(.*)\.(pack|idx)$/) | |
1094 … | + if (!m) return pull.once([400]) | |
1095 … | + | |
1096 … | + var self = this | |
1097 … | + return u.readNext(function (cb) { | |
1098 … | + if (m[3] === 'pack') { | |
1099 … | + var packId = m[1] | |
1100 … | + if (!ssbRef.isBlobId(packId)) return cb(null, pull.once([400])) | |
1101 … | + repo.getPackfile(packId, function (err, read) { | |
1102 … | + if (err) return cb(err) | |
1103 … | + cb(null, pull(read, | |
1104 … | + self.web.serveRaw(null, 'application/x-git-packed-objects') | |
1105 … | + )) | |
1106 … | + }) | |
1107 … | + } | |
1108 … | + | |
1109 … | + if (m[3] === 'idx') { | |
1110 … | + var idxId = m[2] | |
1111 … | + if (!ssbRef.isBlobId(idxId)) return cb(null, pull.once([400])) | |
1112 … | + repo.getPackIndex(idxId, function (err, read) { | |
1113 … | + if (err) return cb(err) | |
1114 … | + cb(null, pull(read, | |
1115 … | + self.web.serveRaw(null, 'application/x-git-packed-objects-toc') | |
1116 … | + )) | |
1117 … | + }) | |
1118 … | + } | |
1119 … | + }) | |
1120 … | +} |
Built with git-ssb-web