From eb08c872740b5bf4ba1c2fa54902ab5867c2de3f Mon Sep 17 00:00:00 2001 From: Akilan Date: Tue, 8 Nov 2022 07:45:16 +0400 Subject: [PATCH] added changes https://github.com/PeernetOfficial/WebGatewayUpload/issues/3 --- README.md | 10 +- main.go | 387 ++++++++++++++++++++++-------------------- templates/upload.html | 32 ++-- 3 files changed, 228 insertions(+), 201 deletions(-) diff --git a/README.md b/README.md index 34ef60f..3917f4f 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,14 @@ go build . ``` ## Run -Run on default parameters +Run on default parameters (With Debug output) ``` ./WebGatewayUpload ``` +Run on Production mode +``` +./WebGatewayUpload -Production +``` Custom Flags ``` ./WebGatewayUpload -h @@ -26,6 +30,8 @@ Usage of ./WebGatewayUpload: SSL Certificate file (default "server.crt") -Key string SSL Key file (default "server.key") + -Production + Flag to check if required to run on production mode -SSL Flag to check if the SSL certificate is enabled or not -WebpageAddress string @@ -34,7 +40,7 @@ Usage of ./WebGatewayUpload: ## Routes - (GET) `/upload` (Opens upload page in the webgateway) -- (POST) `/uploadFile` (Uploads file to peernet from Webpage) +- (POST) `/upload` (Uploads file to peernet from Webpage) - (POST) `/uploadCurl` (Uploads file from CURL) Ex: diff --git a/main.go b/main.go index 6418e2f..a9fdfd1 100644 --- a/main.go +++ b/main.go @@ -1,40 +1,42 @@ package main import ( - "bytes" - "encoding/hex" - "encoding/json" - "errors" - "flag" - "fmt" - "github.com/PeernetOfficial/core" - "github.com/PeernetOfficial/core/btcec" - "github.com/PeernetOfficial/core/webapi" - "github.com/gin-gonic/gin" - "github.com/google/uuid" - limiter "github.com/julianshen/gin-limiter" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "time" + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "flag" + "fmt" + "github.com/PeernetOfficial/core" + "github.com/PeernetOfficial/core/btcec" + "github.com/PeernetOfficial/core/webapi" + "github.com/gin-gonic/gin" + "github.com/google/uuid" + limiter "github.com/julianshen/gin-limiter" + "io" + "io/ioutil" + "mime/multipart" + "net/http" + "time" ) // Variables for the flags to get the address var ( - // BackEndApiAddress Refers to the Peernet address ex:
: - BackEndApiAddress *string - // WebpageAddress Refers to the address for upload webgate server - WebpageAddress *string - // SSL To ensure SSL is required checks if SSL is required and subsequently - // checks if the certificate is provided - SSL *bool - // Certificate SSL Certificate file - Certificate *string - // Key SSL Key file - Key *string - // BackendAddressWithHTTP ex: http://
: - BackendAddressWithHTTP string + // BackEndApiAddress Refers to the Peernet address ex:
: + BackEndApiAddress *string + // WebpageAddress Refers to the address for upload webgate server + WebpageAddress *string + // SSL To ensure SSL is required checks if SSL is required and subsequently + // checks if the certificate is provided + SSL *bool + // Certificate SSL Certificate file + Certificate *string + // Key SSL Key file + Key *string + // BackendAddressWithHTTP ex: http://
: + BackendAddressWithHTTP string + // Production mode + Production *bool ) // ------------------------------------------------------------------------------------------------------------- @@ -43,32 +45,33 @@ var ( // init reading flags before any part of the code is executed func init() { - BackEndApiAddress = flag.String("BackEndApiAddress", "localhost:8088", "current environment") - WebpageAddress = flag.String("WebpageAddress", "localhost:8098", "current environment") - SSL = flag.Bool("SSL", false, "Flag to check if the SSL certificate is enabled or not") - Certificate = flag.String("Certificate", "server.crt", "SSL Certificate file") - Key = flag.String("Key", "server.key", "SSL Key file") + BackEndApiAddress = flag.String("BackEndApiAddress", "localhost:8088", "current environment") + WebpageAddress = flag.String("WebpageAddress", "localhost:8098", "current environment") + SSL = flag.Bool("SSL", false, "Flag to check if the SSL certificate is enabled or not") + Certificate = flag.String("Certificate", "server.crt", "SSL Certificate file") + Key = flag.String("Key", "server.key", "SSL Key file") + Production = flag.Bool("Production", false, "Flag to check if required to run on production mode") } // InitPeernet Initializes Peernet backend func InitPeernet() *core.Backend { - backend, status, err := core.Init("Your application/1.0", "Config.yaml", nil, nil) - if status != core.ExitSuccess { - fmt.Printf("Error %d initializing backend: %s\n", status, err.Error()) - return nil - } + backend, status, err := core.Init("Peernet Upload Application/1.0", "Config.yaml", nil, nil) + if status != core.ExitSuccess { + fmt.Printf("Error %d initializing backend: %s\n", status, err.Error()) + return nil + } - return backend + return backend } // RunPeernet Starts the WebAPI and peernet func RunPeernet(backend *core.Backend) { - webapi.Start(backend, []string{*BackEndApiAddress}, false, "", "", 10*time.Second, 10*time.Second, uuid.Nil) - backend.Connect() + webapi.Start(backend, []string{*BackEndApiAddress}, false, "", "", 10*time.Second, 10*time.Second, uuid.Nil) + backend.Connect() - for { + for { - } + } } // ------------------------------------------------------------------------------------------------------------- @@ -81,8 +84,8 @@ func RunPeernet(backend *core.Backend) { // ---------------------------------- Warehouse related structs --------------------------- type WarehouseResult struct { - Status int `json:"status"` - Hash []byte `json:"hash"` + Status int `json:"status"` + Hash []byte `json:"hash"` } // ----------------------------------------------------------------------------------------- @@ -90,20 +93,20 @@ type WarehouseResult struct { // BlockchainRequest blockchain backend API request struct type BlockchainRequest struct { - Files []File `json:"files"` + Files []File `json:"files"` } type File struct { - Hash []byte `json:"hash"` - Type int `json:"type"` - Name string `json:"name"` + Hash []byte `json:"hash"` + Type uint16 `json:"type"` + Name string `json:"name"` } // BlockchainResponse blockchain backend API response struct type BlockchainResponse struct { - Status int `json:"status"` - Height int `json:"height"` - Version int `json:"version"` + Status int `json:"status"` + Height int `json:"height"` + Version int `json:"version"` } // ----------------------------------------------------------------------------------------- @@ -120,55 +123,53 @@ type BlockchainResponse struct { // AddFileWarehouse API call for (Storing file in the warehouse) func AddFileWarehouse(file io.Reader) *WarehouseResult { - url := BackendAddressWithHTTP + "/warehouse/create" + url := BackendAddressWithHTTP + "/warehouse/create" - req, err := http.NewRequest("POST", url, file) - //req.Header.Set("X-Custom-Header", "myvalue") - //req.Header.Set("Content-Type", "application/json") + req, err := http.NewRequest("POST", url, file) + //req.Header.Set("X-Custom-Header", "myvalue") + //req.Header.Set("Content-Type", "application/json") - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - panic(err) - } - defer resp.Body.Close() + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() - //fmt.Println("response Status:", resp.Status) - //fmt.Println("response Headers:", resp.Header) - body, _ := ioutil.ReadAll(resp.Body) - //fmt.Println("response Body:", string(body)) - var result WarehouseResult - err = json.Unmarshal(body, &result) - if err != nil { - fmt.Println(err) - } + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + fmt.Println(err) + } + var result WarehouseResult + err = json.Unmarshal(body, &result) + if err != nil { + fmt.Println(err) + } - return &result + return &result } // UploadFile Simple abstracted function to add files to peernet core func UploadFile(backend *core.Backend, file *multipart.File, header *multipart.FileHeader) (*btcec.PublicKey, *WarehouseResult, error) { - buf := bytes.NewBuffer(nil) - if _, err := io.Copy(buf, *file); err != nil { - return nil, nil, errors.New("io.Copy not successful") - } + buf := bytes.NewBuffer(nil) + if _, err := io.Copy(buf, *file); err != nil { + return nil, nil, errors.New("io.Copy not successful") + } - // adds file to warehouse - warehouseResult := AddFileWarehouse(buf) - fmt.Println(warehouseResult.Hash) - // current using default port for Peernet api which is 8080 - // First add file to warehouse + // adds file to warehouse + warehouseResult := AddFileWarehouse(buf) + // current using default port for Peernet api which is 8080 + // First add file to warehouse - // Adds the file to a blockchain - Blockchainfo := AddFileToBlockchain(warehouseResult.Hash, header.Filename) - if Blockchainfo == nil { - return nil, nil, errors.New("add file to blockchain not successful") - } + // Adds the file to a blockchain + Blockchainfo := AddFileToBlockchain(warehouseResult.Hash, header.Filename) + if Blockchainfo == nil { + return nil, nil, errors.New("add file to blockchain not successful") + } - _, publicKey := backend.ExportPrivateKey() - fmt.Println(hex.EncodeToString(publicKey.SerializeCompressed())) + _, publicKey := backend.ExportPrivateKey() - return publicKey, warehouseResult, nil + return publicKey, warehouseResult, nil } // ----------------------------------------------------------------------------------------- @@ -176,39 +177,45 @@ func UploadFile(backend *core.Backend, file *multipart.File, header *multipart.F // AddFileToBlockchain The follwoing function adds the filename and hash to the blockchain func AddFileToBlockchain(hash []byte, filename string) *BlockchainResponse { - url := BackendAddressWithHTTP + "/blockchain/file/add" + url := BackendAddressWithHTTP + "/blockchain/file/add" - // Create file object for post - var blockchainRequest BlockchainRequest - var files File - files.Name = filename - files.Hash = hash - files.Type = 0 - blockchainRequest.Files = append(blockchainRequest.Files, files) + // Get file type + detectType, _, err := webapi.FileDetectType(filename) + if err != nil { + panic(err) + } - Byte, err := json.Marshal(blockchainRequest) + // Create file object for post + var blockchainRequest BlockchainRequest + var files File + files.Name = filename + files.Hash = hash + files.Type = detectType + blockchainRequest.Files = append(blockchainRequest.Files, files) - // convert bytes - req, err := http.NewRequest("POST", url, bytes.NewBuffer(Byte)) - //req.Header.Set("X-Custom-Header", "myvalue") - req.Header.Set("Content-Type", "application/json") + Byte, err := json.Marshal(blockchainRequest) - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - panic(err) - } - defer resp.Body.Close() + // convert bytes + req, err := http.NewRequest("POST", url, bytes.NewBuffer(Byte)) + //req.Header.Set("X-Custom-Header", "myvalue") + req.Header.Set("Content-Type", "application/json") - body, _ := ioutil.ReadAll(resp.Body) + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() - var result BlockchainResponse - err = json.Unmarshal(body, &result) - if err != nil { - return nil - } + body, _ := ioutil.ReadAll(resp.Body) - return &result + var result BlockchainResponse + err = json.Unmarshal(body, &result) + if err != nil { + return nil + } + + return &result } // ----------------------------------------------------------------------------------------- @@ -219,85 +226,99 @@ func AddFileToBlockchain(hash []byte, filename string) *BlockchainResponse { // ------------------------------------------------------------------------------------------------------------- func main() { - // Parsing flags - flag.Parse() + // Parsing flags + flag.Parse() - // Start peernet - backend := InitPeernet() - go RunPeernet(backend) + // Start peernet + backend := InitPeernet() + go RunPeernet(backend) - r := gin.Default() - r.LoadHTMLGlob("templates/*.html") - r.Static("/templates", "./templates") + var r *gin.Engine + if *Production { + gin.SetMode(gin.ReleaseMode) + r = gin.New() + } else { + r = gin.Default() + } + + r.LoadHTMLGlob("templates/*.html") + r.Static("/templates", "./templates") - // --------------------------------- Middleware rate limiter ----------------------------------- - lm := limiter.NewRateLimiter(time.Minute, 2, func(ctx *gin.Context) (string, error) { - return "", nil - }) - // --------------------------------------------------------------------------------------------- + // --------------------------------- Middleware rate limiter ----------------------------------- + lm := limiter.NewRateLimiter(time.Minute, 10, func(ctx *gin.Context) (string, error) { + return "", nil + }) + // --------------------------------------------------------------------------------------------- - // ---------------------------------------- Routes --------------------------------------------- - // GET /upload to open upload page from webgateway - r.GET("/upload", lm.Middleware(), func(c *gin.Context) { - c.HTML(http.StatusOK, "upload.html", nil) - }) + // ---------------------------------------- Routes --------------------------------------------- + // GET /upload to open upload page from webgateway + r.GET("/upload", lm.Middleware(), func(c *gin.Context) { + c.HTML(http.StatusOK, "upload.html", nil) + }) - // POST /uploadFile Uploads file to peernet from Webgateway - r.POST("/uploadFile", lm.Middleware(), func(c *gin.Context) { - file, header, err := c.Request.FormFile("file") - defer file.Close() + // POST /uploadFile Uploads file to peernet from Webgateway + r.POST("/upload", lm.Middleware(), func(c *gin.Context) { + file, header, err := c.Request.FormFile("file") + defer file.Close() - if err != nil { - fmt.Println(err) - } + if err != nil { + c.HTML(http.StatusBadRequest, "upload.html", gin.H{ + "error": "File not added during upload", + }) + return + } - publicKey, warehouseResult, err := UploadFile(backend, &file, header) - if err != nil { - fmt.Println(err) - } + publicKey, warehouseResult, err := UploadFile(backend, &file, header) + if err != nil { + c.HTML(http.StatusBadRequest, "upload.html", gin.H{ + "error": "File not added during upload", + }) + return + //fmt.Println(err) + } - c.HTML(http.StatusOK, "upload.html", gin.H{ - "hash": hex.EncodeToString(warehouseResult.Hash), - "filename": header.Filename, - "size": header.Size, - "link": "https://peer.ae/" + hex.EncodeToString(publicKey.SerializeCompressed()) + "/" + hex.EncodeToString(warehouseResult.Hash), - "address": *WebpageAddress, - }) + c.HTML(http.StatusOK, "upload.html", gin.H{ + "hash": hex.EncodeToString(warehouseResult.Hash), + "filename": header.Filename, + "size": header.Size, + "link": "https://peer.ae/" + hex.EncodeToString(publicKey.SerializeCompressed()) + "/" + hex.EncodeToString(warehouseResult.Hash), + "address": *WebpageAddress, + }) - }) + }) - // Implement CURL script to ensure linux users can upload directly - // the Cli like https://bashupload.com - // Ex: curl http://localhost:8080/uploadCurl -F add=@ - r.POST("/uploadCurl", lm.Middleware(), func(c *gin.Context) { - file, header, err := c.Request.FormFile("add") - defer file.Close() + // Implement CURL script to ensure linux users can upload directly + // the Cli like https://bashupload.com + // Ex: curl http://localhost:8080/uploadCurl -F add=@ + r.POST("/uploadCurl", lm.Middleware(), func(c *gin.Context) { + file, header, err := c.Request.FormFile("add") + defer file.Close() - if err != nil { - fmt.Println(err) - } + if err != nil { + fmt.Println(err) + } - publicKey, warehouseResult, err := UploadFile(backend, &file, header) - if err != nil { - fmt.Println(err) - } + publicKey, warehouseResult, err := UploadFile(backend, &file, header) + if err != nil { + fmt.Println(err) + } - link := "https://peer.ae/" + hex.EncodeToString(publicKey.SerializeCompressed()) + "/" + hex.EncodeToString(warehouseResult.Hash) - c.Data(http.StatusOK, "plain/text", []byte(link)) - }) + link := "https://peer.ae/" + hex.EncodeToString(publicKey.SerializeCompressed()) + "/" + hex.EncodeToString(warehouseResult.Hash) + c.Data(http.StatusOK, "plain/text", []byte(link)) + }) - // --------------------------------------------------------------------------------------------- + // --------------------------------------------------------------------------------------------- - // ---------------------------------- Start Gin server ----------------------------------------- - // check if SSL is used or not - if *SSL { - BackendAddressWithHTTP = "https://" + *BackEndApiAddress - r.RunTLS(*WebpageAddress, *Certificate, *Key) - *WebpageAddress = "https://" + *WebpageAddress - } else { - BackendAddressWithHTTP = "http://" + *BackEndApiAddress - r.Run(*WebpageAddress) - *WebpageAddress = "http://" + *WebpageAddress - } - // --------------------------------------------------------------------------------------------- + // ---------------------------------- Start Gin server ----------------------------------------- + // check if SSL is used or not + if *SSL { + BackendAddressWithHTTP = "https://" + *BackEndApiAddress + r.RunTLS(*WebpageAddress, *Certificate, *Key) + *WebpageAddress = "https://" + *WebpageAddress + } else { + BackendAddressWithHTTP = "http://" + *BackEndApiAddress + r.Run(*WebpageAddress) + *WebpageAddress = "http://" + *WebpageAddress + } + // --------------------------------------------------------------------------------------------- } diff --git a/templates/upload.html b/templates/upload.html index 6ad39ae..df80d2d 100644 --- a/templates/upload.html +++ b/templates/upload.html @@ -2,7 +2,7 @@ - Peernet Download file + Peernet Upload file @@ -25,18 +25,18 @@

Upload file to peernet



-
+
- +
- + {{ if .error }} +

Error: {{ .error }}

+ {{end}}
-

or

-

curl {{ .address }}/uploadCurl -F add=@<file name>

+ +

@@ -69,17 +69,17 @@

{{ .size }} bytes

{{end}} -
- - {{ if .hash }} -

{{ .hash }}

- {{end}} -
+ + + + + +

{{ if .link }} - {{ .filename }} link + {{ .filename }} link {{end}}
- +