Skip to content

Instantly share code, notes, and snippets.

@jtolio

jtolio/go.mod Secret

Created April 22, 2020 17:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jtolio/9faad0981ece6d8427aa6903081d281c to your computer and use it in GitHub Desktop.
Save jtolio/9faad0981ece6d8427aa6903081d281c to your computer and use it in GitHub Desktop.
Storj Labs Q2 townhall live coding
module demo
go 1.14
require storj.io/uplink v1.0.3
package main
import (
"context"
"html/template"
"io"
"log"
"net/http"
"storj.io/uplink"
)
const accessGrant = "<your-access-grant-goes-here>"
const bucket = "<your-bucket-goes-here>"
var rootPage = template.Must(template.New("root").Parse(
`<!doctype html>
<html>
<body>
<form method="post" enctype="multipart/form-data" action="/upload/">
<input type="file" name="file" />
<input type="submit" value="upload" />
</form>
<ul>
{{range .}}
<li><a href="/serve/{{.}}">{{.}}</a></li>
{{end}}
</ul>
</body>
</html>
`))
func handleErr(w http.ResponseWriter, err error) {
http.Error(w, err.Error(), 500)
log.Printf("error: %+v", err)
}
func main() {
err := Main(context.Background())
if err != nil {
panic(err)
}
}
type Server struct {
p *uplink.Project
}
func (s *Server) root(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
it := s.p.ListObjects(ctx, bucket, &uplink.ListObjectsOptions{
Recursive: true,
})
var paths []string
for it.Next() {
paths = append(paths, it.Item().Key)
}
if err := it.Err(); err != nil {
handleErr(w, err)
return
}
rootPage.Execute(w, paths)
}
func (s *Server) upload(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
mr, err := r.MultipartReader()
if err != nil {
handleErr(w, err)
return
}
for {
part, err := mr.NextPart()
if err != nil {
if err == io.EOF {
http.Redirect(w, r, "/", 303)
return
}
handleErr(w, err)
return
}
if part.FormName() != "file" {
part.Close()
continue
}
u, err := s.p.UploadObject(ctx, bucket, part.FileName(), nil)
if err != nil {
handleErr(w, err)
return
}
_, err = io.Copy(u, part)
if err != nil {
handleErr(w, err)
return
}
err = u.Commit()
if err != nil {
handleErr(w, err)
return
}
part.Close()
}
}
func (s *Server) serve(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
o, err := s.p.DownloadObject(ctx, bucket, r.URL.Path, nil)
if err != nil {
handleErr(w, err)
return
}
defer o.Close()
io.Copy(w, o)
}
func Main(ctx context.Context) error {
ag, err := uplink.ParseAccess(accessGrant)
if err != nil {
return err
}
p, err := uplink.OpenProject(ctx, ag)
if err != nil {
return err
}
defer p.Close()
server := &Server{p: p}
mux := http.NewServeMux()
mux.Handle("/", http.HandlerFunc(server.root))
mux.Handle("/upload/", http.HandlerFunc(server.upload))
mux.Handle("/serve/", http.StripPrefix("/serve/", http.HandlerFunc(server.serve)))
return http.ListenAndServe(":8080", mux)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment