oauth2: allow users to register broken OAuth2 implementations

Fixes golang/oauth2#111.

Change-Id: Iaea8adb038bcff91b4b468b1a3bdaa5c03d7e8e7
Reviewed-on: https://go-review.googlesource.com/16976
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/internal/token.go b/internal/token.go
index 3e913c2..39caf6c 100644
--- a/internal/token.go
+++ b/internal/token.go
@@ -115,6 +115,10 @@
 	"https://www.strava.com/oauth/",
 }
 
+func RegisterBrokenAuthHeaderProvider(tokenURL string) {
+	brokenAuthHeaderProviders = append(brokenAuthHeaderProviders, tokenURL)
+}
+
 // providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL
 // implements the OAuth2 spec correctly
 // See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
diff --git a/internal/token_test.go b/internal/token_test.go
index 626e933..d8d1e98 100644
--- a/internal/token_test.go
+++ b/internal/token_test.go
@@ -10,6 +10,14 @@
 	"testing"
 )
 
+func TestRegisterBrokenAuthHeaderProvider(t *testing.T) {
+	RegisterBrokenAuthHeaderProvider("https://aaa.com/")
+	tokenURL := "https://aaa.com/token"
+	if providerAuthHeaderWorks(tokenURL) {
+		t.Errorf("URL: %s is a broken provider", tokenURL)
+	}
+}
+
 func Test_providerAuthHeaderWorks(t *testing.T) {
 	for _, p := range brokenAuthHeaderProviders {
 		if providerAuthHeaderWorks(p) {
diff --git a/oauth2.go b/oauth2.go
index 97997f8..a682896 100644
--- a/oauth2.go
+++ b/oauth2.go
@@ -23,6 +23,18 @@
 // your own context.Context (see https://golang.org/x/net/context).
 var NoContext = context.TODO()
 
+// RegisterBrokenAuthHeaderProvider registers an OAuth2 server
+// identified by the tokenURL prefix as an OAuth2 implementation
+// which doesn't support the HTTP Basic authentication
+// scheme to authenticate with the authorization server.
+// Once a server is registered, credentials (client_id and client_secret)
+// will be passed as query parameters rather than being present
+// in the Authorization header.
+// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
+func RegisterBrokenAuthHeaderProvider(tokenURL string) {
+	internal.RegisterBrokenAuthHeaderProvider(tokenURL)
+}
+
 // Config describes a typical 3-legged OAuth2 flow, with both the
 // client application information and the server's endpoint URLs.
 type Config struct {