2015-03-30 14 views
5

Zadałem to pytanie before i nie otrzymałem satysfakcjonującej odpowiedzi, więc tym razem starałem się być bardziej szczegółowy.Wdrażanie GitHub Odznaki w Golang

Chciałbym zaimplementować serwer w golangu, który wysyła dynamiczne aktualizacje statusu w postaci svg. (Pomyśl "Zbuduj przekazywanie/niepowodzenie" Plakietki GitHub.) Celem jest to, aby można było umieścić link do adresu serwera w Readme GitHub, a plik Readme powinien automatycznie aktualizować się w zależności od stanu serwera.

Oto kod golang, który wymyśliłem, ale nie działa z agresywnym buforowaniem GitHub. Czy muszę dodać więcej nagłówków Cache-Control? Czy muszę dodać ETag?

Używam następujących elementów do osadzenia obrazu w Readme GitHub.

[![Mine](http://58dcd0b5.ngrok.com/view)]() 

Idealnie, chciałbym zobaczyć Readme GitHub zmienić obraz za każdym razem ładować go - przerzucanie między dwoma obrazami „poprawne”/„źle”. (To jest tylko proof of concept.)

package main 

import (
    "log" 
    "net/http" 
    _ "time" 
) 
var mymap map[string][]byte 

var state bool = false 


func viewHandler(w http.ResponseWriter, r *http.Request) { 
    log.Printf("State %v", state) 
    state = !state 
    w.Header().Set("Content-Type", "image/svg+xml") 
    w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") 
    if state { 
     w.Write(mymap["correct"]) 
    } else { 
     w.Write(mymap["wrong"]) 
    } 
} 

func main() { 
    mymap = make(map[string][]byte) 
    mymap["correct"] = []byte(`<svg xmlns="http://www.w3.org/2000/svg" width="104" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="104" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#4c1" d="M54 0h50v20H54z"/><path fill="url(#b)" d="M0 0h104v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="28" y="15" fill="#010101" fill-opacity=".3">solution</text><text x="28" y="14">solution</text><text x="78" y="15" fill="#010101" fill-opacity=".3">correct</text><text x="78" y="14">correct</text></g></svg>`) 
    mymap["wrong"] = []byte(`<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="99" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#e05d44" d="M54 0h45v20H54z"/><path fill="url(#b)" d="M0 0h99v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="28" y="15" fill="#010101" fill-opacity=".3">solution</text><text x="28" y="14">solution</text><text x="75.5" y="15" fill="#010101" fill-opacity=".3">wrong</text><text x="75.5" y="14">wrong</text></g></svg>`) 

    mux := http.NewServeMux() 
    mux.HandleFunc("/view", viewHandler) 
    http.ListenAndServe(":8085", mux) 
} 
+0

go uruchomić badge.go –

+0

Check out http://shields.io i zobaczyć, jak podają swoje obrazy. – Jamesking56

Odpowiedz

1

Po this commit to shields.io server wprowadziłem następujące zmiany do powyższego kodu i teraz to działa.

w.Header().Set("Date", date) 
w.Header().Set("Expires", date) 

Dla kompletności (w przypadku, gdy ktoś chce to wypróbować), oto pełny kod. (Również na GitHub.)

package main 

import (
    "log" 
    "net/http" 
    "time" 
) 

var mymap map[string][]byte 

var state bool = false 

func viewHandler(w http.ResponseWriter, r *http.Request) { 
    date := time.Now().Format(http.TimeFormat) 
    log.Printf("%v", date) 
    log.Printf("State %v", state) 
    state = !state 
    w.Header().Set("Content-Type", "image/svg+xml") 
    w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") 
    w.Header().Set("Date", date) 
    w.Header().Set("Expires", date) 
    if state { 
     w.Write(mymap["correct"]) 
    } else { 
     w.Write(mymap["wrong"]) 
    } 
} 

func main() { 
    mymap = make(map[string][]byte) 
    mymap["correct"] = []byte(`<svg xmlns="http://www.w3.org/2000/svg" width="104" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="104" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#4c1" d="M54 0h50v20H54z"/><path fill="url(#b)" d="M0 0h104v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="28" y="15" fill="#010101" fill-opacity=".3">solution</text><text x="28" y="14">solution</text><text x="78" y="15" fill="#010101" fill-opacity=".3">correct</text><text x="78" y="14">correct</text></g></svg>`) 
    mymap["wrong"] = []byte(`<svg xmlns="http://www.w3.org/2000/svg" width="99" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="99" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h54v20H0z"/><path fill="#e05d44" d="M54 0h45v20H54z"/><path fill="url(#b)" d="M0 0h99v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="28" y="15" fill="#010101" fill-opacity=".3">solution</text><text x="28" y="14">solution</text><text x="75.5" y="15" fill="#010101" fill-opacity=".3">wrong</text><text x="75.5" y="14">wrong</text></g></svg>`) 

    mux := http.NewServeMux() 
    mux.HandleFunc("/view", viewHandler) 
    log.Println("Server started. Listening on 8085...") 
    http.ListenAndServe(":8085", mux) 
} 
3

Oto co travis służą do swoich obrazów:

Age:0 
Cache-Control:no-cache 
Content-Length:0 
Date:Mon, 30 Mar 2015 07:49:10 GMT 
ETag:"88e168c2d5cdb30ee9af739765e78e4d" 
Expires:Mon, 30 Mar 2015 07:49:10 GMT 
Keep-Alive:timeout=10, max=48 
Last-Modified:Wed, 07 Jan 2015 11:26:53 GMT 
Timing-Allow-Origin:https://github.com 
X-Timer:S1427701750.146025,VS0,VE156 

To może być dobry początek, aby spróbować tych i zobaczyć, co działa.

+3

OP: Oczywiście nie ślepo kopiuj nagłówki takie jak "ETag" z innego źródła.Najlepiej, jeśli czytasz o buforowaniu i jak to jest kontrolowane przez nagłówki, więc nie robisz czegoś głupiego/marnotrawnego, jak zapobieganie buforowaniu czegoś, co tylko rzadko się zmienia lub może zmienić tylko raz w pewnym przedziale. –

4

Oto Github Emisja o tym: https://github.com/github/markup/issues/224

Aktywa muszą zawierać Cache-Control: no-cache i nagłówki wytycznych. Jeśli znaczek nie aktualizuje się, oznacza to, że nie ustawiają one odpowiednio nagłówków.

i

aktywów może również dołączyć OSOBĄ ETag nagłówek lub wygasł. Fastly's docs on Cache-Control Podkreśl, że "brak pamięci podręcznej" oznacza "ponownie sprawdź poprawność przed wyświetleniem tej treści", ale nie określa, co to oznacza z "ponownym sprawdzeniem poprawności". Zgaduję, że jest to ponowne sprawdzanie poprawności, ale nie ma wskazania, że ​​zasób się zmienił, więc nadal obsługuje zasób buforowany o wartości .

ETag będzie największą wygraną, ponieważ zagwarantuje, że pamięć podręczna o numerze zostanie odświeżona po zmianie, ale nadal będzie oszczędzać przepustowość.