func (r ImageRebalancer) retrieveReplica(n StashableNode, satisfied bool) int { s := resize.MakeSizeSpec("full") ri := &ImageSpecifier{r.hash, s, r.extension[1:]} img_info, err := n.RetrieveImageInfo(ri) if err == nil && img_info != nil && img_info.Local { // node should have it. node has it. cool. return 1 } else { // that node should have a copy, but doesn't so stash it if !satisfied { if n.Stash(r.path, "") { r.sl.Info(fmt.Sprintf("replicated %s\n", r.path)) return 1 } else { // couldn't stash to that node. not writeable perhaps. // not really our problem to deal with, but we do want // to make sure that another node gets a copy // so we don't increment found_replicas } } } return 0 }
func NewImageSpecifier(s string) *ImageSpecifier { parts := strings.Split(s, "/") ahash, _ := HashFromString(parts[0], "") size := parts[1] rs := resize.MakeSizeSpec(size) filename := parts[2] fparts := strings.Split(filename, ".") extension := "." + fparts[1] return &ImageSpecifier{Hash: ahash, Size: rs, Extension: extension} }
func Test_Urls(t *testing.T) { n := NodeData{ Nickname: "test node", UUID: "test-uuid", BaseUrl: "localhost:8080", Location: "test", Writeable: true, } hash, err := HashFromString("fb682e05b9be61797601e60165825c0b089f755e", "") if err != nil { t.Error("bad hash") } s := resize.MakeSizeSpec("full") ri := &ImageSpecifier{hash, s, "jpg"} testOneUrl(n, ri, t, "http://localhost:8080/retrieve/fb682e05b9be61797601e60165825c0b089f755e/full/jpg/", "http://localhost:8080/retrieve_info/fb682e05b9be61797601e60165825c0b089f755e/full/jpg/", "http://localhost:8080/stash/", "http://localhost:8080/announce/", ) n.BaseUrl = "localhost:8080/" testOneUrl(n, ri, t, "http://localhost:8080/retrieve/fb682e05b9be61797601e60165825c0b089f755e/full/jpg/", "http://localhost:8080/retrieve_info/fb682e05b9be61797601e60165825c0b089f755e/full/jpg/", "http://localhost:8080/stash/", "http://localhost:8080/announce/", ) n.BaseUrl = "http://localhost:8081/" testOneUrl(n, ri, t, "http://localhost:8081/retrieve/fb682e05b9be61797601e60165825c0b089f755e/full/jpg/", "http://localhost:8081/retrieve_info/fb682e05b9be61797601e60165825c0b089f755e/full/jpg/", "http://localhost:8081/stash/", "http://localhost:8081/announce/", ) n.BaseUrl = "http://localhost:8081" testOneUrl(n, ri, t, "http://localhost:8081/retrieve/fb682e05b9be61797601e60165825c0b089f755e/full/jpg/", "http://localhost:8081/retrieve_info/fb682e05b9be61797601e60165825c0b089f755e/full/jpg/", "http://localhost:8081/stash/", "http://localhost:8081/announce/", ) }
func checkImageOnNode(n NodeData, hash *Hash, extension string, path string, c *Cluster, sl Logger) (bool, bool, error) { s := resize.MakeSizeSpec("full") ri := &ImageSpecifier{hash, s, extension} img, err := n.RetrieveImage(ri) if err != nil { // doesn't have it sl.Info(fmt.Sprintf("node %s does not have a copy of the desired image\n", n.Nickname)) return true, true, nil } else { if !doublecheck_replica(img, hash) { // the copy from that node isn't right either return true, true, nil } return replaceImageWithCorrected(path, img, sl) } }
func convertArgs(size, path, convertBin string) []string { // need to convert our size spec to what convert expects // we can ignore 'full' since that will never trigger // a resize_worker request s := resize.MakeSizeSpec(size) var maxDim int if s.Width() > s.Height() { maxDim = s.Width() } else { maxDim = s.Height() } var args []string if s.IsSquare() { args = []string{ convertBin, "-resize", s.ToImageMagickSpec(), "-auto-orient", "-gravity", "center", "-extent", fmt.Sprintf("%dx%d", maxDim, maxDim), path, resizedPath(path, size), } } else { // BUG(thraxil): this auto orients properly // but doesn't switch width/height in that case // so 90 or 270 degree rotations come out the wrong // size args = []string{ convertBin, "-auto-orient", "-resize", s.ToImageMagickSpec(), path, resizedPath(path, size), } } return args }
func parsePathServeImage(w http.ResponseWriter, r *http.Request, ctx Context) (*ImageSpecifier, bool) { parts := strings.Split(r.URL.String(), "/") if (len(parts) < 5) || (parts[1] != "image") { http.Error(w, "bad request", 404) return nil, true } ahash, err := HashFromString(parts[2], "") if err != nil { http.Error(w, "invalid hash", 404) return nil, true } size := parts[3] if size == "" { http.Error(w, "missing size", 404) return nil, true } s := resize.MakeSizeSpec(size) if s.String() != size { // force normalization of size spec http.Redirect(w, r, "/image/"+ahash.String()+"/"+s.String()+"/"+parts[4], 301) return nil, true } filename := parts[4] if filename == "" { filename = "image.jpg" } extension := filepath.Ext(filename) if extension == ".jpeg" { fixed_filename := strings.Replace(parts[4], ".jpeg", ".jpg", 1) http.Redirect(w, r, "/image/"+ahash.String()+"/"+s.String()+"/"+fixed_filename, 301) return nil, true } ri := &ImageSpecifier{ahash, s, extension} return ri, false }