Skip to content

Instantly share code, notes, and snippets.

@elisalimli
Created April 22, 2023 08:48
Show Gist options
  • Select an option

  • Save elisalimli/45db2e6ca59e1bea1776709e13b10366 to your computer and use it in GitHub Desktop.

Select an option

Save elisalimli/45db2e6ca59e1bea1776709e13b10366 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func uploadProgress(w http.ResponseWriter, r *http.Request) {
mr, err := r.MultipartReader()
if err != nil {
fmt.Fprintln(w, err)
return
}
length := r.ContentLength
progress := float64(0)
lastProgressSent := float64(0)
// Set the response headers for Server-Sent Events
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
// Send an initial progress update to the client
fmt.Fprintf(w, "data: %v\n\n", progress)
for {
var read int64
part, err := mr.NextPart()
if err == io.EOF {
fmt.Printf("\nDone!")
break
}
dst, err := os.OpenFile("a.pdf", os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return
}
for {
buffer := make([]byte, 100000)
cBytes, err := part.Read(buffer)
if err == io.EOF {
fmt.Printf("\nLast buffer read!")
break
}
read += int64(cBytes)
if read > 0 {
newProgress := float64(read) / float64(length) * 100
// Send a progress update to the client if it's divisible by 20
if int(newProgress/5) > int(lastProgressSent/5) {
lastProgressSent = newProgress
fmt.Fprintf(w, "data: %v\n\n", newProgress)
}
dst.Write(buffer[0:cBytes])
} else {
break
}
}
}
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/receive", uploadProgress)
http.ListenAndServe(":8080", mux)
}
@elisalimli
Copy link
Author

A web server for uploading a file and tracking upload progress using SSE(Server-Sent Events).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment