mirror of
https://github.com/PeernetOfficial/WebGatewayUpload.git
synced 2026-07-16 19:47:51 +01:00
added fixes to upload to handle from client side js for adding files with the new upload spec
This commit is contained in:
1
go.mod
1
go.mod
@@ -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
235
main.go
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user