Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
17b9c68d
Commit
17b9c68d
authored
9 years ago
by
Marin Jankovski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move lfs handling into its separate file.
parent
60d7ae97
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
151 additions
and
5 deletions
+151
-5
githandler.go
githandler.go
+4
-5
lfs.go
lfs.go
+147
-0
No files found.
githandler.go
View file @
17b9c68d
...
...
@@ -47,6 +47,9 @@ type gitRequest struct {
// CommitId is used do prevent race conditions between the 'time of check'
// in the GitLab Rails app and the 'time of use' in gitlab-workhorse.
CommitId
string
// TODO: say something about this
StoreLFSPath
string
}
// Routing table
...
...
@@ -60,13 +63,9 @@ var gitServices = [...]gitService{
gitService
{
"GET"
,
"/repository/archive.tar.gz"
,
handleGetArchive
,
"tar.gz"
},
gitService
{
"GET"
,
"/repository/archive.tar.bz2"
,
handleGetArchive
,
"tar.bz2"
},
gitService
{
"PUT"
,
"/gitlab-lfs/objects"
,
handleStoreLfsObject
,
"lfs-object-receive"
},
gitService
{
"GET"
,
"/gitlab-lfs/objects"
,
handleRetreiveLfsObject
,
"lfs-object-upload"
},
}
var
(
errHashMismatch
=
errors
.
New
(
"Content hash does not match OID"
)
errSizeMismatch
=
errors
.
New
(
"Content size does not match"
)
)
func
newGitHandler
(
authBackend
string
,
authTransport
http
.
RoundTripper
)
*
gitHandler
{
return
&
gitHandler
{
&
http
.
Client
{
Transport
:
authTransport
},
authBackend
}
}
...
...
This diff is collapsed.
Click to expand it.
lfs.go
0 → 100644
View file @
17b9c68d
/*
In this file we handle git lfs objects downloads and uploads
*/
package
main
import
(
"compress/gzip"
"crypto/sha256"
"encoding/hex"
"errors"
"io"
"log"
"net/http"
"os"
"path/filepath"
"regexp"
"strconv"
)
var
(
errHashMismatch
=
errors
.
New
(
"Content hash does not match OID"
)
errSizeMismatch
=
errors
.
New
(
"Content size does not match"
)
)
func
handleStoreLfsObject
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
rpc
string
)
{
var
body
io
.
ReadCloser
var
err
error
urlPath
:=
r
.
URL
.
Path
regExp
:=
regexp
.
MustCompile
(
`([0-9a-f]{64})/([0-9]+)`
)
matches
:=
regExp
.
FindStringSubmatch
(
urlPath
)
if
matches
==
nil
{
log
.
Printf
(
"Found no object info in path: %s"
,
urlPath
)
return
}
oid
:=
matches
[
1
]
size
:=
matches
[
2
]
log
.
Printf
(
"Found oid: %s and size: %s"
,
oid
,
size
)
path
:=
filepath
.
Join
(
r
.
StoreLFSPath
,
transformKey
(
oid
))
tmpPath
:=
path
+
".tmp"
// TODO try removing gzip, possibly not needed
// The client request body may have been gzipped.
if
r
.
Header
.
Get
(
"Content-Encoding"
)
==
"gzip"
{
body
,
err
=
gzip
.
NewReader
(
r
.
Body
)
if
err
!=
nil
{
fail500
(
w
,
"Couldn't handle LFS upload request."
,
err
)
return
}
}
else
{
body
=
r
.
Body
}
defer
body
.
Close
()
// TODO maybe set dir permissions to 700
dir
:=
filepath
.
Dir
(
path
)
if
err
:=
os
.
MkdirAll
(
dir
,
0750
);
err
!=
nil
{
fail500
(
w
,
"Couldn't create directory for storing LFS objects."
,
err
)
return
}
// TODO use go library for creating TMP files
file
,
err
:=
os
.
OpenFile
(
tmpPath
,
os
.
O_CREATE
|
os
.
O_WRONLY
|
os
.
O_EXCL
,
0640
)
if
err
!=
nil
{
fail500
(
w
,
"Couldn't open tmp file for writing."
,
err
)
return
}
defer
os
.
Remove
(
tmpPath
)
defer
file
.
Close
()
hash
:=
sha256
.
New
()
hw
:=
io
.
MultiWriter
(
hash
,
file
)
written
,
err
:=
io
.
Copy
(
hw
,
body
)
if
err
!=
nil
{
fail500
(
w
,
"Failed to save received LFS object."
,
err
)
return
}
file
.
Close
()
sizeInt
,
err
:=
strconv
.
ParseInt
(
size
,
10
,
64
)
if
err
!=
nil
{
fail500
(
w
,
"Couldn't read size: "
,
err
)
return
}
if
written
!=
sizeInt
{
fail500
(
w
,
"Inconsistent size: "
,
errSizeMismatch
)
return
}
shaStr
:=
hex
.
EncodeToString
(
hash
.
Sum
(
nil
))
if
shaStr
!=
oid
{
fail500
(
w
,
"Inconsistent size: "
,
errSizeMismatch
)
return
}
if
err
:=
os
.
Rename
(
tmpPath
,
path
);
err
!=
nil
{
fail500
(
w
,
"Failed to rename temporary LFS object."
,
err
)
return
}
log
.
Printf
(
"Received the LFS object from client, oid: %s"
,
oid
)
return
}
func
handleRetreiveLfsObject
(
w
http
.
ResponseWriter
,
r
*
gitRequest
,
rpc
string
)
{
log
.
Printf
(
"I should download %s"
,
r
)
urlPath
:=
r
.
URL
.
Path
regExp
:=
regexp
.
MustCompile
(
`([0-9a-f]{64})\z`
)
oid
:=
regExp
.
FindString
(
urlPath
)
if
len
(
oid
)
==
0
{
log
.
Printf
(
"Found no object for download: %s"
,
urlPath
)
return
}
log
.
Printf
(
"Found oid: %s"
,
oid
)
path
:=
filepath
.
Join
(
r
.
StoreLFSPath
,
transformKey
(
oid
))
content
,
err
:=
os
.
Open
(
path
)
if
err
!=
nil
{
fail500
(
w
,
"Cannot get file: "
,
err
)
return
}
defer
content
.
Close
()
io
.
Copy
(
w
,
content
)
log
.
Printf
(
"Sent the LFS object to client, oid: %s"
,
oid
)
return
}
func
transformKey
(
key
string
)
string
{
if
len
(
key
)
<
5
{
return
key
}
return
filepath
.
Join
(
key
[
0
:
2
],
key
[
2
:
4
],
key
[
4
:
len
(
key
)])
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment