annotate pkg/controllers/proxy.go @ 1017:a244b18cb916

Added GNU Affero General Public License. Adjusted the headers of the Go files to be AGPLv3.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 23 Oct 2018 18:15:14 +0200
parents 82765aa6de53
children aac42dacb503
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1017
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
1 // This is Free Software under GNU Affero General Public License v >= 3.0
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
2 // without warranty, see README.md and license for details.
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
3 //
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
4 // SPDX-License-Identifier: AGPL-3.0-or-later
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
5 // License-Filename: LICENSES/AGPL-3.0.txt
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
6 //
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
7 // Copyright (C) 2018 by via donau
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
8 // – Österreichische Wasserstraßen-Gesellschaft mbH
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
9 // Software engineering by Intevation GmbH
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
10 //
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
11 // Author(s):
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
12 // * Sascha L. Teichmann <sascha.teichmann@intevation.de>
a244b18cb916 Added GNU Affero General Public License.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 847
diff changeset
13
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
14 package controllers
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
15
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
16 import (
352
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
17 "compress/flate"
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
18 "compress/gzip"
408
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
19 "crypto/hmac"
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
20 "crypto/sha256"
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
21 "encoding/base64"
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
22 "encoding/xml"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
23 "io"
352
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
24 "io/ioutil"
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
25 "log"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
26 "net/http"
346
ad0e47c1fedf Use httputil.ReverseProxy for WFS proxying.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 344
diff changeset
27 "net/url"
408
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
28 "regexp"
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
29 "strings"
369
a43495c91856 Show timing of writing in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 365
diff changeset
30 "time"
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
31
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
32 "github.com/gorilla/mux"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
33 "golang.org/x/net/html/charset"
414
c1047fd04a3a Moved project specific Go packages to new pkg folder.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 409
diff changeset
34
c1047fd04a3a Moved project specific Go packages to new pkg folder.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 409
diff changeset
35 "gemma.intevation.de/gemma/pkg/config"
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
36 )
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
37
408
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
38 // proxyBlackList is a set of URLs that should not be rewritten by the proxy.
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
39 var proxyBlackList = map[string]struct{}{
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
40 "http://www.w3.org/2001/XMLSchema-instance": struct{}{},
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
41 "http://www.w3.org/1999/xlink": struct{}{},
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
42 "http://www.w3.org/2001/XMLSchema": struct{}{},
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
43 "http://www.w3.org/XML/1998/namespace": struct{}{},
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
44 "http://www.opengis.net/wfs/2.0": struct{}{},
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
45 "http://www.opengis.net/ows/1.1": struct{}{},
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
46 "http://www.opengis.net/gml/3.2": struct{}{},
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
47 "http://www.opengis.net/fes/2.0": struct{}{},
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
48 "http://schemas.opengis.net/gml": struct{}{},
538
9ccf2c6b7275 WFS/WMS proxy: blacklist another namespace to make OpenLayers work.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 441
diff changeset
49 "http://www.opengis.net/wfs": struct{}{},
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
50 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
51
421
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
52 func proxyDirector(lookup func(string) (string, bool)) func(*http.Request) {
346
ad0e47c1fedf Use httputil.ReverseProxy for WFS proxying.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 344
diff changeset
53
421
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
54 return func(req *http.Request) {
350
1ea90a22bd15 Better replacements for WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 349
diff changeset
55
421
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
56 log.Printf("proxyDirector: %s\n", req.RequestURI)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
57
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
58 abort := func(format string, args ...interface{}) {
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
59 log.Printf(format, args...)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
60 panic(http.ErrAbortHandler)
408
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
61 }
346
ad0e47c1fedf Use httputil.ReverseProxy for WFS proxying.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 344
diff changeset
62
421
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
63 vars := mux.Vars(req)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
64
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
65 var s string
408
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
66
421
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
67 if entry, found := vars["entry"]; found {
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
68 if s, found = lookup(entry); !found {
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
69 abort("Cannot find entry '%s'\n", entry)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
70 }
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
71 } else {
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
72 expectedMAC, err := base64.URLEncoding.DecodeString(vars["hash"])
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
73 if err != nil {
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
74 abort("Cannot base64 decode hash: %v\n", err)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
75 }
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
76 url, err := base64.URLEncoding.DecodeString(vars["url"])
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
77 if err != nil {
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
78 abort("Cannot base64 decode url: %v\n", err)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
79 }
346
ad0e47c1fedf Use httputil.ReverseProxy for WFS proxying.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 344
diff changeset
80
421
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
81 mac := hmac.New(sha256.New, config.ProxyKey())
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
82 mac.Write(url)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
83 messageMAC := mac.Sum(nil)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
84
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
85 s = string(url)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
86
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
87 if !hmac.Equal(messageMAC, expectedMAC) {
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
88 abort("HMAC of URL %s failed.\n", s)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
89 }
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
90 }
346
ad0e47c1fedf Use httputil.ReverseProxy for WFS proxying.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 344
diff changeset
91
421
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
92 nURL := s + "?" + req.URL.RawQuery
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
93 //log.Printf("%v\n", nURL)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
94
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
95 u, err := url.Parse(nURL)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
96 if err != nil {
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
97 abort("Invalid url: %v\n", err)
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
98 }
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
99 req.URL = u
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
100
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
101 req.Host = u.Host
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
102 //req.Header.Del("If-None-Match")
c37457f12b8e Differ between internal and external proxies.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 419
diff changeset
103 //log.Printf("headers: %v\n", req.Header)
346
ad0e47c1fedf Use httputil.ReverseProxy for WFS proxying.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 344
diff changeset
104 }
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
105 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
106
352
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
107 type nopCloser struct {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
108 io.Writer
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
109 }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
110
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
111 func (nopCloser) Close() error { return nil }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
112
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
113 func encoding(h http.Header) (
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
114 func(io.Reader) (io.ReadCloser, error),
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
115 func(io.Writer) (io.WriteCloser, error),
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
116 ) {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
117 switch enc := h.Get("Content-Encoding"); {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
118 case strings.Contains(enc, "gzip"):
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
119 log.Println("gzip compression")
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
120 return func(r io.Reader) (io.ReadCloser, error) {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
121 return gzip.NewReader(r)
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
122 },
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
123 func(w io.Writer) (io.WriteCloser, error) {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
124 return gzip.NewWriter(w), nil
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
125 }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
126 case strings.Contains(enc, "deflate"):
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
127 log.Println("Deflate compression")
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
128 return func(r io.Reader) (io.ReadCloser, error) {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
129 return flate.NewReader(r), nil
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
130 },
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
131 func(w io.Writer) (io.WriteCloser, error) {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
132 return flate.NewWriter(w, flate.DefaultCompression)
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
133 }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
134 default:
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
135 log.Println("No content compression")
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
136 return func(r io.Reader) (io.ReadCloser, error) {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
137 if r2, ok := r.(io.ReadCloser); ok {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
138 return r2, nil
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
139 }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
140 return ioutil.NopCloser(r), nil
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
141 },
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
142 func(w io.Writer) (io.WriteCloser, error) {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
143 if w2, ok := w.(io.WriteCloser); ok {
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
144 return w2, nil
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
145 }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
146 return nopCloser{w}, nil
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
147 }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
148 }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
149 }
23d4a9104b0c Support deflate compression in WFS proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 351
diff changeset
150
419
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
151 func proxyModifyResponse(suffix string) func(*http.Response) error {
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
152
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
153 return func(resp *http.Response) error {
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
154
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
155 if !isXML(resp.Header) {
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
156 return nil
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
157 }
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
158
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
159 pr, pw := io.Pipe()
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
160
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
161 var (
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
162 r io.ReadCloser
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
163 w io.WriteCloser
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
164 err error
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
165 )
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
166
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
167 reader, writer := encoding(resp.Header)
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
168
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
169 if r, err = reader(resp.Body); err != nil {
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
170 return err
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
171 }
346
ad0e47c1fedf Use httputil.ReverseProxy for WFS proxying.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 344
diff changeset
172
419
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
173 if w, err = writer(pw); err != nil {
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
174 return err
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
175 }
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
176
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
177 go func(force io.ReadCloser) {
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
178 start := time.Now()
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
179 defer func() {
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
180 //r.Close()
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
181 w.Close()
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
182 pw.Close()
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
183 force.Close()
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
184 log.Printf("rewrite took %s\n", time.Since(start))
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
185 }()
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
186 if err := rewrite(suffix, w, r); err != nil {
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
187 log.Printf("rewrite failed: %v\n", err)
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
188 return
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
189 }
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
190 log.Println("rewrite successful")
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
191 }(resp.Body)
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
192
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
193 resp.Body = pr
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
194
355
e170075c22ac Cosmetics: Unindent some code in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 354
diff changeset
195 return nil
e170075c22ac Cosmetics: Unindent some code in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 354
diff changeset
196 }
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
197 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
198
365
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
199 var xmlContentTypes = []string{
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
200 "application/xml",
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
201 "text/xml",
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
202 "application/gml+xml",
847
82765aa6de53 Rewrite WMS capabilities documents (content type "application/vnd.ogc.wms_xml") in proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 538
diff changeset
203 "application/vnd.ogc.wms_xml",
365
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
204 }
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
205
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
206 func isXML(h http.Header) bool {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
207 for _, t := range h["Content-Type"] {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
208 t = strings.ToLower(t)
365
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
209 for _, ct := range xmlContentTypes {
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
210 if strings.Contains(t, ct) {
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
211 return true
765e056ab4e8 Recognize more XML content types in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 359
diff changeset
212 }
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
213 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
214 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
215 return false
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
216 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
217
847
82765aa6de53 Rewrite WMS capabilities documents (content type "application/vnd.ogc.wms_xml") in proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 538
diff changeset
218 var replaceRe = regexp.MustCompile(`\b(https?://[^\s\?'"]*)`)
408
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
219
419
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
220 func replace(suffix, s string) string {
408
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
221
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
222 proxyKey := config.ProxyKey()
419
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
223 proxyPrefix := config.ProxyPrefix() + suffix
408
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
224
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
225 return replaceRe.ReplaceAllStringFunc(s, func(s string) string {
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
226 if _, found := proxyBlackList[s]; found {
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
227 return s
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
228 }
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
229 mac := hmac.New(sha256.New, proxyKey)
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
230 b := []byte(s)
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
231 mac.Write(b)
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
232 expectedMAC := mac.Sum(nil)
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
233
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
234 hash := base64.URLEncoding.EncodeToString(expectedMAC)
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
235 enc := base64.URLEncoding.EncodeToString(b)
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
236 return proxyPrefix + hash + "/" + enc
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
237 })
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
238 }
ac23905e64b1 Improve WFS proxy a lot. It now generates signed re-writings.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 372
diff changeset
239
419
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
240 func rewrite(suffix string, w io.Writer, r io.Reader) error {
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
241
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
242 decoder := xml.NewDecoder(r)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
243 decoder.CharsetReader = charset.NewReaderLabel
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
244
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
245 encoder := xml.NewEncoder(w)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
246
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
247 var n nsdef
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
248
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
249 tokens:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
250 for {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
251 tok, err := decoder.Token()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
252 switch {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
253 case tok == nil && err == io.EOF:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
254 break tokens
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
255 case err != nil:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
256 return err
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
257 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
258
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
259 switch t := tok.(type) {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
260 case xml.StartElement:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
261 t = t.Copy()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
262
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
263 isDef := n.isDef(t.Name.Space)
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
264 n = n.push()
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
265
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
266 for i := range t.Attr {
419
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
267 t.Attr[i].Value = replace(suffix, t.Attr[i].Value)
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
268 n.checkDef(&t.Attr[i])
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
269 }
351
b89138a25f9e Fixed namespace compression in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 350
diff changeset
270
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
271 for i := range t.Attr {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
272 n.adjust(&t.Attr[i])
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
273 }
351
b89138a25f9e Fixed namespace compression in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 350
diff changeset
274
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
275 switch {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
276 case isDef:
351
b89138a25f9e Fixed namespace compression in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 350
diff changeset
277 t.Name.Space = ""
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
278 default:
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
279 if s := n.lookup(t.Name.Space); s != "" {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
280 t.Name.Space = ""
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
281 t.Name.Local = s + ":" + t.Name.Local
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
282 }
351
b89138a25f9e Fixed namespace compression in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 350
diff changeset
283 }
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
284 tok = t
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
285
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
286 case xml.CharData:
419
6627c48363a0 First attempt for user injection of proxy for using GeoServer with role based security.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 414
diff changeset
287 tok = xml.CharData(replace(suffix, string(t)))
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
288
847
82765aa6de53 Rewrite WMS capabilities documents (content type "application/vnd.ogc.wms_xml") in proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 538
diff changeset
289 case xml.Directive:
82765aa6de53 Rewrite WMS capabilities documents (content type "application/vnd.ogc.wms_xml") in proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 538
diff changeset
290 tok = xml.Directive(replace(suffix, string(t)))
82765aa6de53 Rewrite WMS capabilities documents (content type "application/vnd.ogc.wms_xml") in proxy, too.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 538
diff changeset
291
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
292 case xml.EndElement:
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
293 s := n.lookup(t.Name.Space)
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
294
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
295 n = n.pop()
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
296
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
297 if n.isDef(t.Name.Space) {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
298 t.Name.Space = ""
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
299 } else if s != "" {
351
b89138a25f9e Fixed namespace compression in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 350
diff changeset
300 t.Name.Space = ""
b89138a25f9e Fixed namespace compression in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 350
diff changeset
301 t.Name.Local = s + ":" + t.Name.Local
b89138a25f9e Fixed namespace compression in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 350
diff changeset
302 }
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
303 tok = t
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
304 }
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
305
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
306 if err := encoder.EncodeToken(tok); err != nil {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
307 return err
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
308 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
309 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
310
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
311 return encoder.Flush()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
312 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
313
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
314 type nsframe struct {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
315 def string
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
316 ns map[string]string
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
317 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
318
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
319 type nsdef []nsframe
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
320
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
321 func (n nsdef) setDef(def string) {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
322 if l := len(n); l > 0 {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
323 n[l-1].def = def
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
324 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
325 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
326
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
327 func (n nsdef) isDef(s string) bool {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
328 for i := len(n) - 1; i >= 0; i-- {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
329 if x := n[i].def; x != "" {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
330 return s == x
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
331 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
332 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
333 return false
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
334 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
335
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
336 func (n nsdef) define(ns, s string) {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
337 if l := len(n); l > 0 {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
338 n[l-1].ns[ns] = s
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
339 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
340 }
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
341
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
342 func (n nsdef) lookup(ns string) string {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
343 for i := len(n) - 1; i >= 0; i-- {
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
344 if s := n[i].ns[ns]; s != "" {
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
345 return s
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
346 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
347 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
348 return ""
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
349 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
350
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
351 func (n nsdef) checkDef(at *xml.Attr) {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
352 if at.Name.Space == "" && at.Name.Local == "xmlns" {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
353 n.setDef(at.Value)
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
354 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
355 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
356
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
357 func (n nsdef) adjust(at *xml.Attr) {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
358 switch {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
359 case at.Name.Space == "xmlns":
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
360 n.define(at.Value, at.Name.Local)
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
361 at.Name.Local = "xmlns:" + at.Name.Local
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
362 at.Name.Space = ""
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
363
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
364 case at.Name.Space != "":
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
365 if n.isDef(at.Name.Space) {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
366 at.Name.Space = ""
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
367 } else if s := n.lookup(at.Name.Space); s != "" {
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
368 at.Name.Local = s + ":" + at.Name.Local
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
369 at.Name.Space = ""
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
370 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
371 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
372 }
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
373
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
374 func (n nsdef) push() nsdef {
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
375 return append(n, nsframe{ns: make(map[string]string)})
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
376 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
377
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
378 func (n nsdef) pop() nsdef {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
379 if l := len(n); l > 0 {
372
15369b41be74 Teach WFS proxy about default namespaces.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 369
diff changeset
380 n[l-1] = nsframe{}
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
381 n = n[:l-1]
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
382 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
383 return n
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
384 }