view pkg/middleware/json.go @ 3719:916534d9d6f6

client: waterlevel diagram: handle gauges without reference waterlevels
author Markus Kottlaender <markus@intevation.de>
date Thu, 20 Jun 2019 17:03:38 +0200
parents ef59a4255670
children 6f9d00c8cc38
line wrap: on
line source

// This is Free Software under GNU Affero General Public License v >= 3.0
// without warranty, see README.md and license for details.
//
// SPDX-License-Identifier: AGPL-3.0-or-later
// License-Filename: LICENSES/AGPL-3.0.txt
//
// Copyright (C) 2019 by via donau
//   – Österreichische Wasserstraßen-Gesellschaft mbH
// Software engineering by Intevation GmbH
//
// Author(s):
//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>

package middleware

import (
	"context"
	"encoding/json"
	"io"
	"net/http"
)

type jsonInputKeyType int

const jsonInputKey jsonInputKeyType = 0

const DefaultLimit = 2048

func GetJSONInput(req *http.Request) interface{} {
	return req.Context().Value(jsonInputKey)
}

func JSONInput(next http.Handler, input func(*http.Request) interface{}, limit int64) http.Handler {

	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		dst := input(req)
		defer req.Body.Close()
		var r io.Reader
		switch {
		case limit == 0:
			r = io.LimitReader(req.Body, DefaultLimit)
		case limit > 0:
			r = io.LimitReader(req.Body, limit)
		default:
			r = req.Body
		}
		if err := json.NewDecoder(r).Decode(dst); err != nil {
			http.Error(rw, "error: "+err.Error(), http.StatusBadRequest)
			return
		}
		parent := req.Context()
		ctx := context.WithValue(parent, jsonInputKey, input)
		req = req.WithContext(ctx)
		next.ServeHTTP(rw, req)
	})
}