mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
ipn/ipnlocal: q-encode (RFC 2047) Tailscale serve header values
Updates #11603 RELNOTE=Tailscale serve headers are now RFC 2047 Q-encoded Change-Id: I1314b65ecf5d39a5a601676346ec2c334fdef042 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
262fa8a01e
commit
b9611461e5
@ -12,6 +12,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"mime"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
@ -25,6 +26,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
"unicode/utf8"
|
||||||
|
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
@ -717,12 +719,27 @@ func (b *LocalBackend) addTailscaleIdentityHeaders(r *httputil.ProxyRequest) {
|
|||||||
// Only currently set for nodes with user identities.
|
// Only currently set for nodes with user identities.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.Out.Header.Set("Tailscale-User-Login", user.LoginName)
|
r.Out.Header.Set("Tailscale-User-Login", encTailscaleHeaderValue(user.LoginName))
|
||||||
r.Out.Header.Set("Tailscale-User-Name", user.DisplayName)
|
r.Out.Header.Set("Tailscale-User-Name", encTailscaleHeaderValue(user.DisplayName))
|
||||||
r.Out.Header.Set("Tailscale-User-Profile-Pic", user.ProfilePicURL)
|
r.Out.Header.Set("Tailscale-User-Profile-Pic", user.ProfilePicURL)
|
||||||
r.Out.Header.Set("Tailscale-Headers-Info", "https://tailscale.com/s/serve-headers")
|
r.Out.Header.Set("Tailscale-Headers-Info", "https://tailscale.com/s/serve-headers")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// encTailscaleHeaderValue cleans or encodes as necessary v, to be suitable in
|
||||||
|
// an HTTP header value. See
|
||||||
|
// https://github.com/tailscale/tailscale/issues/11603.
|
||||||
|
//
|
||||||
|
// If v is not a valid UTF-8 string, it returns an empty string.
|
||||||
|
// If v is a valid ASCII string, it returns v unmodified.
|
||||||
|
// If v is a valid UTF-8 string with non-ASCII characters, it returns a
|
||||||
|
// RFC 2047 Q-encoded string.
|
||||||
|
func encTailscaleHeaderValue(v string) string {
|
||||||
|
if !utf8.ValidString(v) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return mime.QEncoding.Encode("utf-8", v)
|
||||||
|
}
|
||||||
|
|
||||||
// serveWebHandler is an http.HandlerFunc that maps incoming requests to the
|
// serveWebHandler is an http.HandlerFunc that maps incoming requests to the
|
||||||
// correct *http.
|
// correct *http.
|
||||||
func (b *LocalBackend) serveWebHandler(w http.ResponseWriter, r *http.Request) {
|
func (b *LocalBackend) serveWebHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -823,3 +823,21 @@ func Test_isGRPCContentType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncTailscaleHeaderValue(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
in string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"", ""},
|
||||||
|
{"Alice Smith", "Alice Smith"},
|
||||||
|
{"Bad\xffUTF-8", ""},
|
||||||
|
{"Krūmiņa", "=?utf-8?q?Kr=C5=ABmi=C5=86a?="},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
got := encTailscaleHeaderValue(tt.in)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("encTailscaleHeaderValue(%q) = %q, want %q", tt.in, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user