Skip to content
Snippets Groups Projects
Select Git revision
  • 2dcd065bb05ce40d31b6bfd2d3fb2b1d52e22f88
  • master default protected
  • fix-warnings
  • tvbgone-fixes
  • genofire/ble-follow-py
  • schneider/ble-stability-new-phy-adv
  • schneider/ble-stability
  • msgctl/gfx_rle
  • schneider/ble-stability-new-phy
  • add_menu_vibration
  • plaetzchen/ios-workaround
  • blinkisync-as-preload
  • schneider/max30001-pycardium
  • schneider/max30001-epicaridum
  • schneider/max30001
  • schneider/stream-locks
  • schneider/fundamental-test
  • schneider/ble-buffers
  • schneider/maxim-sdk-update
  • ch3/splashscreen
  • koalo/bhi160-works-but-dirty
  • v1.11
  • v1.10
  • v1.9
  • v1.8
  • v1.7
  • v1.6
  • v1.5
  • v1.4
  • v1.3
  • v1.2
  • v1.1
  • v1.0
  • release-1
  • bootloader-v1
  • v0.0
36 results

gpio.c

Blame
  • Forked from card10 / firmware
    Source project has a limited visibility.
    server_mirror.go 3.13 KiB
    package main
    
    import (
    	"archive/tar"
    	"bytes"
    	"compress/bzip2"
    	"fmt"
    	"io"
    	"log"
    	"net/http"
    	"regexp"
    	"strings"
    	"strconv"
    )
    
    func (s *server) cacheTarball(rel *GLRelease, data io.Reader) error {
    	bz2 := bzip2.NewReader(data)
    	t := tar.NewReader(bz2)
    
    	log.Printf("Extracting %q...", rel.TagName)
    	cacheEntry := make(map[string][]byte)
    	for {
    		hdr, err := t.Next()
    		if err == io.EOF {
    			break
    		}
    		if err != nil {
    			return fmt.Errorf("when reading header: %v", err)
    		}
    		parts := strings.Split(hdr.Name, "/")
    		last := parts[len(parts)-1]
    		log.Printf("%q has %q", rel.TagName, last)
    		buf := bytes.NewBuffer(nil)
    		if _, err := io.Copy(buf, t); err != nil {
    			return fmt.Errorf("file %s: %v", hdr.Name, err)
    		}
    		cacheEntry[last] = buf.Bytes()
    	}
    	s.cacheMu.Lock()
    	s.cache[rel.TagName] = cacheEntry
    	s.cacheMu.Unlock()
    	return nil
    }
    
    func (s *server) serveMirroredFile(w http.ResponseWriter, r *http.Request, rel *GLRelease, artifact string) {
    	ctx := r.Context()
    
    	s.cacheMu.RLock()
    	if s.cache[rel.TagName] != nil && s.cache[rel.TagName][artifact] != nil {
    		b := s.cache[rel.TagName][artifact]
    		s.cacheMu.RUnlock()
    		w.Header().Add("Content-Type", "application/octet-stream")
    		w.Header().Add("Content-Length", strconv.Itoa(len(b)))
    		w.Write(b)
    		return
    	}
    	if s.cache[rel.TagName] != nil {
    		log.Printf("Failed: no %q in %q", artifact, rel.TagName)
    		http.NotFound(w, r)
    		return
    	}
    	s.cacheMu.RUnlock()
    
    	log.Printf("Fetching %q (for %q)...", rel.TagName, artifact)
    
    	if len(rel.Assets.Links) < 0 {
    		log.Printf("Tag %s has %d assets", rel.TagName, len(rel.Assets.Links))
    		http.NotFound(w, r)
    		return
    	}
    	needle := -1
    	for i, link := range rel.Assets.Links {
    		if strings.HasSuffix(link.Name, ".tar.bz2") {
    			needle = i
    			break
    		}
    	}
    	if needle == -1 {
    		log.Printf("Tag %s has no .tar.bz", rel.TagName)
    		http.NotFound(w, r)
    	}
    	link := rel.Assets.Links[needle]
    	req, err := http.NewRequestWithContext(ctx, "GET", link.URL, nil)
    	if err != nil {
    		w.WriteHeader(500)
    		fmt.Fprintf(w, "could not download")
    		return
    	}
    	res, err := http.DefaultTransport.RoundTrip(req)
    	if err != nil {
    		w.WriteHeader(500)
    		fmt.Fprintf(w, "could not download")
    		return
    	}
    	defer res.Body.Close()
    
    	if err := s.cacheTarball(rel, res.Body); err != nil {
    		w.WriteHeader(500)
    		fmt.Fprintf(w, "could not cache")
    		return
    	}
    
    	s.cacheMu.RLock()
    	if s.cache[rel.TagName] != nil && s.cache[rel.TagName][artifact] != nil {
    		b := s.cache[rel.TagName][artifact]
    		s.cacheMu.RUnlock()
    		w.Header().Add("Content-Type", "application/octet-stream")
    		w.Header().Add("Content-Length", strconv.Itoa(len(b)))
    		w.Write(b)
    		return
    	}
    	s.cacheMu.RUnlock()
    	http.NotFound(w, r)
    }
    
    var (
    	reMirrorURL = regexp.MustCompile("^/api/release/([^/]+)/([^/]+.bin)$")
    )
    
    func (s *server) handleReleaseMirror(w http.ResponseWriter, r *http.Request) {
    	ctx := r.Context()
    
    	matches := reMirrorURL.FindStringSubmatch(r.URL.Path)
    	if matches == nil {
    		http.NotFound(w, r)
    		return
    	}
    	tag := matches[1]
    	artifact := matches[2]
    
    	releases, err := s.getReleases(ctx)
    	if err != nil {
    		return
    	}
    
    	for _, rel := range releases {
    		if rel.TagName == tag {
    			s.serveMirroredFile(w, r, &rel, artifact)
    			return
    		}
    	}
    }