Exemple #1
0
// Build returns the zipped contents of the function.
func (f *Function) Build() (io.Reader, error) {
	f.Log.Debugf("creating build")

	if err := f.hook(BuildHook); err != nil {
		return nil, err
	}

	buf := new(bytes.Buffer)
	zip := archive.NewZipWriter(buf)

	files, err := utils.LoadFiles(f.Path, f.IgnoredPatterns)
	if err != nil {
		return nil, err
	}

	for path, file := range files {
		f.Log.WithField("file", path).Debug("add file to zip")
		if err := zip.AddFile(path, file); err != nil {
			return nil, err
		}

		if err := file.Close(); err != nil {
			return nil, err
		}
	}

	if err := zip.Close(); err != nil {
		return nil, err
	}

	return buf, nil
}
Exemple #2
0
func main() {
	a := archive.NewZipWriter(os.Stdout)
	f, _ := os.Open("ping.txt")
	a.AddFile(f.Name(), f)
	f, _ = os.Open("pong.txt")
	a.AddFile(f.Name(), f)
	a.Close()
}
Exemple #3
0
// Build returns the zipped contents of the function.
func (f *Function) Build() (io.Reader, error) {
	f.Log.Debugf("creating build")

	if err := f.RunHook("build"); err != nil {
		return nil, err
	}

	buf := new(bytes.Buffer)
	zip := archive.NewZipWriter(buf)

	if r, ok := f.runtime.(runtime.CompiledRuntime); ok {
		f.Log.Debugf("compiling")
		if err := r.Build(f.Path); err != nil {
			return nil, fmt.Errorf("compiling: %s", err)
		}
	}

	if f.env != nil {
		f.Log.Debugf("adding .env.json")

		b, err := json.Marshal(f.env)
		if err != nil {
			return nil, err
		}

		zip.AddBytes(".env.json", b)
	}

	if f.runtime.Shimmed() {
		f.Log.Debugf("adding nodejs shim")
		zip.AddBytes("index.js", shim.MustAsset("index.js"))
		zip.AddBytes("byline.js", shim.MustAsset("byline.js"))
	}

	files, err := utils.LoadFiles(f.Path, f.IgnoredPatterns)
	if err != nil {
		return nil, err
	}

	for path, file := range files {
		f.Log.WithField("file", path).Debug("add file")
		if err := zip.AddFile(path, file); err != nil {
			return nil, err
		}

		if err := file.Close(); err != nil {
			return nil, err
		}
	}

	if err := zip.Close(); err != nil {
		return nil, err
	}

	return buf, nil
}
Exemple #4
0
func handle(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/zip")
	w.WriteHeader(200)
	//write .zip archive directly into response
	a := archive.NewZipWriter(w)
	f, _ := os.Open(LARGE_FILE)
	log.Println("sending...")
	t0 := time.Now()
	a.AddFile("file.bin", f)
	a.Close()
	log.Printf("sent in %s", time.Now().Sub(t0))

}
Exemple #5
0
// Zip returns the zipped contents of the function.
func (f *Function) Zip() (io.Reader, error) {
	buf := new(bytes.Buffer)
	zip := archive.NewZipWriter(buf)

	if r, ok := f.runtime.(runtime.CompiledRuntime); ok {
		f.Log.Debugf("compiling")
		if err := r.Build(f.Path); err != nil {
			return nil, fmt.Errorf("compiling: %s", err)
		}
	}

	if f.env != nil {
		f.Log.Debugf("adding .env.json")

		b, err := json.Marshal(f.env)
		if err != nil {
			return nil, err
		}

		zip.AddBytes(".env.json", b)
	}

	if f.runtime.Shimmed() {
		f.Log.Debugf("adding nodejs shim")
		zip.AddBytes("index.js", shim.MustAsset("index.js"))
		zip.AddBytes("byline.js", shim.MustAsset("byline.js"))
	}

	for path, file := range f.files {
		if err := zip.AddFile(path, file); err != nil {
			return nil, err
		}
		defer file.Close()
	}

	if err := zip.Close(); err != nil {
		return nil, err
	}

	return buf, nil
}
//implement the http.Handler interface
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	path := r.URL.RequestURI()
	//forward users to README
	if path == "/" {
		w.Header().Set("Location", "https://github.com/jpillora/webfont-downloader")
		w.WriteHeader(http.StatusFound)
		w.Write([]byte("Redirecting..."))
		return
	}
	//heroku anti-idle endpoint
	if path == "/ping" {
		w.Write([]byte("Pong"))
		return
	}

	//only allow sane requests
	m := pathParser.FindStringSubmatch(path)
	if len(m) == 0 {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte("Invalid request: " + path))
		return
	}

	//set request ID for logging
	h.count++
	requestID := h.count

	//determine settings
	fontType := "woff" //default
	if m[1] != "" {
		fontType = m[2]
	}
	query := m[3]
	name := nonwords.ReplaceAllString(m[4], "")
	ua := ""
	if fontType == "detect" {
		ua = r.Header.Get("User-Agent")
	} else {
		ua = userAgents[fontType]
	}
	if ua == "" {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte("Could not resolve font type"))
		return
	}

	//fetch css file
	cssBytes, err := h.fetch(ua, baseURL+query)
	if err != nil {
		w.WriteHeader(http.StatusBadGateway)
		w.Write([]byte(err.Error()))
		return
	}

	//stream zip file
	w.Header().Set("Content-Disposition", "attachment; filename="+name+".zip;")
	w.WriteHeader(http.StatusOK)
	zip := archive.NewZipWriter(w)
	log.Printf("[#%04d] Creating '%s' archive (%s)...", requestID, name, query)

	fileFetches := sync.WaitGroup{}
	//1 transform css file and insert in zip
	//2 async fetch each font import and insert in zip
	fileID := 1
	cssStr := cssURL.ReplaceAllStringFunc(string(cssBytes), func(url string) string {
		m = cssURL.FindStringSubmatch(url)
		//parse url
		ext := m[2]
		remoteUrl := m[1] + "." + ext
		localPath := fmt.Sprintf("%s-%d.%s", name, fileID, ext)
		fileID++
		fileFetches.Add(1)
		//async fetch
		go func() {
			defer fileFetches.Done()
			out, err := h.fetch(ua, remoteUrl)
			if err != nil {
				return
			}
			log.Printf("[#%04d] Fetched %s, %d bytes", requestID, remoteUrl, len(out))
			zip.AddBytes(localPath, out)
		}()
		//swap remote url with local url
		return "url(./" + localPath + ")"
	})
	//insert transformed css file
	zip.AddBytes(name+".css", []byte(cssStr))

	//wait for all fetches to complete
	fileFetches.Wait()
	//finalize archive
	log.Printf("[#%04d] Finalize '%s.zip'", requestID, name)
	zip.Close()
}