2022-11-08 07:45:16 +04:00
parent 7697d9ea3e
commit eb08c87274
3 changed files with 228 additions and 201 deletions

View File

@@ -11,10 +11,14 @@ go build .
``` ```
## Run ## Run
Run on default parameters Run on default parameters (With Debug output)
``` ```
./WebGatewayUpload ./WebGatewayUpload
``` ```
Run on Production mode
```
./WebGatewayUpload -Production
```
Custom Flags Custom Flags
``` ```
./WebGatewayUpload -h ./WebGatewayUpload -h
@@ -26,6 +30,8 @@ Usage of ./WebGatewayUpload:
SSL Certificate file (default "server.crt") SSL Certificate file (default "server.crt")
-Key string -Key string
SSL Key file (default "server.key") SSL Key file (default "server.key")
-Production
Flag to check if required to run on production mode
-SSL -SSL
Flag to check if the SSL certificate is enabled or not Flag to check if the SSL certificate is enabled or not
-WebpageAddress string -WebpageAddress string
@@ -34,7 +40,7 @@ Usage of ./WebGatewayUpload:
## Routes ## Routes
- (GET) `/upload` (Opens upload page in the webgateway) - (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) - (POST) `/uploadCurl` (Uploads file from CURL)
Ex: Ex:

387
main.go
View File

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

View File

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<title>Peernet Download file</title> <title>Peernet Upload file</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
@@ -25,18 +25,18 @@
<h2 class="Peernetblue">Upload file to peernet</h2> <h2 class="Peernetblue">Upload file to peernet</h2>
<br> <br>
<br> <br>
<form class="form-group" method="POST" action="/uploadFile" enctype="multipart/form-data"> <form class="form-group" method="POST" action="/upload" enctype="multipart/form-data">
<div class="form-group mb-3"> <div class="form-group mb-3">
<!-- <label for="formFileLg" class="form-label">Upload your file</label> --> <!-- <label for="formFileLg" class="form-label">Upload your file</label> -->
<input class="btn btn-white btn-outline-white" id="formFileLg" type="file" name="file"> <input class="btn btn-white btn-outline-white" id="formFileLg" type="file" name="file" required>
</div> </div>
<input class="btn btn-white btn-outline-white" type="submit" value="Submit"> <input class="btn btn-white btn-outline-white" type="submit" value="Submit">
<!-- {{ if .hash }} {{ if .error }}
<h3> hash: {{ .hash }} </h3> <h3 style="color:red"> Error: {{ .error }} </h3>
{{end}} --> {{end}}
</form> </form>
<h3 style="color:white"> or </h3> <!-- <h3 style="color:white"> or </h3>-->
<h4 style="color:white">curl {{ .address }}/uploadCurl -F add=@&lt;file name&gt;</h4> <!-- <h4 style="color:white">curl {{ .address }}/uploadCurl -F add=@&lt;file name&gt;</h4>-->
<!-- <a href="#" class="btn btn-white btn-outline-white" tyle="color:#3ac4e2">Upload file</a> --> <!-- <a href="#" class="btn btn-white btn-outline-white" tyle="color:#3ac4e2">Upload file</a> -->
<br> <br>
<br> <br>
@@ -69,17 +69,17 @@
<p> {{ .size }} bytes</p> <p> {{ .size }} bytes</p>
{{end}} {{end}}
</div> </div>
<div class="form-group mb-3"> <!-- <div class="form-group mb-3">-->
<label class="label" for="name">File Hash:</label> <!-- <label class="label" for="name">File Hash:</label>-->
{{ if .hash }} <!-- {{ if .hash }}-->
<p> {{ .hash }} </p> <!-- <p> {{ .hash }} </p>-->
{{end}} <!-- {{end}}-->
</div> <!-- </div>-->
<div class="form-group mb-3"> <div class="form-group mb-3">
<label class="label" for="name">Sharable Link:</label> <label class="label" for="name">Sharable Link:</label>
<br> <br>
{{ if .link }} {{ if .link }}
<a href="{{ .link }}" style="color:#1d91ac">{{ .filename }} link</a> <a href="{{ .link }}" style="color:#1d91ac" target="_blank">{{ .filename }} link</a>
{{end}} {{end}}
</div> </div>
<!-- <div class="form-group mb-3"> <!-- <div class="form-group mb-3">
@@ -89,7 +89,7 @@
<label class="label" for="name">File Name:</label> <label class="label" for="name">File Name:</label>
<p>Test.txt</p> <p>Test.txt</p>
</div> --> </div> -->
</div> <!-- </div>-->
<div class="form-group d-md-flex"> <div class="form-group d-md-flex">
<!-- <div class="w-50 text-left"> <!-- <div class="w-50 text-left">
<label class="checkbox-wrap checkbox-primary mb-0">Remember Me <label class="checkbox-wrap checkbox-primary mb-0">Remember Me