Exemplo n.º 1
0
func BucketDeleteItem(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	bucket, err := NewBucket(chi.URLParams(ctx)["bucket"])
	if err != nil {
		respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
		return
	}

	pUrl := r.URL.Query().Get("url")
	if pUrl != "" {
		pKey := sha1Hash(pUrl) // transform to what is expected..
		chi.URLParams(ctx)["key"] = pKey
	}
	imageKey := chi.URLParams(ctx)["key"]
	if imageKey == "" {
		respond.JSON(w, 422, map[string]interface{}{
			"error": "Unable to determine the key for the delete operation",
		})
		return
	}

	err = bucket.DbDelImage(ctx, imageKey)
	if err != nil {
		respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
		return
	}

	respond.JSON(w, 200, []byte{})
}
Exemplo n.º 2
0
func BucketAddItems(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	bucket, err := NewBucket(chi.URLParams(ctx)["bucket"])
	if err != nil {
		respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
		return
	}

	urls := r.URL.Query()["url[]"]
	urls = append(urls, r.URL.Query()["url"]...)

	if len(urls) == 0 {
		respond.JSON(w, 422, map[string]interface{}{"error": "Url or urls parameter required"})
		return
	}

	images, err := bucket.AddImagesFromUrls(ctx, urls)
	if err != nil {
		// TODO: refactor.. ApiError will cache invalid image errors,
		// but for an array of urls, we shouldn't cache the entire response
		if len(urls) == 1 {
			respond.ApiError(w, 422, err)
		} else {
			respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
		}
		return
	}

	respond.JSON(w, 200, images)
}
Exemplo n.º 3
0
// Set the parent context in the middleware chain to something else. Useful
// in the instance of having a global server context to signal all requests.
func ParentContext(parent context.Context) func(next chi.Handler) chi.Handler {
	return func(next chi.Handler) chi.Handler {
		fn := func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			pctx := context.WithValue(parent, chi.URLParamsCtxKey, chi.URLParams(ctx))
			next.ServeHTTPC(pctx, w, r)
		}
		return chi.HandlerFunc(fn)
	}
}
Exemplo n.º 4
0
func BucketFetchItem(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	bucket, err := NewBucket(chi.URLParams(ctx)["bucket"])
	if err != nil {
		respond.ImageError(w, 422, err)
		return
	}

	fetchUrl := r.URL.Query().Get("url")
	if fetchUrl == "" {
		respond.ImageError(w, 422, ErrInvalidURL)
		return
	}

	u, err := urlx.Parse(fetchUrl)
	if err != nil {
		respond.ImageError(w, 422, ErrInvalidURL)
		return
	}
	fetchUrl = u.String()

	imKey := sha1Hash(fetchUrl) // transform to what is expected..
	chi.URLParams(ctx)["key"] = imKey

	// First check if we have the original.. a bit of extra overhead, but its okay
	_, err = bucket.DbFindImage(ctx, imKey, nil)
	if err != nil && err != ErrImageNotFound {
		respond.ImageError(w, 422, err)
		return
	}

	// Fetch the image on-demand and add to bucket if we dont have it
	if err == ErrImageNotFound {
		// TODO: add image sizing throttler here....

		_, err := bucket.AddImagesFromUrls(ctx, []string{fetchUrl})
		if err != nil {
			lg.Errorf("Fetching failed for %s because %s", fetchUrl, err)
			respond.ImageError(w, 422, err)
			return
		}
	}

	BucketGetItem(ctx, w, r)
}
Exemplo n.º 5
0
//GetParamValueAsID accepts the context and try to parse an id into int64
func GetParamValueAsID(ctx context.Context, param string) (int64, error) {
	value := chi.URLParams(ctx)[param]
	id, err := strconv.ParseInt(value, 10, 64)

	if err != nil {
		return -1, err
	}

	return id, nil
}
Exemplo n.º 6
0
Arquivo: main.go Projeto: raj347/chi
func ArticleCtx(next chi.Handler) chi.Handler {
	return chi.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		articleID := chi.URLParams(ctx)["articleID"]
		article, err := dbGetArticle(articleID)
		if err != nil {
			http.Error(w, http.StatusText(404), 404)
			return
		}
		ctx = context.WithValue(ctx, "article", article)
		next.ServeHTTPC(ctx, w, r)
	})
}
Exemplo n.º 7
0
func initChi() {
	h := chi.NewRouter()
	h.Get("/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		fmt.Fprintf(w, "Hello, World")
	})
	h.Get("/:name", func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
		fmt.Fprintf(w, "Hello, %s", chi.URLParams(ctx)["name"])
	})
	registerHandler("chi", h)
}
Exemplo n.º 8
0
func BucketGetItem(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	// TODO: bucket binding should happen in a middleware... refactor all handlers
	// that use it..
	bucket, err := NewBucket(chi.URLParams(ctx)["bucket"])
	if err != nil {
		lg.Errorf("Failed to create bucket for %s cause: %s", r.URL, err)
		respond.ImageError(w, 422, err)
		return
	}

	sizing, err := imgry.NewSizingFromQuery(r.URL.RawQuery)
	if err != nil {
		lg.Errorf("Failed to create sizing for %s cause: %s", r.URL, err)
		respond.ImageError(w, 422, err)
		return
	}

	im, err := bucket.GetImageSize(ctx, chi.URLParams(ctx)["key"], sizing)
	if err != nil {
		lg.Errorf("Failed to get image for %s cause: %s", r.URL, err)
		respond.ImageError(w, 422, err)
		return
	}

	w.Header().Set("Content-Type", im.MimeType())
	w.Header().Set("X-Meta-Width", fmt.Sprintf("%d", im.Width))
	w.Header().Set("X-Meta-Height", fmt.Sprintf("%d", im.Height))
	w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%d", app.Config.CacheMaxAge))

	// If requested, only return the image details instead of the data
	if r.URL.Query().Get("info") != "" {
		// TODO: eventually, once the ruby stack is updated, we should
		// return an ImageInfo packet here instead..
		respond.JSON(w, http.StatusOK, im)
		return
	}

	respond.Data(w, 200, im.Data)
}
Exemplo n.º 9
0
Arquivo: main.go Projeto: raj347/chi
// A completely separate router for administrator routes
func adminRouter() http.Handler { // or chi.Router {
	r := chi.NewRouter()
	r.Use(AdminOnly)
	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("admin: index"))
	})
	r.Get("/accounts", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("admin: list accounts.."))
	})
	r.Get("/users/:userId", func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(fmt.Sprintf("admin: view user id %v", chi.URLParams(ctx)["userId"])))
	})
	return r
}
Exemplo n.º 10
0
// DEPRECATED
func BucketV0FetchItem(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	chi.URLParams(ctx)["bucket"] = "tmp" // we imply the bucket name..
	BucketFetchItem(ctx, w, r)
}
Exemplo n.º 11
0
// Image upload to an s3 bucket, respond with a direct url to the uploaded
// image. Avoid using respond.ApiError() here to prevent any of the responses
// from being cached.
func BucketImageUpload(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	var url string
	var err error
	var data []byte
	var im *Image

	file, header, err := r.FormFile("file")
	switch err {
	case nil:
		defer file.Close()

		data, err = ioutil.ReadAll(file)
		if err != nil {
			respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
			return
		}
		im = NewImageFromSrcUrl(header.Filename)

	case http.ErrMissingFile:
		base64file := r.FormValue("base64file")
		fileLen := len(base64file)
		if fileLen < 100 {
			respond.JSON(w, 422, map[string]interface{}{"error": "invalid file upload"})
			return
		}
		data, err = base64.StdEncoding.DecodeString(base64file)
		if err != nil {
			respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
			return
		}

		// balance collision chance vs hash time
		if fileLen > 10000 {
			fileLen = 10000
		}
		im = NewImageFromSrcUrl(string(base64file[0:fileLen]))

	default:
		respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
		return
	}

	defer im.Release()

	im.Data = data
	if err = im.LoadImage(); err != nil {
		respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
		return
	}

	s3Bucket := getS3Bucket(app.Config.Chainstore.S3AccessKey,
		app.Config.Chainstore.S3SecretKey,
		app.Config.Chainstore.S3Bucket)

	path := s3Path(chi.URLParams(ctx)["bucket"], im.Data, im.Format)

	url, err = s3Upload(s3Bucket, path, im)
	if err != nil {
		respond.JSON(w, 422, map[string]interface{}{"error": err.Error()})
		return
	}

	imfo := imgry.ImageInfo{
		URL:           url,
		Format:        im.Format,
		Mimetype:      im.MimeType(),
		Width:         im.Width,
		Height:        im.Height,
		AspectRatio:   float64(im.Width) / float64(im.Height),
		ContentLength: len(im.Data),
	}

	respond.JSON(w, 200, imfo)
}
Exemplo n.º 12
0
func CreateJob(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	// Low, high and urgent priorities only (high is default).
	priority := r.URL.Query().Get("priority")
	switch priority {
	case "low", "high", "urgent":
		// NOP.
	case "":
		priority = "high"
	default:
		http.Error(w, "unknown priority \""+priority+"\"", 422)
		return
	}

	// Decode request data.
	var req *api.ScriptsRequest
	err := json.NewDecoder(r.Body).Decode(&req)
	if err != nil {
		http.Error(w, "parse request body: "+err.Error(), 422)
		return
	}
	req.Script = chi.URLParams(ctx)["filename"]

	// Make sure ASYNC callback is valid URL.
	if req.CallbackURL != "" {
		req.CallbackURL, err = urlx.NormalizeString(req.CallbackURL)
		if err != nil {
			http.Error(w, "parse request body: "+err.Error(), 422)
			return
		}
	}

	// Enqueue the request.
	data, err := json.Marshal(req)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	lg.Debugf("Handler:\tEnqueue \"%v\" request", priority)
	job, err := Qmd.Enqueue(string(data), priority)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	// Async.
	if req.CallbackURL != "" {
		resp, _ := Qmd.GetAsyncResponse(req, job.ID)
		w.Write(resp)
		lg.Debugf("Handler:\tResponded with job %s ASYNC result", job.ID)

		go func() {
			//TODO: Retry callback if it failed?
			err := Qmd.PostResponseCallback(req, job.ID)
			if err != nil {
				lg.Errorf("can't post callback to %v", err)
			}
		}()
		return
	}

	// Sync.
	lg.Debugf("Handler:\tWaiting for job %s", job.ID)

	resp, _ := Qmd.GetResponse(job.ID)
	w.Write(resp)

	lg.Debugf("Handler:\tResponded with job %s result", job.ID)

	// 	// Kill the job, if client closes the connection before
	// 	// it receives the data.
	// 	done := make(chan struct{})
	// 	defer close(done)
	// 	connClosed := w.(http.CloseNotifier).CloseNotify()
	// 	go func() {
	// 		select {
	// 		case <-connClosed:
	// 			job.Kill()
	// 		case <-done:
	// 		}
	// 	}()
}
Exemplo n.º 13
0
Arquivo: main.go Projeto: vladdy/chi
func getAccount(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	accountID := chi.URLParams(ctx)["accountID"]
	account := ctx.Value("account").(string)
	w.Write([]byte(fmt.Sprintf("get account id:%s details:%s", accountID, account)))
}