FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Reduced write operations for temp files, enhanced tests, minor change… · myCodebox/Gokapi@72aba12 · GitHub

forked from Forceu/Gokapi

Commit 72aba12

Browse files
committed
Reduced write operations for temp files, enhanced tests, minor changes to readme
1 parent ec85056 commit 72aba12

7 files changed

Lines changed: 65 additions & 32 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Gokapi is a lightweight server to share files, which expire after a set amount o
1515

1616
This enables companies or individuals to share their files very easily and having them removed afterwards, therefore saving disk space and having control over who downloads the file from the server.
1717

18-
Customization is very easy with HTML/CSS knowledge. Identical files will be deduplicated. An API is available to interact with Gokapi.
18+
Identical files will be deduplicated. An API is available to interact with Gokapi. Customization is very easy with HTML/CSS knowledge.
1919

2020

2121
## Screenshots

‎internal/storage/FileServing.go‎

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ import (
3030
// it into the global configuration.
3131
func NewFile(fileContent io.Reader, fileHeader *multipart.FileHeader, uploadRequest models.UploadRequest) (models.File, error) {
3232
id := helper.GenerateRandomString(configuration.GetLengthId())
33+
var hasBeenRenamed bool
3334
reader, hash, tempFile := generateHash(fileContent, fileHeader, uploadRequest)
34-
defer deleteTempFile(tempFile)
35+
defer deleteTempFile(tempFile, &hasBeenRenamed)
3536
file := models.File{
3637
Id: id,
3738
Name: fileHeader.Filename,
@@ -50,36 +51,46 @@ func NewFile(fileContent io.Reader, fileHeader *multipart.FileHeader, uploadRequ
5051
file.AwsBucket = settings.AwsBucket
5152
settings.Files[id] = file
5253
configuration.ReleaseAndSave()
53-
if !aws.IsCredentialProvided(false) {
54-
if !helper.FileExists(dataDir + "/" + file.SHA256) {
55-
destinationFile, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
56-
if err != nil {
57-
return models.File{}, err
58-
}
59-
defer destinationFile.Close()
60-
_, err = io.Copy(destinationFile, reader)
61-
if err != nil {
62-
return models.File{}, err
63-
}
64-
}
65-
} else {
54+
if aws.IsCredentialProvided(false) {
6655
_, err := aws.Upload(reader, file)
6756
if err != nil {
6857
return models.File{}, err
6958
}
59+
return file, nil
60+
}
61+
if !helper.FileExists(dataDir + "/" + file.SHA256) {
62+
if tempFile != nil {
63+
err := tempFile.Close()
64+
helper.Check(err)
65+
err = os.Rename(tempFile.Name(), dataDir+"/"+file.SHA256)
66+
helper.Check(err)
67+
hasBeenRenamed = true
68+
return file, nil
69+
}
70+
destinationFile, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
71+
if err != nil {
72+
return models.File{}, err
73+
}
74+
defer destinationFile.Close()
75+
_, err = io.Copy(destinationFile, reader)
76+
if err != nil {
77+
return models.File{}, err
78+
}
7079
}
7180
return file, nil
7281
}
7382

74-
func deleteTempFile(file *os.File) {
75-
if file == nil {
76-
return
83+
func deleteTempFile(file *os.File, hasBeenRenamed *bool) {
84+
if file != nil && !*hasBeenRenamed {
85+
err := file.Close()
86+
helper.Check(err)
87+
err = os.Remove(file.Name())
88+
helper.Check(err)
7789
}
78-
file.Close()
79-
err := os.Remove(file.Name())
80-
helper.Check(err)
8190
}
8291

92+
// Generates the SHA1 hash of an uploaded file and returns a reader for the file, the hash and if a temporary file was created the
93+
// reference to that file.
8394
func generateHash(fileContent io.Reader, fileHeader *multipart.FileHeader, uploadRequest models.UploadRequest) (io.Reader, []byte, *os.File) {
8495
hash := sha1.New()
8596
if fileHeader.Size <= int64(uploadRequest.MaxMemory)*1024*1024 {
@@ -90,12 +101,12 @@ func generateHash(fileContent io.Reader, fileHeader *multipart.FileHeader, uploa
90101
}
91102
tempFile, err := os.CreateTemp(uploadRequest.DataDir, "upload")
92103
helper.Check(err)
93-
_, err = io.Copy(tempFile, fileContent)
94-
helper.Check(err)
95-
_, err = io.Copy(hash, tempFile)
104+
multiWriter := io.MultiWriter(tempFile, hash)
105+
_, err = io.Copy(multiWriter, fileContent)
96106
helper.Check(err)
97107
_, err = tempFile.Seek(0, io.SeekStart)
98108
helper.Check(err)
109+
// Instead of returning a reference to the file as the 3rd result, one could use reflections. However that would be more expensive.
99110
return tempFile, hash.Sum(nil), tempFile
100111
}
101112

‎internal/storage/FileServing_test.go‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"Gokapi/internal/test"
99
"Gokapi/internal/test/testconfiguration"
1010
"bytes"
11+
"io"
1112
"io/ioutil"
1213
"mime/multipart"
1314
"net/http/httptest"
@@ -116,10 +117,17 @@ func TestNewFile(t *testing.T) {
116117
MaxMemory: 10,
117118
DataDir: "test/data",
118119
}
120+
// Also testing renaming of temp file
119121
file, err = NewFile(bigFile, &header, request)
120122
test.IsNil(t, err)
121123
test.IsEqualString(t, file.Name, "bigfile")
122-
test.IsEqualString(t, file.SHA256, "da39a3ee5e6b4b0d3255bfef95601890afd80709")
124+
test.IsEqualString(t, file.SHA256, "9674344c90c2f0646f0b78026e127c9b86e3ad77")
125+
test.IsEqualString(t, file.Size, "20.0 MB")
126+
_, err = bigFile.Seek(0, io.SeekStart)
127+
test.IsNil(t, err)
128+
// Testing removal of temp file
129+
test.IsEqualString(t, file.Name, "bigfile")
130+
test.IsEqualString(t, file.SHA256, "9674344c90c2f0646f0b78026e127c9b86e3ad77")
123131
test.IsEqualString(t, file.Size, "20.0 MB")
124132
bigFile.Close()
125133
os.Remove("bigfile")
@@ -129,7 +137,7 @@ func TestNewFile(t *testing.T) {
129137
file, err = NewFile(bytes.NewReader(content), &header, request)
130138
test.IsNil(t, err)
131139
test.IsEqualString(t, file.Name, "bigfile")
132-
test.IsEqualString(t, file.SHA256, "da39a3ee5e6b4b0d3255bfef95601890afd80709")
140+
test.IsEqualString(t, file.SHA256, "f1474c19eff0fc8998fa6e1b1f7bf31793b103a6")
133141
test.IsEqualString(t, file.Size, "20.0 MB")
134142
testconfiguration.DisableS3()
135143
}

‎internal/test/TestHelper.go‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,20 @@ import (
1818

1919
type MockT interface {
2020
Errorf(format string, args ...interface{})
21+
Helper()
2122
}
2223

2324
// IsEqualString fails test if got and want are not identical
2425
func IsEqualString(t MockT, got, want string) {
26+
t.Helper()
2527
if got != want {
2628
t.Errorf("Assertion failed, got: %s, want: %s.", got, want)
2729
}
2830
}
2931

3032
// ResponseBodyContains fails test if http response does contain string
3133
func ResponseBodyContains(t MockT, got *httptest.ResponseRecorder, want string) {
34+
t.Helper()
3235
result, _ := io.ReadAll(got.Result().Body)
3336
if !strings.Contains(string(result), want) {
3437
t.Errorf("Assertion failed, got: %s, want: %s.", got, want)
@@ -37,55 +40,63 @@ func ResponseBodyContains(t MockT, got *httptest.ResponseRecorder, want string)
3740

3841
// IsNotEqualString fails test if got and want are not identical
3942
func IsNotEqualString(t MockT, got, want string) {
43+
t.Helper()
4044
if got == want {
4145
t.Errorf("Assertion failed, got: %s, want: not %s.", got, want)
4246
}
4347
}
4448

4549
// IsEqualBool fails test if got and want are not identical
4650
func IsEqualBool(t MockT, got, want bool) {
51+
t.Helper()
4752
if got != want {
4853
t.Errorf("Assertion failed, got: %t, want: %t.", got, want)
4954
}
5055
}
5156

5257
// IsEqualInt fails test if got and want are not identical
5358
func IsEqualInt(t MockT, got, want int) {
59+
t.Helper()
5460
if got != want {
5561
t.Errorf("Assertion failed, got: %d, want: %d.", got, want)
5662
}
5763
}
5864

5965
// IsNotEmpty fails test if string is empty
6066
func IsNotEmpty(t MockT, s string) {
67+
t.Helper()
6168
if s == "" {
6269
t.Errorf("Assertion failed, got: %s, want: empty.", s)
6370
}
6471
}
6572

6673
// IsEmpty fails test if string is not empty
6774
func IsEmpty(t MockT, s string) {
75+
t.Helper()
6876
if s != "" {
6977
t.Errorf("Assertion failed, got: %s, want: empty.", s)
7078
}
7179
}
7280

7381
// IsNil fails test if error not nil
7482
func IsNil(t MockT, got error) {
83+
t.Helper()
7584
if got != nil {
7685
t.Errorf("Assertion failed, got: %s, want: nil.", got.(error).Error())
7786
}
7887
}
7988

8089
// IsNotNil fails test if error is nil
8190
func IsNotNil(t MockT, got error) {
91+
t.Helper()
8292
if got == nil {
8393
t.Errorf("Assertion failed, got: nil, want: not nil.")
8494
}
8595
}
8696

8797
// HttpPageResult tests if a http server is outputting the correct result
8898
func HttpPageResult(t MockT, config HttpTestConfig) []*http.Cookie {
99+
t.Helper()
89100
config.init(t)
90101
client := &http.Client{}
91102

@@ -148,6 +159,7 @@ type HttpTestConfig struct {
148159
}
149160

150161
func (c *HttpTestConfig) init(t MockT) {
162+
t.Helper()
151163
if c.Url == "" {
152164
t.Errorf("No url passed!")
153165
}
@@ -183,6 +195,7 @@ type PostBody struct {
183195

184196
// HttpPostRequest sends a post request
185197
func HttpPostRequest(t MockT, config HttpTestConfig) {
198+
t.Helper()
186199
file, err := os.Open(config.UploadFileName)
187200
IsNil(t, err)
188201
defer file.Close()

‎internal/test/TestHelper_test.go‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type MockTest struct {
2323
func (t MockTest) Errorf(format string, args ...interface{}) {
2424
isFailed = true
2525
}
26+
func (t MockTest) Helper() {
27+
}
2628

2729
func (t *MockTest) WantFail() {
2830
t.Check()

‎internal/webserver/ssl/Ssl.go‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func isCertificatePresent() bool {
2929
return helper.FileExists(certificate) && helper.FileExists(key)
3030
}
3131

32+
// GetCertificateLocations returns the filepath of the public certificate and private key
3233
func GetCertificateLocations() (string, string) {
3334
if configDir == "" {
3435
env := environment.New()
@@ -37,16 +38,17 @@ func GetCertificateLocations() (string, string) {
3738
return configDir + "/ssl.crt", configDir + "/ssl.key"
3839
}
3940

41+
// GenerateIfInvalidCert checks validity of the SSL certificate and generates a new one if none is present or if it is expired
4042
func GenerateIfInvalidCert(extUrl string, forceGeneration bool) {
4143
if !isCertificatePresent() || forceGeneration {
4244
generateCertificates(extUrl)
4345
} else {
4446
days := getDaysRemaining()
45-
if days < 15 {
46-
fmt.Println("Certificate is valid for less than 15 days.")
47+
if days < 8 {
48+
fmt.Println("Certificate is valid for less than 8 days.")
4749
generateCertificates(extUrl)
4850
} else {
49-
fmt.Printf("Certificate is valid for %d days. A new one will be generated 14 days before expiration.\n", days)
51+
fmt.Printf("Certificate is valid for %d days. A new one will be generated 7 days before expiration.\n", days)
5052
}
5153
}
5254
}

‎internal/webserver/ssl/Ssl_test.go‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,3 @@ func TestGenerateIfInvalidCert(t *testing.T) {
6969
GenerateIfInvalidCert("http://127.0.0.1/", false)
7070
test.IsEqualInt(t, getDaysRemaining(), 365)
7171
}
72-
73-
// fingerprint 79294C898BB086DCCC8CCA1509849F482A4981978907A00E7BD1DE86B4B87F4F
74-
// valid until

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL