Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to disable cookie processing altogether by setting cookie… #123

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ application/json, text/*;0.9, */*;q=0.8

where `Cookie` is a [`tough-cookie` Cookie](https://www.npmjs.com/package/tough-cookie#cookie).

`cookieJar` can also be set to undefined, which will cause `fetch-h2` to not process/store cookies.

### Content encodings (compression)

Expand Down
7 changes: 2 additions & 5 deletions lib/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class Context
private _userAgent: string | PerOrigin< string >;
private _overwriteUserAgent: boolean | PerOrigin< boolean >;
private _accept: string | PerOrigin< string >;
private _cookieJar: CookieJar;
private _cookieJar: undefined | CookieJar;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor]: since you need to use the same type in another place, so I would suggest that you make this an alias.

private _decoders:
ReadonlyArray< Decoder > | PerOrigin< ReadonlyArray< Decoder > >;
private _sessionOptions:
Expand Down Expand Up @@ -122,10 +122,7 @@ export class Context
{
opts = opts || { };

this._cookieJar = "cookieJar" in opts
? ( opts.cookieJar || new CookieJar( ) )
: new CookieJar( );

this._cookieJar = "cookieJar" in opts ? opts.cookieJar : new CookieJar( );
this._userAgent = parsePerOrigin( opts.userAgent, "" );
this._overwriteUserAgent =
parsePerOrigin( opts.overwriteUserAgent, false );
Expand Down
4 changes: 2 additions & 2 deletions lib/fetch-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ export async function setupFetch(

const headers = new Headers( request.headers );

const cookies = ( await session.cookieJar.getCookies( url ) )
.map( cookie => cookie.cookieString( ) );
const cookies = session.cookieJar ? ( await session.cookieJar.getCookies( url ) )
.map( cookie => cookie.cookieString( ) ) : [];

const contentDecoders = session.contentDecoders( );

Expand Down
2 changes: 1 addition & 1 deletion lib/fetch-http1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ export async function fetchImpl(

const isRedirected = isRedirectStatus[ "" + statusCode ];

if ( headers[ HTTP1_HEADER_SET_COOKIE ] )
if ( session.cookieJar && headers[ HTTP1_HEADER_SET_COOKIE ] )
{
const setCookies =
arrayify( headers[ HTTP1_HEADER_SET_COOKIE ] );
Expand Down
2 changes: 1 addition & 1 deletion lib/fetch-http2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ async function fetchImpl(

const isRedirected = isRedirectStatus[ status ];

if ( headers[ HTTP2_HEADER_SET_COOKIE ] )
if ( session.cookieJar && headers[ HTTP2_HEADER_SET_COOKIE ] )
{
const setCookies =
arrayify( headers[ HTTP2_HEADER_SET_COOKIE ] );
Expand Down
2 changes: 1 addition & 1 deletion lib/simple-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface SimpleSession
{
protocol: HttpProtocols;

cookieJar: CookieJar;
cookieJar: CookieJar | undefined;

userAgent( ): string;
accept( ): string;
Expand Down
81 changes: 78 additions & 3 deletions test/fetch-h2/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ describe( `context (${version} over ${proto.replace( ":", "" )})`, ( ) =>
{
it( "should be able to specify custom cookie jar", async ( ) =>
{
const { server, port } = await makeServer( );
const { server, port, receivedCookies: serverReceivedCookies } = await makeServer( );

const cookieJar = new CookieJar( );

Expand All @@ -181,11 +181,14 @@ describe( `context (${version} over ${proto.replace( ":", "" )})`, ( ) =>
userAgent: "foobar",
} );

await fetch( `${proto}//localhost:${port}/set-cookie`, {
const response1 = await fetch( `${proto}//localhost:${port}/set-cookie`, {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor]: It's batter to avoid numbers in a variable name. It seems like a code smell. If you realised that you need more then one response, so just describe in the name of these responses what you expect.

json: [ "a=b" , "c=d" ],
method: "POST",
allowForbiddenHeaders: true,
} );

expect(serverReceivedCookies).toHaveLength(0);
expect(response1.headers.get('set-cookie')).not.toBeNull();
const cookies =
await cookieJar.getCookies( `${proto}//localhost:${port}/` );

Expand All @@ -198,6 +201,8 @@ describe( `context (${version} over ${proto.replace( ":", "" )})`, ( ) =>
// Next request should maintain cookies

await fetch( `${proto}//localhost:${port}/echo` );
expect(serverReceivedCookies.length).toBe(1);
expect(serverReceivedCookies).toEqual(["a=b; c=d"]);

const cookies2 =
await cookieJar.getCookies( `${proto}//localhost:${port}/` );
Expand All @@ -207,10 +212,13 @@ describe( `context (${version} over ${proto.replace( ":", "" )})`, ( ) =>
// If we manually clear the cookie jar, subsequent requests
// shouldn't have any cookies

serverReceivedCookies.splice(0);
cookieJar.reset( );

await fetch( `${proto}//localhost:${port}/echo` );

expect(serverReceivedCookies.length).toBe(0);

const cookies3 =
await cookieJar.getCookies( `${proto}//localhost:${port}/` );

Expand All @@ -221,7 +229,74 @@ describe( `context (${version} over ${proto.replace( ":", "" )})`, ( ) =>
await server.shutdown( );
} );

it( "shouldn't be able to read cookie headers be default", async ( ) =>
it( "should be able to specify undefined cookie jar to indicate not to manage cookies", async ( ) =>
{
const { server, port, receivedCookies: serverReceivedCookies } = await makeServer( );

const { disconnectAll, fetch } = context( {
...cycleOpts,
cookieJar: undefined,
overwriteUserAgent: true,
userAgent: "foobar",
} );

await fetch( `${proto}//localhost:${port}/set-cookie`, {
json: [ "a=b" , "c=d" ],
method: "POST",
} );

expect(serverReceivedCookies).toHaveLength(0);

// Next request should not return cookies
await fetch( `${proto}//localhost:${port}/set-cookie`, {
json: [ "x=y" , "y=z" ],
method: "POST",
} );

expect(serverReceivedCookies).toHaveLength(0);

await fetch( `${proto}//localhost:${port}/echo` );

expect(serverReceivedCookies).toHaveLength(0);

disconnectAll( );

await server.shutdown( );
} );

it( "should be able to not specify cookie jar and have its setup by default, cookies working", async ( ) =>
{
const { server, port, receivedCookies: serverReceivedCookies } = await makeServer( );


const { disconnectAll, fetch } = context( {
...cycleOpts,
overwriteUserAgent: true,
userAgent: "foobar",
} );

const response1 = await fetch( `${proto}//localhost:${port}/set-cookie`, {
json: [ "a=b" , "c=d" ],
method: "POST",
allowForbiddenHeaders: true,
} );

expect(serverReceivedCookies).toHaveLength(0);
expect(response1.headers.get('set-cookie')).not.toBeNull();

// Next request should maintain cookies

await fetch( `${proto}//localhost:${port}/echo` );
expect(serverReceivedCookies.length).toBe(1);
expect(serverReceivedCookies).toEqual(["a=b; c=d"]);

disconnectAll( );

await server.shutdown( );
} );


it( "shouldn't be able to read cookie headers by default", async ( ) =>
{
const { server, port } = await makeServer( );

Expand Down
2 changes: 1 addition & 1 deletion test/lib/server-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ export interface ServerOptions
export abstract class Server
{
public port: number | null = null;
public receivedCookies: Array<string> = new Array<string>();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor]: It is not a good idea to use constructors as types.

  • Some constructors, such as Object, Function, or Array, are very broad and do not provide much type safety or information. Using them as types can make the code less clear and more prone to bugs.
  • TypeScript has built-in types for primitive values, such as number, string, boolean, etc. Using constructors like Number, String, or Boolean as types can lead to unexpected behavior and type errors.
Suggested change
public receivedCookies: Array<string> = new Array<string>();
public receivedCookies: string[] = [];

protected _opts: ServerOptions = { };
protected _server: HttpServer | HttpsServer | Http2Server = < any >void 0;


public async listen( port: number | undefined = void 0 ): Promise< number >
{
return new Promise< void >( ( resolve, _reject ) =>
Expand Down
8 changes: 6 additions & 2 deletions test/lib/server-http1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ export class ServerHttp1 extends TypedServer< HttpServer | HttpsServer >
if ( path == null )
throw new Error( "Internal test error" );

if (request.headers.cookie) {
this.receivedCookies.push(request.headers.cookie);
}

const sendHeaders = ( headers: RawHeaders ) =>
{
const { ":status": status = 200, ...rest } = { ...headers };
Expand Down Expand Up @@ -310,11 +314,11 @@ export class ServerHttp1 extends TypedServer< HttpServer | HttpsServer >
}

export async function makeServer( opts: ServerOptions = { } )
: Promise< { server: Server; port: number | null; } >
: Promise< { server: Server; port: number | null; receivedCookies: Array<string> } >
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor]: As i described before use constructors as types is not a good idea.

Suggested change
: Promise< { server: Server; port: number | null; receivedCookies: Array<string> } >
: Promise< { server: Server; port: number | null; receivedCookies: string[] } >

{
opts = opts || { };

const server = new ServerHttp1( opts );
await server.listen( opts.port );
return { server, port: server.port };
return { server, port: server.port, receivedCookies: server.receivedCookies };
}
9 changes: 6 additions & 3 deletions test/lib/server-http2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ export class ServerHttp2 extends TypedServer< Http2Server >
const path = headers[ HTTP2_HEADER_PATH ] as string;
let m;

if (headers.cookie) {
this.receivedCookies.push(headers.cookie);
}

if ( path === "/headers" )
{
stream.respond( {
Expand Down Expand Up @@ -129,7 +133,6 @@ export class ServerHttp2 extends TypedServer< Http2Server >
( < any >responseHeaders[ HTTP2_HEADER_SET_COOKIE ] )
.push( cookie );
} );

stream.respond( responseHeaders );
stream.end( );
}
Expand Down Expand Up @@ -360,11 +363,11 @@ export class ServerHttp2 extends TypedServer< Http2Server >
}

export async function makeServer( opts: ServerOptions = { } )
: Promise< { server: Server; port: number | null; } >
: Promise< { server: Server; port: number | null; receivedCookies: Array<string> } >
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor]: As i described before use constructors as types is not a good idea.

Suggested change
: Promise< { server: Server; port: number | null; receivedCookies: Array<string> } >
: Promise< { server: Server; port: number | null; receivedCookies: string[] } >

{
opts = opts || { };

const server = new ServerHttp2( opts );
await server.listen( opts.port );
return { server, port: server.port };
return { server, port: server.port, receivedCookies: server.receivedCookies };
}