2019-01-23 11:56:51 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2022-09-02 22:18:23 +03:00
package integration
2019-01-23 11:56:51 +03:00
import (
"archive/zip"
"bytes"
2021-09-22 08:38:34 +03:00
"io"
2019-01-23 11:56:51 +03:00
"net/http"
2020-05-11 11:37:59 +03:00
"net/http/httptest"
2019-01-23 11:56:51 +03:00
"testing"
2022-06-12 18:51:54 +03:00
git_model "code.gitea.io/gitea/models/git"
2021-12-10 04:27:50 +03:00
repo_model "code.gitea.io/gitea/models/repo"
2021-07-24 19:03:58 +03:00
"code.gitea.io/gitea/modules/json"
2019-01-23 11:56:51 +03:00
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/setting"
2021-06-09 02:33:54 +03:00
"code.gitea.io/gitea/routers/web"
2022-09-02 22:18:23 +03:00
"code.gitea.io/gitea/tests"
2019-01-23 11:56:51 +03:00
gzipp "github.com/klauspost/compress/gzip"
2019-08-23 19:40:30 +03:00
"github.com/stretchr/testify/assert"
2019-01-23 11:56:51 +03:00
)
func storeObjectInRepo ( t * testing . T , repositoryID int64 , content * [ ] byte ) string {
2021-04-09 01:25:57 +03:00
pointer , err := lfs . GeneratePointer ( bytes . NewReader ( * content ) )
2019-01-23 11:56:51 +03:00
assert . NoError ( t , err )
2022-06-12 18:51:54 +03:00
_ , err = git_model . NewLFSMetaObject ( & git_model . LFSMetaObject { Pointer : pointer , RepositoryID : repositoryID } )
2019-01-23 11:56:51 +03:00
assert . NoError ( t , err )
2021-04-09 01:25:57 +03:00
contentStore := lfs . NewContentStore ( )
exist , err := contentStore . Exists ( pointer )
2020-09-08 18:45:10 +03:00
assert . NoError ( t , err )
if ! exist {
2021-04-09 01:25:57 +03:00
err := contentStore . Put ( pointer , bytes . NewReader ( * content ) )
2019-01-23 11:56:51 +03:00
assert . NoError ( t , err )
}
2021-04-09 01:25:57 +03:00
return pointer . Oid
2019-01-23 11:56:51 +03:00
}
2020-05-11 11:37:59 +03:00
func storeAndGetLfs ( t * testing . T , content * [ ] byte , extraHeader * http . Header , expectedStatus int ) * httptest . ResponseRecorder {
2021-12-10 04:27:50 +03:00
repo , err := repo_model . GetRepositoryByOwnerAndName ( "user2" , "repo1" )
2019-01-23 11:56:51 +03:00
assert . NoError ( t , err )
oid := storeObjectInRepo ( t , repo . ID , content )
2022-06-12 18:51:54 +03:00
defer git_model . RemoveLFSMetaObjectByOid ( repo . ID , oid )
2019-01-23 11:56:51 +03:00
session := loginUser ( t , "user2" )
// Request OID
req := NewRequest ( t , "GET" , "/user2/repo1.git/info/lfs/objects/" + oid + "/test" )
req . Header . Set ( "Accept-Encoding" , "gzip" )
2020-05-11 11:37:59 +03:00
if extraHeader != nil {
for key , values := range * extraHeader {
for _ , value := range values {
req . Header . Add ( key , value )
}
}
}
2020-10-31 23:51:48 +03:00
2020-05-11 11:37:59 +03:00
resp := session . MakeRequest ( t , req , expectedStatus )
2019-01-23 11:56:51 +03:00
2020-05-11 11:37:59 +03:00
return resp
}
func checkResponseTestContentEncoding ( t * testing . T , content * [ ] byte , resp * httptest . ResponseRecorder , expectGzip bool ) {
2019-01-23 11:56:51 +03:00
contentEncoding := resp . Header ( ) . Get ( "Content-Encoding" )
if ! expectGzip || ! setting . EnableGzip {
assert . NotContains ( t , contentEncoding , "gzip" )
result := resp . Body . Bytes ( )
assert . Equal ( t , * content , result )
} else {
assert . Contains ( t , contentEncoding , "gzip" )
gzippReader , err := gzipp . NewReader ( resp . Body )
assert . NoError ( t , err )
2021-09-22 08:38:34 +03:00
result , err := io . ReadAll ( gzippReader )
2019-01-23 11:56:51 +03:00
assert . NoError ( t , err )
assert . Equal ( t , * content , result )
}
}
func TestGetLFSSmall ( t * testing . T ) {
2022-09-02 22:18:23 +03:00
defer tests . PrepareTestEnv ( t ) ( )
2019-01-23 11:56:51 +03:00
content := [ ] byte ( "A very small file\n" )
2020-05-11 11:37:59 +03:00
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
checkResponseTestContentEncoding ( t , & content , resp , false )
2019-01-23 11:56:51 +03:00
}
func TestGetLFSLarge ( t * testing . T ) {
2022-09-02 22:18:23 +03:00
defer tests . PrepareTestEnv ( t ) ( )
2021-06-09 02:33:54 +03:00
content := make ( [ ] byte , web . GzipMinSize * 10 )
2019-01-23 11:56:51 +03:00
for i := range content {
content [ i ] = byte ( i % 256 )
}
2020-05-11 11:37:59 +03:00
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
checkResponseTestContentEncoding ( t , & content , resp , true )
2019-01-23 11:56:51 +03:00
}
func TestGetLFSGzip ( t * testing . T ) {
2022-09-02 22:18:23 +03:00
defer tests . PrepareTestEnv ( t ) ( )
2021-06-09 02:33:54 +03:00
b := make ( [ ] byte , web . GzipMinSize * 10 )
2019-01-23 11:56:51 +03:00
for i := range b {
b [ i ] = byte ( i % 256 )
}
outputBuffer := bytes . NewBuffer ( [ ] byte { } )
gzippWriter := gzipp . NewWriter ( outputBuffer )
gzippWriter . Write ( b )
gzippWriter . Close ( )
content := outputBuffer . Bytes ( )
2020-05-11 11:37:59 +03:00
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
checkResponseTestContentEncoding ( t , & content , resp , false )
2019-01-23 11:56:51 +03:00
}
func TestGetLFSZip ( t * testing . T ) {
2022-09-02 22:18:23 +03:00
defer tests . PrepareTestEnv ( t ) ( )
2021-06-09 02:33:54 +03:00
b := make ( [ ] byte , web . GzipMinSize * 10 )
2019-01-23 11:56:51 +03:00
for i := range b {
b [ i ] = byte ( i % 256 )
}
outputBuffer := bytes . NewBuffer ( [ ] byte { } )
zipWriter := zip . NewWriter ( outputBuffer )
fileWriter , err := zipWriter . Create ( "default" )
assert . NoError ( t , err )
fileWriter . Write ( b )
zipWriter . Close ( )
content := outputBuffer . Bytes ( )
2020-05-11 11:37:59 +03:00
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
checkResponseTestContentEncoding ( t , & content , resp , false )
}
func TestGetLFSRangeNo ( t * testing . T ) {
2022-09-02 22:18:23 +03:00
defer tests . PrepareTestEnv ( t ) ( )
2020-05-11 11:37:59 +03:00
content := [ ] byte ( "123456789\n" )
resp := storeAndGetLfs ( t , & content , nil , http . StatusOK )
assert . Equal ( t , content , resp . Body . Bytes ( ) )
}
func TestGetLFSRange ( t * testing . T ) {
2022-09-02 22:18:23 +03:00
defer tests . PrepareTestEnv ( t ) ( )
2020-05-11 11:37:59 +03:00
content := [ ] byte ( "123456789\n" )
tests := [ ] struct {
in string
out string
status int
} {
{ "bytes=0-0" , "1" , http . StatusPartialContent } ,
{ "bytes=0-1" , "12" , http . StatusPartialContent } ,
{ "bytes=1-1" , "2" , http . StatusPartialContent } ,
{ "bytes=1-3" , "234" , http . StatusPartialContent } ,
{ "bytes=1-" , "23456789\n" , http . StatusPartialContent } ,
// end-range smaller than start-range is ignored
{ "bytes=1-0" , "23456789\n" , http . StatusPartialContent } ,
{ "bytes=0-10" , "123456789\n" , http . StatusPartialContent } ,
// end-range bigger than length-1 is ignored
{ "bytes=0-11" , "123456789\n" , http . StatusPartialContent } ,
2020-10-31 23:51:48 +03:00
{ "bytes=11-" , "Requested Range Not Satisfiable" , http . StatusRequestedRangeNotSatisfiable } ,
2020-05-11 11:37:59 +03:00
// incorrect header value cause whole header to be ignored
{ "bytes=-" , "123456789\n" , http . StatusOK } ,
{ "foobar" , "123456789\n" , http . StatusOK } ,
}
for _ , tt := range tests {
t . Run ( tt . in , func ( t * testing . T ) {
h := http . Header {
"Range" : [ ] string { tt . in } ,
}
resp := storeAndGetLfs ( t , & content , & h , tt . status )
2021-06-06 02:59:27 +03:00
if tt . status == http . StatusPartialContent || tt . status == http . StatusOK {
assert . Equal ( t , tt . out , resp . Body . String ( ) )
} else {
var er lfs . ErrorResponse
2021-07-24 19:03:58 +03:00
err := json . Unmarshal ( resp . Body . Bytes ( ) , & er )
2021-06-06 02:59:27 +03:00
assert . NoError ( t , err )
assert . Equal ( t , tt . out , er . Message )
}
2020-05-11 11:37:59 +03:00
} )
}
2019-01-23 11:56:51 +03:00
}