// ServeHTTP is called whenever there is a new request. // This is quite similar to JavaEE Servlet interface. func (h *MyHandler) ServeHTTP(ctx *fasthttp.RequestCtx) { // In the future we can use requester can detect request spammers! // requester := ctx.RemoteAddr() // Increase request count count := &(h.requests) atomic.AddUint64(count, 1) if ctx.IsGet() { url := ctx.URI() operations, format, err, invalid := ParseURI(url, h.imageSource, h.watermarker) if err != nil { ctx.NotFound() logging.Debug(err) return } if invalid != nil { ctx.Error(invalid.Error(), 400) return } blob, err := h.operator.GetBlob(operations...) if err != nil { ctx.NotFound() logging.Debug(err) } else { ctx.SetContentType("image/" + format) ctx.Write(blob) logging.Debug("Blob returned") } } else if ctx.IsPost() { // POST is currently unused so we can use this for testing h.RetrieveHello(ctx) logging.Debug("Post request received") } }
// Tests getting images. c.Testfn is treated as GET string (filename?params). // Executes the tests supported by TestCaseAll. func testGetImages(cases []testutils.TestCaseAll) (err error) { s, ln, srverr := startServer() defer stopServer(s, ln, srverr) tolerance := 0.002 // Todo: this threading is copied from common_test.go unify it to single implementation (DRY) sem := make(chan error, len(cases)) for _, c := range cases { go func(tc testutils.TestCaseAll) { logging.Debug(fmt.Sprintf("Testing get: %v, %v, %v, %v, %v", tc.Testfn, tc.Reffn, tc.Resfn, tc.W, tc.H)) blob, err := getBlobFromServer(tc.Testfn) if err != nil { sem <- err return } sem <- testutils.TestAll(tc, blob, tolerance) }(c) } for range cases { var verr = <-sem if verr != nil && err == nil { err = verr } } return }
func main() { cpath := flag.String("c", "config.ini", "Sets the configuration .ini file used.") flag.Parse() // CLI arguments conf := config.ReadConfig(*cpath) mem := flag.Uint64("m", conf.Server.Memory, "Sets the maximum memory to be used for caching images in bytes. Does not account for memory consumption of other things.") imagick.Initialize() defer imagick.Terminate() log.Println("Server starting...") logging.Debug("Debug enabled") server, handler, ln := NewServer(8005, *mem, conf) handler.started = time.Now() err := server.Serve(ln) end := time.Now() // Get number of requests requests := strconv.FormatUint((*handler).requests, 10) // Calculate the elapsed time duration := end.Sub(handler.started) log.Println("Server requests: " + requests) log.Println("Server uptime: " + duration.String()) // Log errors if err != nil { log.Fatal(err) } }
func (i ImageSource) searchRootsInternal(filename string, visitPath, visitURL func(string) error) (err error) { if len(i.roots) == 0 && len(i.webroots) == 0 { logging.Debug("No roots") err = os.ErrNotExist return } // Search requested image from all roots by trial and error for _, root := range i.roots { // TODO: Fix escape vulnerability (sanitize filename from at least ".." etc) err = visitPath(filepath.Join(root, filename)) if err == nil { return } } for _, root := range i.webroots { logging.Debugf("Attempting to load %s", root+filename) err = visitURL(root + filename) if err == nil { return } } return }
func (roots *roots) Add(r string) error { logging.Debug("Adding root: " + r) if roots.HasRoot(r) { return ErrRootAlreadyAdded } *roots = append(*roots, r) return nil }
// Create a new fasthttp server and configure it. // This does not run the server however. func NewServer(port int, maxMemory uint64, conf *config.ConfValues) (*fasthttp.Server, *MyHandler, net.Listener) { logging.Debug("Creating server") imageSource := ops.MakeImageSource() // Add roots // TODO: This must be externalized outside the source code. logging.Debug("Adding roots") if imageSource.AddRoot("/var/www") != nil { log.Fatal("Root not added /var/www") } if imageSource.AddRoot(".") != nil { log.Println("Root not added .") } logging.Debug("Reading server config") //setting default values watermarker, err := ops.MakeWatermarker(conf.Watermark) if err != nil { log.Printf("Error creating watermarker: %v\n", err.Error()) } // Configure handler logging.Debug("Configuring handler") handler := &MyHandler{ requests: 0, imageSource: imageSource, operator: operator.MakeDefault(maxMemory, "/tmp/RICdiskcache", conf.Server.Tokens), watermarker: watermarker, } // Configure server server := &fasthttp.Server{ Handler: handler.ServeHTTP, } logging.Debug("Beginning to listen") ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { log.Fatal("Error creating listener:" + err.Error()) } logging.Debug("Server ready") return server, handler, ln }
func (c Convert) Apply(img images.Image) error { logging.Debug(fmt.Sprintf("Converting image to: %v", c.Format)) return img.Convert(c.Format) }
func (i loadImageOp) Apply(img images.Image) error { logging.Debug("Loading: %v", i.id) return i.is.searchRoots(i.id, img) }
func (r Resize) Apply(img images.Image) error { logging.Debug("Resizing image to: %v, %v", r.Width, r.Height) return img.Resize(r.Width, r.Height) }
func (w watermark) Apply(img images.Image) (err error) { logging.Debug("Adding watermark") return img.Watermark(w.stamp, w.horizontal, w.vertical) }