added fixes to upload to handle from client side js for adding files with the new upload spec

This commit is contained in:
2023-05-21 02:21:03 +01:00
parent 53cfee4363
commit 21971dca9e
3 changed files with 290 additions and 48 deletions

1
go.mod
View File

@@ -3,6 +3,7 @@ module github.com/PeernetOfficial/WebGatewayUpload
go 1.18
replace github.com/Akilan1999/p2p-rendering-computation => /Users/akilan/Documents/p2p-rendering-computation
replace github.com/PeernetOfficial/core => /Users/akilan/Documents/peernet/core
require (
github.com/Akilan1999/p2p-rendering-computation v0.0.0-00010101000000-000000000000

235
main.go
View File

@@ -16,6 +16,7 @@ import (
limiter "github.com/julianshen/gin-limiter"
"io"
"io/ioutil"
"log"
"mime/multipart"
"net"
"net/http"
@@ -77,7 +78,7 @@ func InitPeernet() *core.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)
webapi.Start(backend, []string{*BackEndApiAddress}, false, "", "", 200000*time.Second, 200000*time.Second, uuid.Nil)
backend.Connect()
for {
@@ -133,41 +134,162 @@ type BlockchainResponse struct {
// ---------------------------------- Warehouse related ------------------------------------
// AddFileWarehouse API call for (Storing file in the warehouse)
func AddFileWarehouse(file io.Reader) *WarehouseResult {
//func AddFileWarehouse(file io.Reader, id string) *WarehouseResult {
// route := BackendAddressWithHTTP + "/warehouse/create"
//
// form := url.Values{}
// form.Add("file", file)
// form.Add("ip", c.ip)
// form.Add("ua", c.ua)
// req.PostForm = form
//
// req, err := http.NewRequest("POST", route, file)
// //req.Header.Set("X-Custom-Header", "myvalue")
// req.Header.Set("Content-Type", "multipart/form-data")
//
// client := &http.Client{}
// resp, err := client.Do(req)
// if err != nil {
// panic(err)
// }
// defer resp.Body.Close()
//
// 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
//}
func AddFileWarehouse(File io.Reader, uuid string) (resp *WarehouseResult, err error) {
//// Prepare a form that you will submit to that URL.
//var b bytes.Buffer
//w := multipart.NewWriter(&b)
//for key, r := range values {
// var fw io.Writer
// if x, ok := r.(io.Closer); ok {
// defer x.Close()
// }
// // Add an image file
// if x, ok := r.(*os.File); ok {
// if fw, err = w.CreateFormFile(key, x.Name()); err != nil {
// return
// }
// } else {
// // Add other fields
// if fw, err = w.CreateFormField(key); err != nil {
// return
// }
// }
// if _, err = io.Copy(fw, r); err != nil {
// return nil, err
// }
//
//}
//// Don't forget to close the multipart writer.
//// If you don't close it, your request will be missing the terminating boundary.
//w.Close()
//
//// Now that you have a form, you can submit it to your handler.
//req, err := http.NewRequest("POST", BackendAddressWithHTTP+"/warehouse/create", &b)
//if err != nil {
// return
//}
//// Don't forget to set the content type, this will contain the boundary.
//req.Header.Set("Content-Type", w.FormDataContentType())
//
//client := &http.Client{}
//
//// Submit the request
//res, err := client.Do(req)
//if err != nil {
// return
//}
//
//// Check the response
//if res.StatusCode != http.StatusOK {
// err = fmt.Errorf("bad status: %s", res.Status)
//}
//
//body, err := ioutil.ReadAll(res.Body)
//if err != nil {
// return
//}
//
//err = json.Unmarshal(body, &resp)
//if err != nil {
// return
//}
//
//fmt.Println(resp)
//
//return
url := BackendAddressWithHTTP + "/warehouse/create"
req, err := http.NewRequest("POST", url, file)
//req.Header.Set("X-Custom-Header", "myvalue")
req.Header.Set("Content-Type", "multipart/form-data")
method := "POST"
payload := &bytes.Buffer{}
writer := multipart.NewWriter(payload)
_ = writer.WriteField("id", uuid)
part2, errFile2 := writer.CreateFormFile("File", "test")
_, errFile2 = io.Copy(part2, File)
if errFile2 != nil {
fmt.Println(errFile2)
return
}
err = writer.Close()
if err != nil {
fmt.Println(err)
return
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
req, err := http.NewRequest(method, url, payload)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return
}
var result WarehouseResult
err = json.Unmarshal(body, &result)
req.Header.Set("Content-Type", writer.FormDataContentType())
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
return &result
err = json.Unmarshal(body, &resp)
if err != nil {
return
}
return
}
// 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, uuid string) (*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")
}
// adds file to warehouse
warehouseResult := AddFileWarehouse(buf)
warehouseResult, err := AddFileWarehouse(buf, uuid)
if err != nil {
fmt.Println(err.Error())
return nil, nil, err
}
// current using default port for Peernet api which is 8080
// First add file to warehouse
@@ -225,9 +347,37 @@ func AddFileToBlockchain(hash []byte, filename string) *BlockchainResponse {
return nil
}
fmt.Println(result)
return &result
}
// ---------------------------------------------------------------------------------------------
// ----------------------------------- Get status upload file ---------------------------------
func GetStatusUploadFile(uuid string) (uploadStatus *webapi.UploadStatus) {
url := BackendAddressWithHTTP + "/create/track/uploadID?id=" + uuid
resp, err := http.Get(url)
if err != nil {
log.Fatalln(err)
}
//We Read the response body on the line below.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
err = json.Unmarshal(body, uploadStatus)
if err != nil {
return nil
}
fmt.Println(uploadStatus.Progress.Percentage)
return
}
// -----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------
@@ -251,6 +401,8 @@ func main() {
r = gin.Default()
}
r.Use(CORSMiddleware())
r.LoadHTMLGlob("templates/*.html")
r.Static("/templates", "./templates")
@@ -262,8 +414,8 @@ func main() {
// ---------------------------------------- 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)
r.GET("/", lm.Middleware(), func(c *gin.Context) {
c.HTML(http.StatusOK, "upload.html", gin.H{"backendUrl": *BackEndApiAddress})
})
// POST /uploadFile Uploads file to peernet from Webgateway
@@ -271,6 +423,8 @@ func main() {
file, header, err := c.Request.FormFile("file")
defer file.Close()
uuid := c.Request.FormValue("uuid")
if err != nil {
c.HTML(http.StatusBadRequest, "upload.html", gin.H{
"error": err,
@@ -278,25 +432,34 @@ func main() {
return
}
publicKey, warehouseResult, err := UploadFile(backend, &file, header)
publicKey, warehouseResult, err := UploadFile(backend, &file, header, uuid)
if err != nil {
c.HTML(http.StatusBadRequest, "upload.html", gin.H{
"error": err,
"backendUrl": *BackEndApiAddress,
"error": err,
})
return
//fmt.Println(err)
}
c.HTML(http.StatusOK, "upload.html", gin.H{
"hash": hex.EncodeToString(warehouseResult.Hash),
"filename": header.Filename,
"size": header.Size,
"link": "http://164.90.177.167:8889/" + hex.EncodeToString(publicKey.SerializeCompressed()) + "/" + hex.EncodeToString(warehouseResult.Hash) + "/?filename=" + header.Filename,
"address": *WebpageAddress,
c.JSON(http.StatusOK, gin.H{
"hash": hex.EncodeToString(warehouseResult.Hash),
"filename": header.Filename,
"size": header.Size,
"link": "http://164.90.177.167:8889/" + hex.EncodeToString(publicKey.SerializeCompressed()) + "/" + hex.EncodeToString(warehouseResult.Hash) + "/?filename=" + header.Filename,
"address": *WebpageAddress,
"backendUrl": *BackEndApiAddress,
})
})
r.GET("/uploadStatus", lm.Middleware(), func(c *gin.Context) {
uuid := c.Query("uuid")
c.JSON(http.StatusOK, GetStatusUploadFile(uuid))
})
// 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>
@@ -308,7 +471,7 @@ func main() {
fmt.Println(err)
}
publicKey, warehouseResult, err := UploadFile(backend, &file, header)
publicKey, warehouseResult, err := UploadFile(backend, &file, header, "")
if err != nil {
fmt.Println(err)
}
@@ -365,3 +528,21 @@ func EscapeNATWebGateway() (ExposePortP2PRC string, err error) {
return
}
// CORSMiddleware Use Cors middleware
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Credentials", "true")
c.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Header("Access-Control-Allow-Methods", "POST,HEAD,PATCH, OPTIONS, GET, PUT")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
}
}

View File

@@ -14,6 +14,19 @@
</head>
<style>
#myProgress {
width: 100%;
background-color: #ddd;
}
#myBar {
width: 1%;
height: 30px;
background-color: #04AA6D;
}
</style>
<body>
<section class="ftco-section">
<div class="container">
@@ -25,16 +38,20 @@
<h2 class="Peernetblue">Upload file to peernet</h2>
<br>
<br>
<form class="form-group" method="POST" action="/upload" 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" required>
</div>
<input class="btn btn-white btn-outline-white" type="submit" value="Submit">
<input class="btn btn-white btn-outline-white" type="button" value="Submit" onclick="uploader()">
{{ if .error }}
<h3 style="color:red"> Error: {{ .error }} </h3>
{{end}}
</form>
<!-- </form>-->
<!-- <div id="myProgress">-->
<!-- <div id="myBar"></div>-->
<!-- </div>-->
<br>
<!-- <div class="progress">-->
<!-- <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 3%"></div>-->
@@ -63,15 +80,11 @@
<form action="#" class="signin-form">
<div class="form-group mb-3">
<label class="label" for="name">File Name:</label>
{{ if .filename }}
<p> {{ .filename }} </p>
{{end}}
<p id="fileName"> {{ .filename }} </p>
</div>
<div class="form-group mb-3">
<label class="label" for="name">File Size:</label>
{{ if .size }}
<p> {{ .size }} bytes</p>
{{end}}
<p id="fileSize"> {{ .size }} bytes</p>
</div>
<!-- <div class="form-group mb-3">-->
<!-- <label class="label" for="name">File Hash:</label>-->
@@ -82,9 +95,7 @@
<div class="form-group mb-3">
<label class="label" for="name">Sharable Link:</label>
<br>
{{ if .link }}
<a href="{{ .link }}" style="color:#1d91ac" target="_blank">{{ .filename }} link</a>
{{end}}
<a href="{{ .link }}" style="color:#1d91ac" target="_blank" id="fileLink"></a>
</div>
<!-- <div class="form-group mb-3">
<label class="label" for="password">Password</label>
@@ -124,15 +135,64 @@
// The second call will start the upload based
// on the ID presented
//
// function uploader() {
// var formData = new FormData();
// formData.append("name", "Smith");
// formData.append("data", fileInputElement.files[0]);
// var request = new XMLHttpRequest();
//
// request.open("POST", "https://site[DOT]net/upload");
// request.send(formData);
// }
var backendUrl = {{ .backendUrl }}
function uploader() {
var formData = new FormData();
var uuid = generateUUID()
formData.append("id", uuid);
formData.append("file", document.getElementById("formFileLg").files[0]);
var request = new XMLHttpRequest();
request.open("POST", "/upload");
request.send(formData);
//
// setTimeout(function(){
// console.log(UploadTracker(uuid));
// }, 100);
request.onload = () => {
if ( request.readyState == 4 && request.status == 200) {
let data = request.response;
console.log(data);
data = JSON.parse(data)
document.getElementById("fileName").innerText = data["filename"]
document.getElementById("fileSize").innerText = data["size"] + " bytes"
document.getElementById("fileLink").innerText = data["filename"] + " link"
document.getElementById("fileLink").href = data["link"]
} else {
console.log(`Error: ${ request.status}`);
}
};
}
function UploadTracker(uuid) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", "/uploadStatus?uuid=" + uuid, false ); // false for synchronous request
xmlHttp.send( null );
return xmlHttp.responseText;
}
// source: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid
function generateUUID() { // Public Domain/MIT
var d = new Date().getTime();//Timestamp
var d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now()*1000)) || 0;//Time in microseconds since page-load or 0 if unsupported
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16;//random number between 0 and 16
if(d > 0){//Use timestamp until depleted
r = (d + r)%16 | 0;
d = Math.floor(d/16);
} else {//Use microseconds since page-load if supported
r = (d2 + r)%16 | 0;
d2 = Math.floor(d2/16);
}
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
</script>