connect-es
connect-es copied to clipboard
Content-Type and other HTTP headers missing with gRPC requests when launching in Cypress E2E Test
Describe the bug
As clearly as you can, please tell us what the bug is.
In the Cypress E2E (end to end) test, the Content-Type
header is missing(not attached) to the request when launched with the Cypress when the client is making the transport as transport = createConnectTransport
However, in the normal browser case, everything works fine. The Content-Type
HTTP header could be observed when it's launched in a regular Chrome browser.
The workaround is to switch the transport to transport = createGrpcWebTransport
, the problem is gone.
To Reproduce
If you encountered an error message, please copy and paste it verbatim. If the bug is specific to an RPC or payload, please provide a reduced example.
The business logic part of the code is simplied to this
/* external dependencies */
import { createPromiseClient } from "@connectrpc/connect";
import { createConnectTransport } from "@connectrpc/connect-web";
import type { PromiseClient } from "@connectrpc/connect";
/* local dependencies */
import { UserService } from "./api/user/v1/service_connect";
import { SigninRequest } from "./api/user/v1/service_pb";
// createApp(App).use(router).mount('#app')
const client: PromiseClient<typeof UserService> = createPromiseClient(
UserService,
createConnectTransport({
baseUrl: "https://service.company.com:443",
})
);
async function signin(email = "", password = "") {
const request = new SigninRequest({email, password})
console.log(request);
if (client) {
try {
const response = await client.signin(request)
console.log(response);
} catch(error: any) {
// gRPC errors will be caught here
console.error('gRPC Error code:', error.code);
console.error('gRPC Error:', error.message);
}
}
}
await signin("[email protected]", "sfsdf");
This is what's expected, when launched from a regular browser
This is what happened within Cypress run. With the same request, but missing a few HTTP headers. Specifically, the Content-Type
header is missing when it's launched in Cypress.
Environment (please complete the following information):
- @connectrpc/connect-web version: (for example,
0.1.0
) 1.3.0 - @connectrpc/connect version: (for example,
0.1.0
) 1.1.2" - Frontend framework and version: (for example,
[email protected]
) [email protected] - Node.js version: (for example,
18.0.0
) v20.10.0 - Browser and version: (for example,
Google Chrome 103.0.5060.134
)
If your problem is specific to bundling, please also provide the following information:
- Bundler and version: (for example,
[email protected]
) - Bundler plugins and version: (for example
[email protected]
) - Bundler configuration file:
Additional context Add any other context about the problem here.
An issue https://github.com/cypress-io/cypress/issues/28849 was reported on the cypress side as well.
Thank you for opening the issue on both repos. The code for headers is pretty much identical between the two transports except for the contents of the headers. I don't see any fetch
overrides in the sample snippet, just to be sure you are not overriding the fetch
function, right?
One odd thing from the cypress screenshot is that it is receiving the headers and is trying to stringify the function properties of the Headers
type, notice the FoEach
, Entries
and others. I am leaning towards this issue being in cypress, lets wait for them to get back.
I switched the client, and still failing,
--- a/packages/zitadel-node/src/index.ts
+++ b/packages/zitadel-node/src/index.ts
@@ -1,8 +1,9 @@
import { NewAuthorizationBearerInterceptor } from "@zitadel/client2";
-import {
- createGrpcWebTransport,
- GrpcTransportOptions,
-} from "@connectrpc/connect-node";
+// import {
+// createGrpcWebTransport,
+// GrpcTransportOptions,
+// } from "@connectrpc/connect-node";
+import { createGrpcWebTransport, GrpcWebTransportOptions } from "@connectrpc/connect-web";
import { importPKCS8, SignJWT } from "jose";
/**
@@ -12,7 +13,7 @@ import { importPKCS8, SignJWT } from "jose";
*/
export function createServerTransport(
token: string,
- opts: GrpcTransportOptions,
+ opts: GrpcWebTransportOptions,
) {
return createGrpcWebTransport({
...opts,
[test] ⨯ ConnectError: [unknown] fetch failed
[test] at async Page (loginname/page.tsx:30:27)
[test] digest: "1552443515"
[test] Cause: TypeError: fetch failed
[test] at node:internal/deps/undici/undici:12345:11
[test] at async next (webpack-internal:///(rsc)/../../node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_@[email protected]_/node_modules/@connectrpc/connect-web/dist/esm/grpc-web-transport.js:93:38)
[test] at async Object.unary (webpack-internal:///(rsc)/../../node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_@[email protected]_/node_modules/@connectrpc/connect-web/dist/esm/grpc-web-transport.js:71:20)
[test] at async Object.eval [as getLoginSettings] (webpack-internal:///(rsc)/../../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@connectrpc/connect/dist/esm/promise-client.js:80:26)
[test] at async Page (webpack-internal:///(rsc)/./src/app/(login)/loginname/page.tsx:30:27) {
[test] cause: HTTPParserError: Response does not match the HTTP/1.1 protocol (Expected HTTP/)
[test] at Parser.execute (node:internal/deps/undici/undici:8593:19)
@yordis I don't think the issue related, the error trace you pasted is using undici which is a node package, it is not related to web.
If you are using the clients on node, you should use the transports from the @connectrpc/connect-node
package
@srikrsna-buf As you could notice, it used to be the connect-node
, and still, the same issue. I am gonna research about cy.request
since that is being used as well https://github.com/zitadel/typescript/blob/dafe5fe25ab8d0ee776ba7138450240e1c3ba4ee/apps/login/cypress/support/mock.ts
I switched the client, and still failing,
--- a/packages/zitadel-node/src/index.ts +++ b/packages/zitadel-node/src/index.ts @@ -1,8 +1,9 @@ import { NewAuthorizationBearerInterceptor } from "@zitadel/client2"; -import { - createGrpcWebTransport, - GrpcTransportOptions, -} from "@connectrpc/connect-node"; +// import { +// createGrpcWebTransport, +// GrpcTransportOptions, +// } from "@connectrpc/connect-node"; +import { createGrpcWebTransport, GrpcWebTransportOptions } from "@connectrpc/connect-web"; import { importPKCS8, SignJWT } from "jose"; /** @@ -12,7 +13,7 @@ import { importPKCS8, SignJWT } from "jose"; */ export function createServerTransport( token: string, - opts: GrpcTransportOptions, + opts: GrpcWebTransportOptions, ) { return createGrpcWebTransport({ ...opts,
[test] ⨯ ConnectError: [unknown] fetch failed [test] at async Page (loginname/page.tsx:30:27) [test] digest: "1552443515" [test] Cause: TypeError: fetch failed [test] at node:internal/deps/undici/undici:12345:11 [test] at async next (webpack-internal:///(rsc)/../../node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_@[email protected]_/node_modules/@connectrpc/connect-web/dist/esm/grpc-web-transport.js:93:38) [test] at async Object.unary (webpack-internal:///(rsc)/../../node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]_@[email protected]_/node_modules/@connectrpc/connect-web/dist/esm/grpc-web-transport.js:71:20) [test] at async Object.eval [as getLoginSettings] (webpack-internal:///(rsc)/../../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@connectrpc/connect/dist/esm/promise-client.js:80:26) [test] at async Page (webpack-internal:///(rsc)/./src/app/(login)/loginname/page.tsx:30:27) { [test] cause: HTTPParserError: Response does not match the HTTP/1.1 protocol (Expected HTTP/) [test] at Parser.execute (node:internal/deps/undici/undici:8593:19)
@yordis, same issue when using playwright. I'm wondering if you managed to solve it and mind sharing please.
Our issue was due to the server not being able to handle the header;