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