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 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:

387
main.go
View File

@@ -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: <address>:<port no>
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://<address>:<port no>
BackendAddressWithHTTP string
// BackEndApiAddress Refers to the Peernet address ex: <address>:<port no>
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://<address>:<port no>
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=@<file name>
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=@<file name>
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
}
// ---------------------------------------------------------------------------------------------
}

View File

@@ -2,7 +2,7 @@
<html lang="en">
<head>
<title>Peernet Download file</title>
<title>Peernet Upload file</title>
<meta charset="utf-8">
<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>
<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">
<!-- <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>
<input class="btn btn-white btn-outline-white" type="submit" value="Submit">
<!-- {{ if .hash }}
<h3> hash: {{ .hash }} </h3>
{{end}} -->
{{ if .error }}
<h3 style="color:red"> Error: {{ .error }} </h3>
{{end}}
</form>
<h3 style="color:white"> or </h3>
<h4 style="color:white">curl {{ .address }}/uploadCurl -F add=@&lt;file name&gt;</h4>
<!-- <h3 style="color:white"> or </h3>-->
<!-- <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> -->
<br>
<br>
@@ -69,17 +69,17 @@
<p> {{ .size }} bytes</p>
{{end}}
</div>
<div class="form-group mb-3">
<label class="label" for="name">File Hash:</label>
{{ if .hash }}
<p> {{ .hash }} </p>
{{end}}
</div>
<!-- <div class="form-group mb-3">-->
<!-- <label class="label" for="name">File Hash:</label>-->
<!-- {{ if .hash }}-->
<!-- <p> {{ .hash }} </p>-->
<!-- {{end}}-->
<!-- </div>-->
<div class="form-group mb-3">
<label class="label" for="name">Sharable Link:</label>
<br>
{{ if .link }}
<a href="{{ .link }}" style="color:#1d91ac">{{ .filename }} link</a>
<a href="{{ .link }}" style="color:#1d91ac" target="_blank">{{ .filename }} link</a>
{{end}}
</div>
<!-- <div class="form-group mb-3">
@@ -89,7 +89,7 @@
<label class="label" for="name">File Name:</label>
<p>Test.txt</p>
</div> -->
</div>
<!-- </div>-->
<div class="form-group d-md-flex">
<!-- <div class="w-50 text-left">
<label class="checkbox-wrap checkbox-primary mb-0">Remember Me