annotate controllers/externalwfs.go @ 344:e98033e3683a

Be more precise with HTTP headers in WFS proxy.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 06 Aug 2018 14:52:04 +0200
parents bd292a554b6e
children ad0e47c1fedf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
1 package controllers
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
2
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
3 import (
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
4 "compress/gzip"
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
5 "encoding/xml"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
6 "fmt"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
7 "io"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
8 "log"
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
9 "net"
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
10 "net/http"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
11 "strings"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
12
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
13 "github.com/gorilla/mux"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
14 "golang.org/x/net/html/charset"
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 "gemma.intevation.de/gemma/config"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
17 )
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
18
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
19 func copyHeader(dst, src http.Header) {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
20 for k, vv := range src {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
21 log.Printf("%s: %v\n", k, vv)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
22 for _, v := range vv {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
23 dst.Add(k, v)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
24 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
25 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
26 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
27
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
28 func cloneHeader(h http.Header) http.Header {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
29 h2 := make(http.Header, len(h))
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
30 for k, vv := range h {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
31 log.Printf("clone: %s: %v\n", k, vv)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
32 vv2 := make([]string, len(vv))
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
33 copy(vv2, vv)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
34 h2[k] = vv2
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
35 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
36 return h2
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
37 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
38
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
39 // Hop-by-hop headers. These are removed when sent to the backend.
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
40 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
41 var hopHeaders = []string{
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
42 "Connection",
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
43 "Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
44 "Keep-Alive",
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
45 "Proxy-Authenticate",
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
46 "Proxy-Authorization",
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
47 "Te", // canonicalized version of "TE"
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
48 "Trailer", // not Trailers per URL above; http://www.rfc-editor.org/errata_search.php?eid=4522
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
49 "Transfer-Encoding",
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
50 "Upgrade",
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
51 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
52
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
53 // removeConnectionHeaders removes hop-by-hop headers listed in the "Connection" header of h.
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
54 // See RFC 2616, section 14.10.
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
55 func removeConnectionHeaders(h http.Header) {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
56 if c := h.Get("Connection"); c != "" {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
57 for _, f := range strings.Split(c, ",") {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
58 if f = strings.TrimSpace(f); f != "" {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
59 h.Del(f)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
60 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
61 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
62 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
63 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
64
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
65 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
66 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
67 t = strings.ToLower(t)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
68 if strings.Contains(t, "text/xml") ||
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
69 strings.Contains(t, "application/xml") {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
70 return true
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
71 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
72 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
73 return false
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
74 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
75
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
76 func externalWFSProxy(rw http.ResponseWriter, req *http.Request) {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
77
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
78 external := config.ExternalWFSs()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
79 if external == nil || len(external) == 0 {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
80 http.NotFound(rw, req)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
81 return
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
82 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
83 wfs := mux.Vars(req)["wfs"]
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
84
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
85 alias, found := external[wfs]
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
86 if !found {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
87 http.NotFound(rw, req)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
88 return
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
89 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
90 data, ok := alias.(map[string]interface{})
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
91 if !ok {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
92 log.Printf("error: badly configured external wfs %s\n", wfs)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
93 http.Error(rw,
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
94 http.StatusText(http.StatusInternalServerError),
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
95 http.StatusInternalServerError)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
96 return
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
97 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
98
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
99 urlS, found := data["url"]
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
100 if !found {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
101 log.Printf("error: missinf url fore xternal wfs %s\n", wfs)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
102 http.Error(rw,
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
103 http.StatusText(http.StatusInternalServerError),
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
104 http.StatusInternalServerError)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
105 return
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
106 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
107
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
108 prefix, ok := urlS.(string)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
109 if !ok {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
110 log.Printf("error: badly configured url for external wfs %s\n", wfs)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
111 http.Error(rw,
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
112 http.StatusText(http.StatusInternalServerError),
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
113 http.StatusInternalServerError)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
114 return
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
115 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
116
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
117 log.Printf("%v\n", prefix)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
118 url := prefix + "?" + req.URL.RawQuery
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
119 log.Printf("%v\n", url)
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
120
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
121 remoteReq, err := http.NewRequest(req.Method, url, req.Body)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
122 if err != nil {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
123 http.Error(rw, fmt.Sprintf("error: %v", err), http.StatusBadRequest)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
124 return
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
125 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
126
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
127 remoteReq.Header = cloneHeader(req.Header)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
128 removeConnectionHeaders(remoteReq.Header)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
129
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
130 // Remove hop-by-hop headers to the backend. Especially
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
131 // important is "Connection" because we want a persistent
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
132 // connection, regardless of what the client sent to us.
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
133 for _, h := range hopHeaders {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
134 if remoteReq.Header.Get(h) != "" {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
135 remoteReq.Header.Del(h)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
136 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
137 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
138
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
139 if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
140 // If we aren't the first proxy retain prior
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
141 // X-Forwarded-For information as a comma+space
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
142 // separated list and fold multiple headers into one.
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
143 if prior, ok := remoteReq.Header["X-Forwarded-For"]; ok {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
144 clientIP = strings.Join(prior, ", ") + ", " + clientIP
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
145 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
146 remoteReq.Header.Set("X-Forwarded-For", clientIP)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
147 log.Printf("X-Forwarded-For: %s\n", clientIP)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
148 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
149
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
150 log.Printf("req: %v\n", remoteReq)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
151
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
152 resp, err := http.DefaultTransport.RoundTrip(remoteReq)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
153 //client := &http.Client{}
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
154 //resp, err := client.Do(remoteReq)
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
155 if err != nil {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
156 http.Error(rw, fmt.Sprintf("error: %v", err), http.StatusBadRequest)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
157 return
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
158 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
159
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
160 log.Printf("%v\n", resp.Header)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
161
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
162 xml := isXML(resp.Header)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
163 log.Printf("is xml: %t\n", xml)
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
164
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
165 gzipped := strings.Contains(resp.Header.Get("Content-Encoding"), "gzip")
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
166 if gzipped {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
167 resp.Header.Del("Content-Encoding")
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
168 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
169
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
170 removeConnectionHeaders(resp.Header)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
171 copyHeader(rw.Header(), resp.Header)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
172
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
173 rw.WriteHeader(resp.StatusCode)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
174
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
175 defer resp.Body.Close()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
176
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
177 if xml {
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
178 to := useHTTPS(req) + "://" + req.Host
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
179 if !strings.HasPrefix(req.URL.Path, "/") {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
180 to += "/"
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
181 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
182 to += req.URL.Path
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
183 var r io.Reader = resp.Body
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
184 if gzipped {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
185 var err error
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
186 r, err = gzip.NewReader(resp.Body)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
187 if err != nil {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
188 log.Printf("gzip error: %v\n", err)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
189 http.Error(rw, fmt.Sprintf("error: %v", err), http.StatusBadGateway)
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
190 return
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
191 }
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
192 } else {
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
193 r = resp.Body
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
194 }
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
195 log.Printf("rewrite %s to: %s\n", prefix, to)
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
196 err = rewrite(rw, r, prefix, to)
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
197 } else {
344
e98033e3683a Be more precise with HTTP headers in WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents: 335
diff changeset
198 log.Printf("no rewrite")
335
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
199 _, err = io.Copy(rw, resp.Body)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
200 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
201
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
202 if err != nil {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
203 log.Printf("copy error: %v\n", err)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
204 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
205 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
206
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
207 func rewrite(w io.Writer, r io.Reader, from, to string) error {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
208
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
209 decoder := xml.NewDecoder(r)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
210 decoder.CharsetReader = charset.NewReaderLabel
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
211
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
212 encoder := xml.NewEncoder(w)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
213
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
214 replace := func(s string) string {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
215 return strings.Replace(s, from, to, -1)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
216 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
217
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
218 var ns nsdef
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
219
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
220 tokens:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
221 for {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
222 tok, err := decoder.Token()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
223 switch {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
224 case tok == nil && err == io.EOF:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
225 break tokens
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
226 case err != nil:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
227 return err
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
228 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
229
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
230 switch t := tok.(type) {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
231 case xml.StartElement:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
232 ns = ns.push()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
233 t = t.Copy()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
234
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
235 attr := make([]xml.Attr, len(t.Attr))
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
236
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
237 //var lns string
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
238 for i, at := range t.Attr {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
239 switch {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
240 case at.Name.Space == "xmlns":
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
241 ns.define(at.Value, at.Name.Local)
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
242 attr[i] = xml.Attr{Name: at.Name, Value: at.Value}
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
243 default:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
244 attr[i] = xml.Attr{Name: at.Name, Value: replace(at.Value)}
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
245 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
246 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
247 if s := ns.lookup(t.Name.Space); s != "" {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
248 t.Name.Space = ""
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
249 t.Name.Local = s + ":" + t.Name.Local
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
250 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
251 t.Attr = attr
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
252 tok = t
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
253
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
254 case xml.CharData:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
255 tok = xml.CharData(replace(string(t)))
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
256
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
257 case xml.EndElement:
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
258 //log.Printf("lookup %s -> %s\n", t.Name.Space, ns.lookup(t.Name.Space))
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
259 if s := ns.lookup(t.Name.Space); s != "" {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
260 t.Name.Space = ""
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
261 t.Name.Local = s + ":" + t.Name.Local
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
262 tok = t
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
263 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
264 ns = ns.pop()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
265 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
266 if err := encoder.EncodeToken(tok); err != nil {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
267 return err
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
268 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
269 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
270
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
271 return encoder.Flush()
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
272 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
273
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
274 type nsdef []map[string]string
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
275
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
276 func (n nsdef) lookup(ns string) string {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
277 for i := len(n) - 1; i >= 0; i-- {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
278 if s := n[i][ns]; s != "" {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
279 return s
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
280 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
281 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
282 return ""
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
283 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
284
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
285 func (n nsdef) push() nsdef {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
286 return append(n, make(map[string]string))
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
287 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
288
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
289 func (n nsdef) pop() nsdef {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
290 if l := len(n); l > 0 {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
291 n[l-1] = nil
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
292 n = n[:l-1]
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
293 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
294 return n
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
295 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
296
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
297 func (n nsdef) define(ns, s string) {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
298 if n != nil {
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
299 n[len(n)-1][ns] = s
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
300 }
bd292a554b6e Made gemma a WFS proxy.
Sascha L. Teichmann <sascha.teichmann@intevation.de>
parents:
diff changeset
301 }