/* MapRaw returns a Raw struct which can be used for drawing SVG maps e.g., raw, err := wm.MapRaw(bbox, width) b := bytes.Buffer b.WriteString(`<?xml version="1.0"?>`) b.WriteString(fmt.Sprintf("<svg viewBox=\"0 0 %d %d\" xmlns=\"http://www.w3.org/2000/svg\">", raw.Width, raw.Height)) b.WriteString(fmt.Sprintf("<rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" style=\"fill: azure\"/>", raw.Width, raw.Height)) b.WriteString(fmt.Sprintf("<path style=\"fill: wheat; stroke-width: 1; stroke-linejoin: round; stroke: lightslategrey\" d=\"%s\"/>", raw.Land)) b.WriteString(fmt.Sprintf("<path style=\"fill: azure; stroke-width: 1; stroke-linejoin: round; stroke: lightslategrey\" d=\"%s\"/>", raw.Lakes)) b.WriteString("</svg>") The other properties can be used to scale and translate for drawing on the map e.g., type point struct { latitude, longitude float64 x, y float64 } // create pts []point with x,y, set to EPSG3857 and latitude longitude EPSG4326 // range of pts ... switch raw.CrossesCentral && p.longitude > -180.0 && p.longitude < 0.0 { case true: p.x = (p.x + map180.Width3857 - raw.LLX) * raw.DX p.y = (p.y - math.Abs(raw.YShift)) * raw.DX case false: p.x = (p.x - math.Abs(raw.XShift)) * raw.DX p.y = (p.y - math.Abs(raw.YShift)) * raw.DX } // draw p on SVG. */ func (w *Map180) MapRaw(boundingBox string, width int) (mr Raw, err error) { var b bbox if b, err = newBbox(boundingBox); err != nil { return } var m map3857 if m, err = b.newMap3857(width); err != nil { return } mr.Height = m.height mr.Width = m.width mr.DX = m.dx mr.CrossesCentral = m.crossesCentral mr.LLX = m.llx mr.YShift = m.yshift mr.XShift = m.xshift // Get the land and lakes layers from the cache. This creates them // if they haven't been cached already. if err = landLayers.Get(nil, m.toKey(), groupcache.StringSink(&mr.Land)); err != nil { return } if err = lakeLayers.Get(nil, m.toKey(), groupcache.StringSink(&mr.Lakes)); err != nil { return } return }
func proxyHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "application/json") url := "http://moapi.com:8080" + r.URL.Path + "?" + r.URL.RawQuery var s string stringcache.Get(nil, url, groupcache.StringSink(&s)) fmt.Fprintf(w, s) }
func (c *groupCacheMgr) GetValue(request *api.ValueRequest) { log.WithField("domain", request.Key).Info("GroupCache:GetValue") var value string err := c.group.Get(request, request.Key, gc.StringSink(&value)) log.WithFields(log.Fields{ "domain": request.Key, "value": value, }).Info("GroupCache:GetValue:Get") // send response to client request.Response <- api.NewValueResponse(value, err) close(request.Response) log.WithField("domain", request.Key).Info("GroupCache:GetValue:Done") }
func main() { // setup group stringGroup = gc.NewGroup(stringGroupName, cacheSize, gc.GetterFunc(func(_ gc.Context, key string, dest gc.Sink) error { fmt.Fprintf(os.Stdout, "Setting cache key: %s\n", key) return dest.SetString("ECHO:" + key) })) // Get Items for j := 0; j < 4; j++ { for i := 0; i < 4; i++ { var s string if err := stringGroup.Get(dummyCtx, "TestCaching-key"+strconv.Itoa(i), gc.StringSink(&s)); err != nil { fmt.Fprintf(os.Stdout, "TestCaching-key value: failed%s\n", err) return } fmt.Fprintf(os.Stdout, "TestCaching-key value:%s\n", s) } fmt.Fprintln(os.Stdout, "---") } fmt.Fprintln(os.Stdout, "Done.") }
func QR(w http.ResponseWriter, req *http.Request) { locals := make(map[string]string) locals["s"] = req.FormValue("s") if len(locals["s"]) > 0 { var value string if err := cg.Get(nil, locals["s"], gc.StringSink(&value)); err != nil { fmt.Printf("err: %v\n", err) } locals["image"] = value } templ.Execute(w, locals) // show groupcache stats fmt.Printf("####### Stats ######") fmt.Printf("Group Stats:\n") fmt.Printf(" Gets: %d\n", cg.Stats.Gets) fmt.Printf(" CacheHits: %d\n", cg.Stats.CacheHits) fmt.Printf(" PeerLoads: %d\n", cg.Stats.PeerLoads) fmt.Printf(" PeerErrors: %d\n", cg.Stats.PeerErrors) fmt.Printf(" Loads: %d\n", cg.Stats.Loads) fmt.Printf(" LoadsDeduped: %d\n", cg.Stats.LoadsDeduped) fmt.Printf(" LocalLoads: %d\n", cg.Stats.LocalLoads) fmt.Printf(" LocalLoadErrs: %d\n", cg.Stats.LocalLoadErrs) fmt.Printf(" ServerRequests: %d\n", cg.Stats.ServerRequests) }
/* Map draws an SVG image to buf for the bbox regions. The returned map uses EPSG3857. Width is the SVG image width in pixels (height is calculated). pts haz X Y and values initialised for later drawing. The SVG in buf is not closed. See ValidBbox for boundingBox options. */ func (w *Map180) Map(boundingBox string, width int, pts Points, insetBbox string, buf *bytes.Buffer) (err error) { // If the bbox is zero type then figure it out from the markers. var b bbox b, err = newBbox(boundingBox) if err != nil { return } m, err := b.newMap3857(width) if err != nil { return } buf.WriteString(`<?xml version="1.0"?>`) buf.WriteString(fmt.Sprintf("<svg viewBox=\"0 0 %d %d\" xmlns=\"http://www.w3.org/2000/svg\">", m.width, m.height)) if b.title != "" { buf.WriteString(`<title>Map of ` + b.title + `.</title>`) } else { buf.WriteString(`<title>Map of ` + boundingBox + `.</title>`) } // Get the land and lakes layers from the cache. This creates them // if they haven't been cached already. var landLakes string err = mapLayers.Get(nil, m.toKey(), groupcache.StringSink(&landLakes)) if err != nil { return } buf.WriteString(landLakes) if insetBbox != "" { var inset bbox inset, err = newBbox(insetBbox) if err != nil { return } var in map3857 in, err = inset.newMap3857(80) if err != nil { return } var insetMap string err = mapLayers.Get(nil, in.toKey(), groupcache.StringSink(&insetMap)) if err != nil { return } // use 2 markers to put a the main map bbox as a rect ibboxul := NewMarker(b.llx, b.ury, ``, ``, ``) err = in.marker3857(&ibboxul) if err != nil { return } ibboxlr := NewMarker(b.urx, b.lly, ``, ``, ``) err = in.marker3857(&ibboxlr) if err != nil { return } // if bbox rect is tiny make it bigger and shift it a little. iw := int(ibboxlr.x - ibboxul.x) if iw < 5 { iw = 5 ibboxul.x = ibboxul.x - 2 } ih := int(ibboxlr.y - ibboxul.y) if ih < 5 { ih = 5 ibboxul.y = ibboxul.y - 2 } buf.WriteString(fmt.Sprintf("<g transform=\"translate(10,10)\"><rect x=\"-3\" y=\"-3\" width=\"%d\" height=\"%d\" rx=\"10\" ry=\"10\" fill=\"white\"/>", in.width+6, in.height+6)) buf.WriteString(insetMap) buf.WriteString(fmt.Sprintf("<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" fill=\"red\" opacity=\"0.5\"/>", int(ibboxul.x), int(ibboxul.y), iw, ih) + `</g>`) } // end of inset for i, _ := range pts { if pts[i].Latitude <= 85.0 && pts[i].Latitude >= -85.0 { if err = m.point3857(&pts[i]); err != nil { return } } } return }
/* SVG draws an SVG image showing a map of markers. The returned map uses EPSG3857. Width is the SVG image width in pixels (height is calculated). If boundingBox is the empty string then the map bounds are calculated from the markers. See ValidBbox for boundingBox options. */ func (w *Map180) SVG(boundingBox string, width int, markers []Marker, insetBbox string) (buf bytes.Buffer, err error) { // If the bbox is zero type then figure it out from the markers. var b bbox if boundingBox == "" { b, err = newBboxFromMarkers(markers) if err != nil { return } } else { b, err = newBbox(boundingBox) if err != nil { return } } m, err := b.newMap3857(width) if err != nil { return } buf.WriteString(`<?xml version="1.0"?>`) buf.WriteString(fmt.Sprintf("<svg height=\"%d\" width=\"%d\" xmlns=\"http://www.w3.org/2000/svg\">", m.height, m.width)) if b.title != "" { buf.WriteString(`<title>Map of ` + b.title + `.</title>`) } else { buf.WriteString(`<title>Map of ` + boundingBox + `.</title>`) } // Get the land and lakes layers from the cache. This creates them // if they haven't been cached already. var landLakes string err = mapLayers.Get(nil, m.toKey(), groupcache.StringSink(&landLakes)) if err != nil { return } buf.WriteString(landLakes) if insetBbox != "" { var inset bbox inset, err = newBbox(insetBbox) if err != nil { return } var in map3857 in, err = inset.newMap3857(80) if err != nil { return } var insetMap string err = mapLayers.Get(nil, in.toKey(), groupcache.StringSink(&insetMap)) if err != nil { return } // use 2 markers to put a the main map bbox as a rect ibboxul := NewMarker(b.llx, b.ury, ``, ``, ``) err = in.marker3857(&ibboxul) if err != nil { return } ibboxlr := NewMarker(b.urx, b.lly, ``, ``, ``) err = in.marker3857(&ibboxlr) if err != nil { return } // if bbox rect is tiny make it bigger and shift it a little. iw := int(ibboxlr.x - ibboxul.x) if iw < 5 { iw = 5 ibboxul.x = ibboxul.x - 2 } ih := int(ibboxlr.y - ibboxul.y) if ih < 5 { ih = 5 ibboxul.y = ibboxul.y - 2 } buf.WriteString(fmt.Sprintf("<g transform=\"translate(10,10)\"><rect x=\"-3\" y=\"-3\" width=\"%d\" height=\"%d\" rx=\"10\" ry=\"10\" fill=\"white\"/>", in.width+6, in.height+6)) buf.WriteString(insetMap) buf.WriteString(fmt.Sprintf("<rect x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" fill=\"red\" opacity=\"0.5\"/>", int(ibboxul.x), int(ibboxul.y), iw, ih) + `</g>`) } // end of inset err = m.drawMarkers(markers, &buf) if err != nil { return } var short bool if m.width < 250 { short = true } labelMarkers(markers, m.width-5, m.height-5, `end`, 12, short, &buf) buf.WriteString("</svg>") return }
// Get is used by GroupCache to load a key not found in the cache func (pc *PodAuthCache) Get(podname string) string { var auth string pc.cacheGroup.Get(nil, podname, groupcache.StringSink(&auth)) return auth }
func TestGRPCPool(t *testing.T) { if *peerChild { beChildForTestGRPCPool() os.Exit(0) } const ( nChild = 5 nGets = 5000 ) var childAddr []string for i := 0; i < nChild; i++ { childAddr = append(childAddr, pickFreeAddr(t)) } var cmds []*exec.Cmd var wg sync.WaitGroup for i := 0; i < nChild; i++ { cmd := exec.Command(os.Args[0], "--test.run=TestGRPCPool", "--test_peer_child", "--test_peer_addrs="+strings.Join(childAddr, ","), "--test_peer_index="+strconv.Itoa(i), ) cmds = append(cmds, cmd) wg.Add(1) if err := cmd.Start(); err != nil { t.Fatal("failed to start child process: ", err) } go awaitAddrReady(t, childAddr[i], &wg) } defer func() { for i := 0; i < nChild; i++ { if cmds[i].Process != nil { cmds[i].Process.Kill() } } }() wg.Wait() // Use a dummy self address so that we don't handle gets in-process. p := NewGRPCPool("should-be-ignored", grpc.NewServer()) p.Set(childAddr...) // Dummy getter function. Gets should go to children only. // The only time this process will handle a get is when the // children can't be contacted for some reason. getter := groupcache.GetterFunc(func(ctx groupcache.Context, key string, dest groupcache.Sink) error { return errors.New("parent getter called; something's wrong") }) g := groupcache.NewGroup("grpcPoolTest", 1<<20, getter) for _, key := range testKeys(nGets) { var value string if err := g.Get(nil, key, groupcache.StringSink(&value)); err != nil { t.Fatal(err) } if suffix := ":" + key; !strings.HasSuffix(value, suffix) { t.Errorf("Get(%q) = %q, want value ending in %q", key, value, suffix) } t.Logf("Get key=%q, value=%q (peer:key)", key, value) } }
func main() { // Parse the flags flag.Parse() // Create a new groupcache pool pool := groupcache.NewHTTPPool(*cachePublic) pool.Set(strings.Split(*cachePeers, ",")...) // Listen and serve the groupcache pool cacheServer := http.Server{ Addr: *cacheBind, Handler: pool, } go func() { log.Printf("Starting up the cache HTTP server on address %s", *cacheBind) err := cacheServer.ListenAndServe() if err != nil { log.Fatal(err) } }() // Create a new groupcache pool cache := groupcache.NewGroup("ritratt", *cacheSize, groupcache.GetterFunc(func(ctx groupcache.Context, url string, dest groupcache.Sink) error { // First try with https schema := "https://" resp, err := http.Head("https://" + url) if err != nil { log.Printf("[https] Error while querying %s: %s", url, err) // https doesn't work, try http schema = "http://" resp, err = http.Head("http://" + url) if err != nil { log.Printf("[http] Error while querying %s: %s", url, err) } } // Content-Type of the result has to start with image/ // We also don't support SVGs, check out this link for more information: // https://www.owasp.org/images/0/03/Mario_Heiderich_OWASP_Sweden_The_image_that_called_me.pdf /*ct := resp.Header.Get("Content-Type") if !strings.HasPrefix(ct, "image/") || strings.Contains(ct, "image/svg+xml") { log.Printf("[head] Invalid Content-Type of %s", url) return ErrInvalidContentType }*/ // Query the proper URL, now including the body resp, err = http.Get(schema + url) defer resp.Body.Close() if err != nil { log.Printf("[get] Error while querying %s: %s", url, err) } else { log.Printf("[get] Loaded %s", url) } // Content-Type check #2 ct := resp.Header.Get("Content-Type") if !strings.HasPrefix(ct, "image/") || strings.Contains(ct, "image/svg+xml") { log.Printf("[get] Invalid Content-Type of %s", url) return ErrInvalidContentType } var body []byte // Read the dlenght cls := resp.Header.Get("Content-Length") if cls != "" { cl, err := strconv.Atoi(cls) if err != nil { log.Print(err) } else { if cl > 25*1024*1024 { return ErrTooBig } else { body, err = ioutil.ReadAll(resp.Body) if err != nil { return err } } } } else { body = []byte{} totalRead := 0 for { chunk := make([]byte, 1024*1024) read, err := resp.Body.Read(chunk) totalRead += read if err == io.EOF { break } if err != nil { return err } body = append(body, chunk[:read]...) if totalRead > 25*1024*1024 { return ErrTooBig } } } // Put the body into cache with the Content-Type dest.SetString(ct + ";" + string(body)) return nil })) log.Printf("Starting up the proxy HTTP server on address %s", *proxyBind) proxyServer := http.Server{ Addr: *proxyBind, Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Index page if len(r.RequestURI) < 3 || r.RequestURI[:3] != "/i/" { w.Write([]byte("lavab/ritratt")) return } // Get the data from groupcache var data string err := cache.Get(nil, r.RequestURI[3:], groupcache.StringSink(&data)) if err != nil { w.Write([]byte(err.Error())) return } // Split the result into two parts parts := strings.SplitN(data, ";", 2) // Set the content type w.Header().Set("Content-Type", parts[0]) // Write the body w.Write([]byte(parts[1])) }), } log.Fatal(proxyServer.ListenAndServe()) }