func handler(resp http.ResponseWriter, req *http.Request) { path := req.URL.Path switch { case path == "": path = "/index.html" case strings.HasSuffix(path, "/"): path += "index.html" } status := http.StatusOK s, err := site.New(dir, site.WithCompression(true)) if err != nil { http.Error(resp, err.Error(), http.StatusInternalServerError) return } body, header, err := s.Resource(path) if _, ok := err.(site.NotFoundError); ok { status = http.StatusNotFound if b, h, erre := s.Resource(site.ErrorPage); erre == nil { body = b header = h } else { body = []byte(err.Error()) header = http.Header{"Content-Type": {"text/plain"}} } } else if err != nil { status = http.StatusInternalServerError body = []byte(err.Error()) header = http.Header{"Content-Type": {"text/plain"}} } else if header.Get("Location") != "" { status = 302 } for k, v := range header { resp.Header()[k] = v } resp.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") resp.WriteHeader(status) resp.Write(body) }
func Run() { if len(FlagSet.Args()) != 1 { FlagSet.Usage() } dir := FlagSet.Arg(0) config, err := readConfig(dir) if err != nil { log.Fatal(err) } keys := s3.Keys{ AccessKey: os.Getenv("AWS_ACCESS_KEY_ID"), SecretKey: os.Getenv("AWS_SECRET_ACCESS_KEY"), } if keys.AccessKey == "" || keys.SecretKey == "" { log.Fatal("Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables with AWS keys") } objects, err := fetchObjects(keys, config.Bucket) if err != nil { log.Fatal(err) } s, err := site.New(dir, site.WithCompression(true)) if err != nil { log.Fatal(err) } paths, err := s.Paths() if err != nil { log.Fatal(err) } for _, path := range paths { body, header, err := s.Resource(path) if err != nil { log.Fatal(err) } deployPath := path maxAge := config.MaxAge if o := objects[deployPath[1:]]; o != nil { delete(objects, o.Key) if !*force && o.ETag == fmt.Sprintf(`"%x"`, md5.Sum(body)) { log.Printf("OK %s", deployPath) continue } } log.Printf("UPLOAD %s", deployPath) if *dryRun { continue } if l := header.Get("Location"); l != "" { header.Del("Location") header.Set("X-Amz-Website-Redirect-Location", l) } header.Set("X-Amz-Acl", "public-read") header.Set("Cache-Control", fmt.Sprintf("max-age=%d", maxAge)) if err := put(keys, config.Bucket+deployPath, body, header); err != nil { log.Fatal(err) } } for _, o := range objects { log.Printf("DELETE /%s", o.Key) if *dryRun { continue } if err := del(keys, config.Bucket+"/"+o.Key); err != nil { log.Fatal(err) } } }