Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrennan Conroy <brecon@microsoft.com>2022-05-04 23:49:36 +0300
committerBrennan Conroy <brecon@microsoft.com>2022-05-04 23:49:36 +0300
commit4b79dc9e6ef2670d037f8d3e8964413a58961429 (patch)
tree4616ea2007296095c917bdffae773f332ff7855b
parentbc42cade7ce0b1149ab9bdc30c78094b3007fd67 (diff)
Set Content-Type more accurately in SignalR TS clientbrecon/contentType
-rw-r--r--src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts23
-rw-r--r--src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts18
-rw-r--r--src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts16
-rw-r--r--src/SignalR/clients/ts/signalr/tests/FetchHttpClient.test.ts48
4 files changed, 76 insertions, 29 deletions
diff --git a/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts
index 2b9d6efacb..676aa698d1 100644
--- a/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts
+++ b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts
@@ -1019,29 +1019,6 @@ describe("hubConnection", () => {
}
});
- it("populates the Content-Type header when sending XMLHttpRequest", async () => {
- // Skip test on Node as this header isn't set (it was added for React-Native)
- if (typeof window === "undefined") {
- return;
- }
- const hubConnection = getConnectionBuilder(HttpTransportType.LongPolling, TESTHUB_NOWEBSOCKETS_ENDPOINT_URL)
- .withHubProtocol(new JsonHubProtocol())
- .build();
-
- try {
- await hubConnection.start();
-
- // Check what transport was used by asking the server to tell us.
- expect(await hubConnection.invoke("GetActiveTransportName")).toEqual("LongPolling");
- // Check to see that the Content-Type header is set the expected value
- expect(await hubConnection.invoke("GetContentTypeHeader")).toEqual("text/plain;charset=UTF-8");
-
- await hubConnection.stop();
- } catch (e) {
- fail(e);
- }
- });
-
eachTransport((t) => {
it("sets the user agent header", async () => {
const hubConnection = getConnectionBuilder(t, TESTHUBENDPOINT_URL)
diff --git a/src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts b/src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts
index b7eef31951..9dd3610aa0 100644
--- a/src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts
+++ b/src/SignalR/clients/ts/signalr/src/FetchHttpClient.ts
@@ -7,7 +7,7 @@ import { CookieJar } from "@types/tough-cookie";
import { AbortError, HttpError, TimeoutError } from "./Errors";
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
import { ILogger, LogLevel } from "./ILogger";
-import { Platform, getGlobalThis } from "./Utils";
+import { Platform, getGlobalThis, isArrayBuffer } from "./Utils";
export class FetchHttpClient extends HttpClient {
private readonly _abortControllerType: { prototype: AbortController, new(): AbortController };
@@ -84,14 +84,26 @@ export class FetchHttpClient extends HttpClient {
}, msTimeout);
}
+ if (request.content === "") {
+ request.content = undefined;
+ }
+ if (request.content) {
+ // Explicitly setting the Content-Type header for React Native on Android platform.
+ request.headers = request.headers || {};
+ if (isArrayBuffer(request.content)) {
+ request.headers["Content-Type"] = "application/octet-stream";
+ } else {
+ request.headers["Content-Type"] = "text/plain;charset=UTF-8";
+ }
+ }
+
let response: Response;
try {
response = await this._fetchType(request.url!, {
- body: request.content!,
+ body: request.content,
cache: "no-cache",
credentials: request.withCredentials === true ? "include" : "same-origin",
headers: {
- "Content-Type": "text/plain;charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
...request.headers,
},
diff --git a/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts b/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts
index 8812d1218f..21992813c6 100644
--- a/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts
+++ b/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts
@@ -4,6 +4,7 @@
import { AbortError, HttpError, TimeoutError } from "./Errors";
import { HttpClient, HttpRequest, HttpResponse } from "./HttpClient";
import { ILogger, LogLevel } from "./ILogger";
+import { isArrayBuffer } from "./Utils";
export class XhrHttpClient extends HttpClient {
private readonly _logger: ILogger;
@@ -33,8 +34,17 @@ export class XhrHttpClient extends HttpClient {
xhr.open(request.method!, request.url!, true);
xhr.withCredentials = request.withCredentials === undefined ? true : request.withCredentials;
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- // Explicitly setting the Content-Type header for React Native on Android platform.
- xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
+ if (request.content === "") {
+ request.content = undefined;
+ }
+ if (request.content) {
+ // Explicitly setting the Content-Type header for React Native on Android platform.
+ if (isArrayBuffer(request.content)) {
+ xhr.setRequestHeader("Content-Type", "application/octet-stream");
+ } else {
+ xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
+ }
+ }
const headers = request.headers;
if (headers) {
@@ -81,7 +91,7 @@ export class XhrHttpClient extends HttpClient {
reject(new TimeoutError());
};
- xhr.send(request.content || "");
+ xhr.send(request.content);
});
}
}
diff --git a/src/SignalR/clients/ts/signalr/tests/FetchHttpClient.test.ts b/src/SignalR/clients/ts/signalr/tests/FetchHttpClient.test.ts
index e31c0e1274..5f7432392e 100644
--- a/src/SignalR/clients/ts/signalr/tests/FetchHttpClient.test.ts
+++ b/src/SignalR/clients/ts/signalr/tests/FetchHttpClient.test.ts
@@ -17,4 +17,52 @@ describe("FetchHttpClient", () => {
expect(e).toEqual(new Error("error from test"));
}
});
+
+ it("sets Content-type header for plaintext", async () => {
+ (global.fetch as any) = (_: string, request: RequestInit) => {
+ expect((request.headers as any)!["Content-Type"]).toEqual("text/plain;charset=UTF-8")
+ throw new Error("error from test");
+ };
+ const httpClient = new FetchHttpClient(NullLogger.instance);
+
+ try {
+ await httpClient.post("/", { content: "content" });
+ } catch (e) {
+ expect(e).toEqual(new Error("error from test"));
+ }
+ });
+
+ it("sets Content-Type header for binary", async () => {
+ (global.fetch as any) = (_: string, request: RequestInit) => {
+ expect((request.headers as any)!["Content-Type"]).toEqual("application/octet-stream")
+ throw new Error("error from test");
+ };
+ const httpClient = new FetchHttpClient(NullLogger.instance);
+
+ try {
+ await httpClient.post("/", { content: new ArrayBuffer(1) });
+ } catch (e) {
+ expect(e).toEqual(new Error("error from test"));
+ }
+ });
+
+ it("does not set Content-Type header for empty content", async () => {
+ (global.fetch as any) = (_: string, request: RequestInit) => {
+ expect((request.headers as any)!["Content-Type"]).toBeUndefined()
+ throw new Error("error from test");
+ };
+ const httpClient = new FetchHttpClient(NullLogger.instance);
+
+ try {
+ await httpClient.post("/", { content: "" });
+ } catch (e) {
+ expect(e).toEqual(new Error("error from test"));
+ }
+
+ try {
+ await httpClient.post("/");
+ } catch (e) {
+ expect(e).toEqual(new Error("error from test"));
+ }
+ });
});