Преглед изворни кода

mgmt api: unescape ampersands in gochat URLs

Endpoints /chat/room/public and /chat/room/private unescape ampersands
in their response gochat URLs. This makes it easier to copy/paste gochat
URLs into AIM, which does not recognize unicode ampersands.
Mike пре 1 година
родитељ
комит
d4b86c1c81
2 измењених фајлова са 26 додато и 9 уклоњено
  1. 22 5
      server/http/mgmt_api.go
  2. 4 4
      server/http/mgmt_api_test.go

+ 22 - 5
server/http/mgmt_api.go

@@ -1,6 +1,7 @@
 package http
 
 import (
+	"bytes"
 	"context"
 	"encoding/base64"
 	"encoding/json"
@@ -433,10 +434,7 @@ func getPublicChatHandler(w http.ResponseWriter, _ *http.Request, chatRoomRetrie
 		out[i] = cr
 	}
 
-	if err := json.NewEncoder(w).Encode(out); err != nil {
-		http.Error(w, err.Error(), http.StatusInternalServerError)
-		return
-	}
+	writeUnescapeChatURL(w, out)
 }
 
 // postPublicChatHandler handles the POST /chat/room/public endpoint.
@@ -500,7 +498,26 @@ func getPrivateChatHandler(w http.ResponseWriter, _ *http.Request, chatRoomRetri
 		out[i] = cr
 	}
 
-	if err := json.NewEncoder(w).Encode(out); err != nil {
+	writeUnescapeChatURL(w, out)
+}
+
+// writeUnescapeChatURL writes a JSON-encoded list of chat rooms with unescaped
+// ampersands preceding the exchange query param.
+//
+//	before: aim:gochat?roomname=Office+Hijinks\u0026exchange=5
+//	after:  aim:gochat?roomname=Office+Hijinks&exchange=5
+//
+// This makes it easier to copy the gochat URL into AIM, which does not
+// recognize the ampersand unicode character \u0026.
+func writeUnescapeChatURL(w http.ResponseWriter, out []chatRoom) {
+	buf := &bytes.Buffer{}
+	if err := json.NewEncoder(buf).Encode(out); err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	b := bytes.ReplaceAll(buf.Bytes(), []byte(`\u0026exchange`), []byte(`&exchange`))
+	if _, err := w.Write(b); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}

+ 4 - 4
server/http/mgmt_api_test.go

@@ -1035,7 +1035,7 @@ func TestPublicChatHandler_GET(t *testing.T) {
 	}{
 		{
 			name:       "multiple chat rooms with participants",
-			want:       `[{"name":"chat-room-1-name","create_time":"0001-01-01T00:00:00Z","url":"aim:gochat?roomname=chat-room-1-name\u0026exchange=5","participants":[{"id":"usera","screen_name":"userA"},{"id":"userb","screen_name":"userB"}]},{"name":"chat-room-2-name","create_time":"0001-01-01T00:00:00Z","url":"aim:gochat?roomname=chat-room-2-name\u0026exchange=5","participants":[{"id":"userc","screen_name":"userC"},{"id":"userd","screen_name":"userD"}]}]`,
+			want:       `[{"name":"chat-room-1-name","create_time":"0001-01-01T00:00:00Z","url":"aim:gochat?roomname=chat-room-1-name&exchange=5","participants":[{"id":"usera","screen_name":"userA"},{"id":"userb","screen_name":"userB"}]},{"name":"chat-room-2-name","create_time":"0001-01-01T00:00:00Z","url":"aim:gochat?roomname=chat-room-2-name&exchange=5","participants":[{"id":"userc","screen_name":"userC"},{"id":"userd","screen_name":"userD"}]}]`,
 			statusCode: http.StatusOK,
 			mockParams: mockParams{
 				chatRoomRetrieverParams: chatRoomRetrieverParams{
@@ -1071,7 +1071,7 @@ func TestPublicChatHandler_GET(t *testing.T) {
 		},
 		{
 			name:       "chat room without participants",
-			want:       `[{"name":"chat-room-1-name","create_time":"0001-01-01T00:00:00Z","url":"aim:gochat?roomname=chat-room-1-name\u0026exchange=5","participants":[]}]`,
+			want:       `[{"name":"chat-room-1-name","create_time":"0001-01-01T00:00:00Z","url":"aim:gochat?roomname=chat-room-1-name&exchange=5","participants":[]}]`,
 			statusCode: http.StatusOK,
 			mockParams: mockParams{
 				chatRoomRetrieverParams: chatRoomRetrieverParams{
@@ -1162,7 +1162,7 @@ func TestPrivateChatHandler_GET(t *testing.T) {
 	}{
 		{
 			name:       "multiple chat rooms with participants",
-			want:       `[{"name":"chat-room-1-name","create_time":"0001-01-01T00:00:00Z","creator_id":"chat-room-1-creator","url":"aim:gochat?roomname=chat-room-1-name\u0026exchange=4","participants":[{"id":"usera","screen_name":"userA"},{"id":"userb","screen_name":"userB"}]},{"name":"chat-room-2-name","create_time":"0001-01-01T00:00:00Z","creator_id":"chat-room-2-creator","url":"aim:gochat?roomname=chat-room-2-name\u0026exchange=4","participants":[{"id":"userc","screen_name":"userC"},{"id":"userd","screen_name":"userD"}]}]`,
+			want:       `[{"name":"chat-room-1-name","create_time":"0001-01-01T00:00:00Z","creator_id":"chat-room-1-creator","url":"aim:gochat?roomname=chat-room-1-name&exchange=4","participants":[{"id":"usera","screen_name":"userA"},{"id":"userb","screen_name":"userB"}]},{"name":"chat-room-2-name","create_time":"0001-01-01T00:00:00Z","creator_id":"chat-room-2-creator","url":"aim:gochat?roomname=chat-room-2-name&exchange=4","participants":[{"id":"userc","screen_name":"userC"},{"id":"userd","screen_name":"userD"}]}]`,
 			statusCode: http.StatusOK,
 			mockParams: mockParams{
 				chatRoomRetrieverParams: chatRoomRetrieverParams{
@@ -1198,7 +1198,7 @@ func TestPrivateChatHandler_GET(t *testing.T) {
 		},
 		{
 			name:       "chat room without participants",
-			want:       `[{"name":"chat-room-1-name","create_time":"0001-01-01T00:00:00Z","creator_id":"chat-room-1-creator","url":"aim:gochat?roomname=chat-room-1-name\u0026exchange=4","participants":[]}]`,
+			want:       `[{"name":"chat-room-1-name","create_time":"0001-01-01T00:00:00Z","creator_id":"chat-room-1-creator","url":"aim:gochat?roomname=chat-room-1-name&exchange=4","participants":[]}]`,
 			statusCode: http.StatusOK,
 			mockParams: mockParams{
 				chatRoomRetrieverParams: chatRoomRetrieverParams{