mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 00:07:50 +00:00
Merge pull request #2989 from lavalamp/fix6
Fix proxy bug where it lies about encoding
This commit is contained in:
commit
8eac7303fa
@ -18,7 +18,9 @@ package apiserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
@ -225,17 +227,40 @@ func (t *proxyTransport) scan(n *html.Node, f func(*html.Node)) {
|
|||||||
|
|
||||||
// fixLinks modifies links in an HTML file such that they will be redirected through the proxy if needed.
|
// fixLinks modifies links in an HTML file such that they will be redirected through the proxy if needed.
|
||||||
func (t *proxyTransport) fixLinks(req *http.Request, resp *http.Response) (*http.Response, error) {
|
func (t *proxyTransport) fixLinks(req *http.Request, resp *http.Response) (*http.Response, error) {
|
||||||
defer resp.Body.Close()
|
origBody := resp.Body
|
||||||
|
defer origBody.Close()
|
||||||
|
|
||||||
doc, err := html.Parse(resp.Body)
|
newContent := &bytes.Buffer{}
|
||||||
|
var reader io.Reader = origBody
|
||||||
|
var writer io.Writer = newContent
|
||||||
|
encoding := resp.Header.Get("Content-Encoding")
|
||||||
|
switch encoding {
|
||||||
|
case "gzip":
|
||||||
|
var err error
|
||||||
|
reader, err = gzip.NewReader(reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("errorf making gzip reader: %v", err)
|
||||||
|
}
|
||||||
|
gzw := gzip.NewWriter(writer)
|
||||||
|
defer gzw.Close()
|
||||||
|
writer = gzw
|
||||||
|
// TODO: support flate, other encodings.
|
||||||
|
case "":
|
||||||
|
// This is fine
|
||||||
|
default:
|
||||||
|
// Some encoding we don't understand-- don't try to parse this
|
||||||
|
glog.Errorf("Proxy encountered encoding %v for text/html; can't understand this so not fixing links.", encoding)
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
doc, err := html.Parse(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Parse failed: %v", err)
|
glog.Errorf("Parse failed: %v", err)
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
newContent := &bytes.Buffer{}
|
|
||||||
t.scan(doc, func(n *html.Node) { t.updateURLs(n, req.URL) })
|
t.scan(doc, func(n *html.Node) { t.updateURLs(n, req.URL) })
|
||||||
if err := html.Render(newContent, doc); err != nil {
|
if err := html.Render(writer, doc); err != nil {
|
||||||
glog.Errorf("Failed to render: %v", err)
|
glog.Errorf("Failed to render: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,9 @@ package apiserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@ -132,17 +134,19 @@ func TestProxyTransport_fixLinks(t *testing.T) {
|
|||||||
|
|
||||||
func TestProxy(t *testing.T) {
|
func TestProxy(t *testing.T) {
|
||||||
table := []struct {
|
table := []struct {
|
||||||
method string
|
method string
|
||||||
path string
|
path string
|
||||||
reqBody string
|
reqBody string
|
||||||
respBody string
|
respBody string
|
||||||
reqNamespace string
|
respContentType string
|
||||||
|
reqNamespace string
|
||||||
}{
|
}{
|
||||||
{"GET", "/some/dir", "", "answer", "default"},
|
{"GET", "/some/dir", "", "answer", "text/css", "default"},
|
||||||
{"POST", "/some/other/dir", "question", "answer", "default"},
|
{"GET", "/some/dir", "", "<html><head></head><body>answer</body></html>", "text/html", "default"},
|
||||||
{"PUT", "/some/dir/id", "different question", "answer", "default"},
|
{"POST", "/some/other/dir", "question", "answer", "text/css", "default"},
|
||||||
{"DELETE", "/some/dir/id", "", "ok", "default"},
|
{"PUT", "/some/dir/id", "different question", "answer", "text/css", "default"},
|
||||||
{"GET", "/some/dir/id", "", "answer", "other"},
|
{"DELETE", "/some/dir/id", "", "ok", "text/css", "default"},
|
||||||
|
{"GET", "/some/dir/id", "", "answer", "text/css", "other"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range table {
|
for _, item := range table {
|
||||||
@ -157,7 +161,17 @@ func TestProxy(t *testing.T) {
|
|||||||
if e, a := item.path, req.URL.Path; e != a {
|
if e, a := item.path, req.URL.Path; e != a {
|
||||||
t.Errorf("%v - expected %v, got %v", item.method, e, a)
|
t.Errorf("%v - expected %v, got %v", item.method, e, a)
|
||||||
}
|
}
|
||||||
fmt.Fprint(w, item.respBody)
|
w.Header().Set("Content-Type", item.respContentType)
|
||||||
|
var out io.Writer = w
|
||||||
|
if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") {
|
||||||
|
// The proxier can ask for gzip'd data; we need to provide it with that
|
||||||
|
// in order to test our processing of that data.
|
||||||
|
w.Header().Set("Content-Encoding", "gzip")
|
||||||
|
gzw := gzip.NewWriter(w)
|
||||||
|
out = gzw
|
||||||
|
defer gzw.Close()
|
||||||
|
}
|
||||||
|
fmt.Fprint(out, item.respBody)
|
||||||
}))
|
}))
|
||||||
defer proxyServer.Close()
|
defer proxyServer.Close()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user