Пример #1
0
func (this *Source) fromUrl(s string) *Source {
	if s == "" {
		return nil
	}

	var err error
	parts := strings.Split(s, "://")

	switch len(parts) {
	case NOPROTO:
		this.scheme = config.Get().Scheme()
		this.filepath = filepath.Clean(parts[0])
		break

	case URIFULL:
		this.scheme = parts[0]

		if strings.Contains(parts[1], "\x00") || strings.Contains(parts[1], "../") {
			log.Printf("URI containts illegal characters. `%v`\n", parts[1])
			return nil
		}

		this.filepath = filepath.Clean(parts[1])
		break

	default:
		log.Printf("Wrong URL = '%v'\n", s)
		return nil
	}

	this.root, err = config.Get().Root(this.scheme)
	if err != nil {
		log.Println("Unable to proceed without default root for `file` scheme.", err)
		return nil
	}

	if r, found := readers[this.scheme]; found {
		this.reader = r
	}

	if this.Blob() == nil {
		return nil
	}

	this.Imgcfg, this.imgtype, err = image.DecodeConfig(bytes.NewReader(this.Blob()))
	if err != nil {
		log.Printf("Unable to DecodeConfig() for resource from %v. %v\n", this.Link(), err)
		return nil
	}

	return this
}
Пример #2
0
func main() {
	dumpcfg := flag.Bool("dumpcfg", false, "Dump config.")

	flag.Usage = func() {
		fmt.Fprintf(os.Stdout, "Usage: %s [OPTIONS]\n", os.Args[0])
		flag.PrintDefaults()
	}

	flag.Parse()

	if *dumpcfg {
		config.Get().DumpCfg()
		os.Exit(0)
	}

	initCacheGroup()

	log.Printf("Service listen on %v\n", config.Get().Listen())

	http.HandleFunc("/",
		func(w http.ResponseWriter, r *http.Request) {
			var data []byte
			var ctx groupcache.Context

			cacheGroup.Get(ctx, r.URL.String(), groupcache.AllocatingByteSliceSink(&data))

			http.ServeContent(w, r, r.URL.String(), time.Now(), bytes.NewReader(data))
		},
	)

	http.HandleFunc("/nocache",
		func(w http.ResponseWriter, r *http.Request) {
			var result []byte
			result = imgproc.Do(Construct(new(query.Options), r.URL).(*query.Options))
			w.Write(result)
		},
	)

	http.HandleFunc("/stat",
		func(w http.ResponseWriter, r *http.Request) {
			// awesome stat. not implemented yet.
		},
	)

	log.Fatal(http.ListenAndServe(config.Get().Listen(), nil))
}
Пример #3
0
func initCacheGroup() {
	self := config.Get().CacheSelf()

	pool := groupcache.NewHTTPPool(self)
	pool.Set(config.Get().CachePeers()...)

	if self != "" {
		log.Println("Cache listen on:", strings.TrimLeft(self, "http://"))
		go http.ListenAndServe(strings.TrimLeft(self, "http://"), http.HandlerFunc(pool.ServeHTTP))
	}

	cacheGroup = groupcache.NewGroup("imagio-storage", config.Get().CacheSize(), groupcache.GetterFunc(
		func(ctx groupcache.Context, key string, dest groupcache.Sink) error {
			dest.SetBytes(imgproc.Do(
				Construct(new(query.Options), key).(*query.Options),
			))
			return nil
		}),
	)
}
Пример #4
0
func TestSource(t *testing.T) {
	var once sync.Once

	cases := map[string]*expected{
		"http://" + test_server + "/" + file_name: &expected{&PixelDim{1024, 768}, "jpeg", "image/jpeg", false, test_server + "/" + file_name},
		"":                          &expected{Size: nil, UseConfig: false},
		"file://":                   &expected{Size: nil, UseConfig: false}, //file without 'root' option defined
		"localhost://../etc/passwd": &expected{Size: nil, UseConfig: false}, //wrong characters
		"file:// ":                  &expected{Size: nil, UseConfig: true},
		"file://1024x768.jpg":       &expected{&PixelDim{1024, 768}, "jpeg", "image/jpeg", true, "/tmp/1024x768.jpg"},
	}

	for option, want := range cases {
		if want != nil && want.UseConfig {
			once.Do(func() {
				cfg := config.Get()
				cfg.Sources.File.Default = false
				cfg.Sources.File.Root = "/tmp"
			})
		}

		src := Construct(new(Source), option).(*Source)
		if want.Size == nil && src != nil {
			t.Errorf("Expected nil, got %v\n", src)
			continue
		}
		if src != nil {
			if !reflect.DeepEqual(src.Size(), want.Size) {
				t.Errorf("Expected size is %v, got %v\n", want.Size, src.Size())
			}
			if src.Type() != want.ImgType {
				t.Errorf("Expected image type is %v, got %v\n", want.ImgType, src.Type())
			}
			if src.Mime() != want.MimeType {
				t.Errorf("Expected mime type is %v, got %v", src.Mime(), want.MimeType)
			}
			if src.Link() != want.Link {
				t.Errorf("Expected link is %v, got %v\n", want.Link, src.Link())
			}
		}
	}
}
Пример #5
0
func parseQuery(u *url.URL) *Options {
	query := u.Query()
	log.Println("in:", u.String())
	this := &Options{
		CropRoi: Construct(new(Roi), query.Get("crop")).(*Roi),
		Scale:   Construct(new(Scale), query.Get("scale")).(*Scale),
		Base:    Construct(new(Source), query.Get("source")).(*Source),

		Format:  get(query.Get("format"), config.Get().Format()).(string),
		Method:  get(query.Get("method"), config.Get().Method()).(int),
		Alpha:   getFloat(query.Get("blend_alpha"), config.Get().Alpha()),
		Quality: getInt(query.Get("quality"), config.Get().Quality()),

		Foreground: Construct(new(Source), config.Get().BlendWith(query.Get("blend_with"))).(*Source),
		Mask:       Construct(new(Source), config.Get().BlendMask(query.Get("blend_mask"))).(*Source),
		BlendRoi:   Construct(new(Roi), config.Get().BlendRoi(query.Get("blend_roi"))).(*Roi),
	}

	return this
}