implemented compression

This commit is contained in:
sad 2024-02-28 06:17:37 -07:00
parent 8459f9e4c8
commit 8e65053cc1
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG Key ID: 28D3A882F3E6AD02
2 changed files with 98 additions and 24 deletions

70
main.go
View File

@ -7,6 +7,9 @@ import (
"os" "os"
"strconv" "strconv"
"time" "time"
"compress/gzip"
"strings"
"bytes"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"github.com/gabriel-vasile/mimetype" "github.com/gabriel-vasile/mimetype"
@ -109,31 +112,76 @@ func Exists(path string) bool {
return true return true
} }
func isValidGzipHeader(data []byte) bool {
return len(data) >= 2 && data[0] == 0x1f && data[1] == 0x8b
}
func UploadHandler(w http.ResponseWriter, r *http.Request) { func UploadHandler(w http.ResponseWriter, r *http.Request) {
// expiry time // expiry time
var ttl int64 var ttl int64
ttl = 0 ttl = 0
file, _, err := r.FormFile("file") var file, header, err = r.FormFile("file")
if err != nil { if err != nil {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
defer file.Close() defer file.Close()
mtype, err := mimetype.DetectReader(file) var buffer bytes.Buffer
_, err = io.Copy(&buffer, file)
if err != nil { if err != nil {
w.Write([]byte("error detecting the mime type of your file\n")) log.Error().Err(err).Msg("error reading file data")
w.WriteHeader(http.StatusInternalServerError)
return
}
var data bytes.Buffer
var name = header.Filename
println("file: " + name)
if strings.HasSuffix(name, ".5000") {
buffer.WriteTo(&data)
if isValidGzipHeader(data.Bytes()[:2]) {
gz, err := gzip.NewReader(&data)
if err != nil {
log.Error().Err(err).Msg("error creating gzip reader")
w.WriteHeader(http.StatusInternalServerError)
return
}
defer gz.Close()
_, err = io.Copy(&buffer, gz)
if err != nil {
log.Error().Err(err).Msg("error decompressing gzip file")
w.WriteHeader(http.StatusInternalServerError)
return
}
name = strings.TrimSuffix(name, ".5000")
data.Write(buffer.Bytes())
} else {
log.Error().Msg("Invalid gzip file")
w.WriteHeader(http.StatusBadRequest)
return
}
} else {
data.Write(buffer.Bytes())
}
mtype, err := mimetype.DetectReader(&data)
if err != nil {
log.Error().Err(err).Msg("error detecting MIME type")
w.WriteHeader(http.StatusInternalServerError)
return return
} }
file.Seek(0, 0)
// Check if expiry time is present and length is too long // Check if expiry time is present and length is too long
if r.PostFormValue("expiry") != "" { if r.PostFormValue("expiry") != "" {
ttl, err = strconv.ParseInt(r.PostFormValue("expiry"), 10, 64) ttl, err = strconv.ParseInt(r.PostFormValue("expiry"), 10, 64)
if err != nil { if err != nil {
log.Error().Err(err).Msg("expiry could not be parsed") log.Error().Err(err).Msg("expiry could not be parsed")
w.WriteHeader(http.StatusBadRequest)
} else { } else {
// Get maximum ttl length from config and kill upload if specified ttl is too long, this can probably be handled better in the future // Get maximum ttl length from config and kill upload if specified ttl is too long, this can probably be handled better in the future
if ttl < 1 || ttl > int64(conf.MaxTTL) { if ttl < 1 || ttl > int64(conf.MaxTTL) {
@ -149,7 +197,6 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
} }
// generate + check name // generate + check name
var name string
for { for {
id := NameGen() id := NameGen()
name = id + mtype.Extension() name = id + mtype.Extension()
@ -167,7 +214,7 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
log.Error().Err(err).Msg("failed to put expiry") log.Error().Err(err).Msg("failed to put expiry")
} }
f, err := os.OpenFile(conf.FileFolder+"/"+name, os.O_WRONLY|os.O_CREATE, 0644) f, err := os.OpenFile(conf.FileFolder+"/"+name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil { if err != nil {
log.Error().Err(err).Msg("error opening a file for write") log.Error().Err(err).Msg("error opening a file for write")
w.WriteHeader(http.StatusInternalServerError) // change to json w.WriteHeader(http.StatusInternalServerError) // change to json
@ -175,10 +222,17 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
} }
defer f.Close() defer f.Close()
io.Copy(f, file) io.Copy(f, &buffer)
if err != nil {
log.Error().Err(err).Msg("error copying file")
w.WriteHeader(http.StatusInternalServerError)
return
}
buffer.Reset()
data.Reset()
log.Info().Str("name", name).Int64("ttl", ttl).Msg("wrote new file") log.Info().Str("name", name).Int64("ttl", ttl).Msg("wrote new file")
hostedurl := "https://" + conf.VHost + "/uploads/" + name hostedurl := "http://" + conf.VHost + "/uploads/" + name
w.Header().Set("Location", hostedurl) w.Header().Set("Location", hostedurl)
w.WriteHeader(http.StatusSeeOther) w.WriteHeader(http.StatusSeeOther)

View File

@ -1,6 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html style="overflow: hidden;"> <html style="overflow: hidden;">
<head> <head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.4/pako_deflate.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="//code.jquery.com/jquery-1.10.2.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="fist.ico"> <link rel="icon" href="fist.ico">
@ -241,16 +242,35 @@
</div> </div>
</body> </body>
</html> </html>
<script> <script>
$('#chooseFile').bind('change', function () { $(document).ready(function () {
var filename = $("#chooseFile").val(); $('#chooseFile').bind('change', function (e) {
if (/^\s*$/.test(filename)) { var file = e.target.files[0];
if (!file) {
$(".file-upload").removeClass('active'); $(".file-upload").removeClass('active');
$("#noFile").text("No file chosen..."); $("#noFile").text("No file chosen...");
return;
} }
else {
$(".file-upload").addClass('active'); $(".file-upload").addClass('active');
$("#noFile").text(filename.replace("C:\\fakepath\\", "")); $("#noFile").text(file.name.replace("C:\\fakepath\\", ""));
var reader = new FileReader();
reader.onload = function(event) {
var binaryData = event.target.result;
// Compress the file data
var compressed = pako.gzip(new Uint8Array(binaryData), { level:1});
var compressedFile = new Blob([compressed], { type: "application/gzip" });
updateFileInput(compressedFile, file.name);
};
reader.readAsArrayBuffer(file);
});
function updateFileInput(compressedFile, fileName) {
var dataTransfer = new DataTransfer();
dataTransfer.items.add(new File([compressedFile], fileName + '.5000'));
$('#chooseFile')[0].files = dataTransfer.files;
} }
}); });
</script> </script>