forked from vlang/gitly
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit.v
80 lines (74 loc) · 1.94 KB
/
git.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by a GPL license that can be found in the LICENSE file.
module main
import vweb
import strings
enum GitService {
receive
upload
unknown
}
fn (s GitService) to_str() string {
return match s {
.receive { 'receive-pack' }
.upload { 'upload-pack' }
else { 'unknown' }
}
}
// /vlang/info/refs?service=git-upload-pack
fn (mut app App) git_info() vweb.Result {
app.info('/info/refs')
app.info(app.req.method.str())
// Get service type from the git request.
// Receive (git push) or upload (git pull)
url := app.req.url
service := if url.contains('?service=git-upload-pack') {
GitService.upload
} else if url.contains('?service=git-receive-pack') {
GitService.receive
} else {
GitService.unknown
}
if service == .unknown {
return app.info('git: unknown info/refs service: $url')
}
// Do auth here, we can communicate with the client only in inforefs
if false && !app.repo.is_public {
// Private repos are always closed
// if !auth() {
return app.not_found()
// }
} else {
// public repo push
if service == .receive {
user := '' // get_user(c)
app.info('info/refs user="$user"')
if user == '' {
// app.vweb.write_header(http.status_unauthorized)
return app.not_found()
}
}
}
app.set_content_type('application/x-git-$service-advertisement')
// hdrNocache(c.Writer)
app.add_header('Cache-Control', 'no-cache')
mut sb := strings.new_builder(100)
sb.write(packet_write('# service=git-$service\n'))
sb.write(packet_flush())
refs := app.repo.git_advertise(service.to_str())
app.info('refs = ')
app.info(refs)
sb.write(refs)
return app.ok(sb.str())
}
fn packet_flush() string {
return '0000' // .bytes()
}
fn packet_write(str string) string {
// s := strconv.format_int(i64(str.len+4), 16)
mut s := (str.len + 4).hex()
if s.len % 4 != 0 {
s = strings.repeat(`0`, 4 - s.len % 4) + s
}
return s + str
}