view pkg/middleware/modifyquery.go @ 942:912d016275ee

client: add arrow to drawn linesegment * Add styling function that will place an icon png image at the end of each drawn line segment, in the right rotation. Note that this does not look perfectly centered, see comment in the code.
author Bernhard Reiter <bernhard@intevation.de>
date Tue, 09 Oct 2018 18:39:01 +0200
parents 1b08432a0e5d
children a244b18cb916
line wrap: on
line source

package middleware

import (
	"encoding/hex"
	"log"
	"net/http"
	"net/url"
	"strings"

	"gemma.intevation.de/gemma/pkg/auth"
)

// ParseQuery is a modified version of the internal query
// parser of the url.parseQuery of the standard library.
func ParseQuery(
	m url.Values,
	query string,
	keySep, valueSep string,
	unescape func(string) (string, error),
) error {
	if unescape == nil {
		unescape = url.QueryUnescape
	}
	for query != "" {
		key := query
		if i := strings.Index(key, keySep); i >= 0 {
			key, query = key[:i], key[i+1:]

		} else {
			query = ""
		}
		if key == "" {
			continue
		}
		value := ""
		if i := strings.Index(key, valueSep); i >= 0 {
			key, value = key[:i], key[i+1:]
		}
		key, err := unescape(key)
		if err != nil {
			return err
		}
		value, err = unescape(value)
		if err != nil {
			return err
		}
		m[key] = append(m[key], value)
	}
	return nil
}

func ModifyQuery(next http.Handler, modify func(*http.Request, url.Values) error) http.Handler {

	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {

		// GeoServer query parameters contain ';' as sub key separators.
		// If we would use req.URL.Query() this would be split
		// at the wrong level resulting in broken key/value pairs.
		// So we do the splitting ourselves.

		parameters := make(url.Values)

		if err := ParseQuery(parameters, req.URL.RawQuery, "&", "=", nil); err != nil {
			log.Printf("parsing query failed: %v\n", err)
			http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
			return
		}

		if err := modify(req, parameters); err != nil {
			log.Printf("modifying query parameters failed: %v\n", err)
			http.Error(rw, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
		}

		req.URL.RawQuery = parameters.Encode()

		next.ServeHTTP(rw, req)
	})
}

func InjectUser(req *http.Request, parameters url.Values) error {
	// To prevent SQL injections
	parameters.Del("env")

	if session, ok := auth.GetSession(req); ok {
		log.Printf("Injecting user %s\n", session.User)
		parameters.Set("env", "user:"+hex.EncodeToString([]byte(session.User)))
	}
	return nil
}