internal: don't set client_id and client_secret form values if empty

Fixes golang/oauth2#220.

Change-Id: Ic43b10971e102a8571c7bc895c3ad02b80b685ee
Reviewed-on: https://go-review.googlesource.com/38135
Reviewed-by: Chris Broadfoot <cbro@golang.org>
diff --git a/internal/token.go b/internal/token.go
index ba90a34..b840067 100644
--- a/internal/token.go
+++ b/internal/token.go
@@ -155,9 +155,13 @@
 		return nil, err
 	}
 	bustedAuth := !providerAuthHeaderWorks(tokenURL)
-	if bustedAuth && clientSecret != "" {
-		v.Set("client_id", clientID)
-		v.Set("client_secret", clientSecret)
+	if bustedAuth {
+		if clientID != "" {
+			v.Set("client_id", clientID)
+		}
+		if clientSecret != "" {
+			v.Set("client_secret", clientSecret)
+		}
 	}
 	req, err := http.NewRequest("POST", tokenURL, strings.NewReader(v.Encode()))
 	if err != nil {
diff --git a/internal/token_test.go b/internal/token_test.go
index 5ed0b15..c7c7982 100644
--- a/internal/token_test.go
+++ b/internal/token_test.go
@@ -7,7 +7,12 @@
 
 import (
 	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
 	"testing"
+
+	"golang.org/x/net/context"
 )
 
 func TestRegisterBrokenAuthHeaderProvider(t *testing.T) {
@@ -18,6 +23,26 @@
 	}
 }
 
+func TestRetrieveTokenBustedNoSecret(t *testing.T) {
+	const clientID = "client-id"
+
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if got, want := r.FormValue("client_id"), clientID; got != want {
+			t.Errorf("client_id = %q; want %q", got, want)
+		}
+		if got, want := r.FormValue("client_secret"), ""; got != want {
+			t.Errorf("client_secret = %q; want empty", got)
+		}
+	}))
+	defer ts.Close()
+
+	RegisterBrokenAuthHeaderProvider(ts.URL)
+	_, err := RetrieveToken(context.Background(), clientID, "", ts.URL, url.Values{})
+	if err != nil {
+		t.Errorf("RetrieveToken = %v; want no error", err)
+	}
+}
+
 func Test_providerAuthHeaderWorks(t *testing.T) {
 	for _, p := range brokenAuthHeaderProviders {
 		if providerAuthHeaderWorks(p) {