changeset 352:23d4a9104b0c

Support deflate compression in WFS proxy, too.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 07 Aug 2018 13:09:34 +0200
parents b89138a25f9e
children a80e589c5ade
files controllers/externalwfs.go
diffstat 1 files changed, 60 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/controllers/externalwfs.go	Tue Aug 07 12:37:39 2018 +0200
+++ b/controllers/externalwfs.go	Tue Aug 07 13:09:34 2018 +0200
@@ -1,9 +1,11 @@
 package controllers
 
 import (
+	"compress/flate"
 	"compress/gzip"
 	"encoding/xml"
 	"io"
+	"io/ioutil"
 	"log"
 	"net/http"
 	"net/url"
@@ -95,6 +97,50 @@
 	return resp, err
 }
 
+type nopCloser struct {
+	io.Writer
+}
+
+func (nopCloser) Close() error { return nil }
+
+func encoding(h http.Header) (
+	func(io.Reader) (io.ReadCloser, error),
+	func(io.Writer) (io.WriteCloser, error),
+) {
+	switch enc := h.Get("Content-Encoding"); {
+	case strings.Contains(enc, "gzip"):
+		log.Println("gzip compression")
+		return func(r io.Reader) (io.ReadCloser, error) {
+				return gzip.NewReader(r)
+			},
+			func(w io.Writer) (io.WriteCloser, error) {
+				return gzip.NewWriter(w), nil
+			}
+	case strings.Contains(enc, "deflate"):
+		log.Println("Deflate compression")
+		return func(r io.Reader) (io.ReadCloser, error) {
+				return flate.NewReader(r), nil
+			},
+			func(w io.Writer) (io.WriteCloser, error) {
+				return flate.NewWriter(w, flate.DefaultCompression)
+			}
+	default:
+		log.Println("No content compression")
+		return func(r io.Reader) (io.ReadCloser, error) {
+				if r2, ok := r.(io.ReadCloser); ok {
+					return r2, nil
+				}
+				return ioutil.NopCloser(r), nil
+			},
+			func(w io.Writer) (io.WriteCloser, error) {
+				if w2, ok := w.(io.WriteCloser); ok {
+					return w2, nil
+				}
+				return nopCloser{w}, nil
+			}
+	}
+}
+
 func externalWFSModifyResponse(resp *http.Response) error {
 
 	from := resp.Header.Get("X-Gemma-From")
@@ -104,39 +150,34 @@
 
 	xml := isXML(resp.Header)
 
-	gzipped := strings.Contains(resp.Header.Get("Content-Encoding"), "gzip")
+	reader, writer := encoding(resp.Header)
 
 	if xml {
 		log.Printf("rewrite from %s to %s\n", from, to)
 
 		pr, pw := io.Pipe()
 
-		var r io.ReadCloser
-		var w io.WriteCloser
-		if gzipped {
-			var err error
-			r, err = gzip.NewReader(resp.Body)
-			if err != nil {
-				return err
-			}
-			w = gzip.NewWriter(pw)
-		} else {
-			r = resp.Body
-			w = pw
+		var (
+			r   io.ReadCloser
+			w   io.WriteCloser
+			err error
+		)
+
+		if r, err = reader(resp.Body); err != nil {
+			return err
+		}
+
+		if w, err = writer(pw); err != nil {
+			return err
 		}
 
 		go func(force io.ReadCloser) {
 			defer func() {
+				//r.Close()
 				w.Close()
 				pw.Close()
 				force.Close()
 			}()
-			/*
-				if _, err := io.Copy(pw, r); err != nil {
-					log.Printf("rewrite failed: %v\n", err)
-					return
-				}
-			*/
 			if err := rewrite(w, r, from, to); err != nil {
 				log.Printf("rewrite failed: %v\n", err)
 				return