Skip to content

Commit fd72500

Browse files
committed
Return 400 but not 500 when request archive with wrong format
1 parent 5233051 commit fd72500

File tree

4 files changed

+81
-9
lines changed

4 files changed

+81
-9
lines changed

integrations/api_repo_archive_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2018 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package integrations
6+
7+
import (
8+
"fmt"
9+
"io"
10+
"net/http"
11+
"net/url"
12+
"testing"
13+
14+
"code.gitea.io/gitea/models"
15+
"code.gitea.io/gitea/models/unittest"
16+
17+
"github.com/stretchr/testify/assert"
18+
)
19+
20+
func TestAPIDownloadArchive(t *testing.T) {
21+
defer prepareTestEnv(t)()
22+
23+
repo := unittest.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
24+
user2 := unittest.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
25+
session := loginUser(t, user2.LowerName)
26+
token := getTokenForLoggedInUser(t, session)
27+
28+
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.zip", user2.Name, repo.Name))
29+
link.RawQuery = url.Values{"token": {token}}.Encode()
30+
resp := MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
31+
bs, err := io.ReadAll(resp.Body)
32+
assert.NoError(t, err)
33+
assert.EqualValues(t, 320, len(bs))
34+
35+
link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.tar.gz", user2.Name, repo.Name))
36+
link.RawQuery = url.Values{"token": {token}}.Encode()
37+
resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
38+
bs, err = io.ReadAll(resp.Body)
39+
assert.NoError(t, err)
40+
assert.EqualValues(t, 266, len(bs))
41+
42+
link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.bundle", user2.Name, repo.Name))
43+
link.RawQuery = url.Values{"token": {token}}.Encode()
44+
resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
45+
bs, err = io.ReadAll(resp.Body)
46+
assert.NoError(t, err)
47+
assert.EqualValues(t, 382, len(bs))
48+
49+
link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master", user2.Name, repo.Name))
50+
link.RawQuery = url.Values{"token": {token}}.Encode()
51+
MakeRequest(t, NewRequest(t, "GET", link.String()), 400)
52+
}

routers/web/repo/repo.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"code.gitea.io/gitea/modules/setting"
2323
"code.gitea.io/gitea/modules/storage"
2424
"code.gitea.io/gitea/modules/web"
25+
"code.gitea.io/gitea/services/archiver"
2526
archiver_service "code.gitea.io/gitea/services/archiver"
2627
"code.gitea.io/gitea/services/forms"
2728
repo_service "code.gitea.io/gitea/services/repository"
@@ -373,7 +374,11 @@ func Download(ctx *context.Context) {
373374
uri := ctx.Params("*")
374375
aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
375376
if err != nil {
376-
ctx.ServerError("archiver_service.NewRequest", err)
377+
if errors.Is(err, archiver.ErrUnknowArchiveFormat{}) {
378+
ctx.Error(http.StatusBadRequest, err.Error())
379+
} else {
380+
ctx.ServerError("archiver_service.NewRequest", err)
381+
}
377382
return
378383
}
379384
if aReq == nil {

services/archiver/archiver.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ type ArchiveRequest struct {
3939
// the way to 64.
4040
var shaRegex = regexp.MustCompile(`^[0-9a-f]{4,64}$`)
4141

42+
// ErrUnknowArchiveFormat request archive format is not supported
43+
type ErrUnknowArchiveFormat struct {
44+
RequestFormat string
45+
}
46+
47+
// Error implements error
48+
func (err ErrUnknowArchiveFormat) Error() string {
49+
return fmt.Sprintf("unknown format: %s", err.RequestFormat)
50+
}
51+
52+
// Is implements error
53+
func (ErrUnknowArchiveFormat) Is(err error) bool {
54+
_, ok := err.(ErrUnknowArchiveFormat)
55+
return ok
56+
}
57+
4258
// NewRequest creates an archival request, based on the URI. The
4359
// resulting ArchiveRequest is suitable for being passed to ArchiveRepository()
4460
// if it's determined that the request still needs to be satisfied.
@@ -59,7 +75,7 @@ func NewRequest(repoID int64, repo *git.Repository, uri string) (*ArchiveRequest
5975
ext = ".bundle"
6076
r.Type = git.BUNDLE
6177
default:
62-
return nil, fmt.Errorf("Unknown format: %s", uri)
78+
return nil, ErrUnknowArchiveFormat{RequestFormat: uri}
6379
}
6480

6581
r.refName = strings.TrimSuffix(uri, ext)

services/archiver/archiver_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package archiver
66

77
import (
8+
"errors"
89
"path/filepath"
910
"testing"
1011
"time"
@@ -19,10 +20,6 @@ func TestMain(m *testing.M) {
1920
unittest.MainTest(m, filepath.Join("..", ".."))
2021
}
2122

22-
func waitForCount(t *testing.T, num int) {
23-
24-
}
25-
2623
func TestArchive_Basic(t *testing.T) {
2724
assert.NoError(t, unittest.PrepareTestDatabase())
2825

@@ -83,11 +80,8 @@ func TestArchive_Basic(t *testing.T) {
8380
inFlight[2] = secondReq
8481

8582
ArchiveRepository(zipReq)
86-
waitForCount(t, 1)
8783
ArchiveRepository(tgzReq)
88-
waitForCount(t, 2)
8984
ArchiveRepository(secondReq)
90-
waitForCount(t, 3)
9185

9286
// Make sure sending an unprocessed request through doesn't affect the queue
9387
// count.
@@ -132,3 +126,8 @@ func TestArchive_Basic(t *testing.T) {
132126
assert.NotEqual(t, zipReq.GetArchiveName(), tgzReq.GetArchiveName())
133127
assert.NotEqual(t, zipReq.GetArchiveName(), secondReq.GetArchiveName())
134128
}
129+
130+
func TestErrUnknowArchiveFormat(t *testing.T) {
131+
var err = ErrUnknowArchiveFormat{RequestFormat: "master"}
132+
assert.True(t, errors.Is(err, ErrUnknowArchiveFormat{}))
133+
}

0 commit comments

Comments
 (0)