git ssb

30+

cel / git-ssb-web



Commit 748376976f9403a66ed5bd23db3852f68de0169f

Start implementing git dumb http protocol

Charles Lehner committed on 10/16/2016, 6:24:12 AM
Parent: 4fea9e457824fd965a913b00273827f2032f1731

Files changed

lib/repos/index.jschanged
lib/repos/index.jsView
@@ -9,8 +9,9 @@
99 var u = require('../util')
1010 var paginate = require('../paginate')
1111 var markdown = require('../markdown')
1212 var forms = require('../forms')
13 +var ssbRef = require('ssb-ref')
1314
1415 module.exports = function (web) {
1516 return new RepoRoutes(web)
1617 }
@@ -134,8 +135,35 @@
134135 case 'compare':
135136 return this.pulls.serveRepoCompare(req, repo)
136137 case 'comparing':
137138 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)
138166 default:
139167 return this.web.serve404(req)
140168 }
141169 }
@@ -978,4 +1006,115 @@
9781006 return issue.msg.value.content.type == 'pull-request'
9791007 ? this.pulls.serveRepoPullReq(req, repo, issue, path, id)
9801008 : this.issues.serveRepoIssue(req, repo, issue, path, id)
9811009 }
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