Skip to content

Commit

Permalink
fix(client): properly handle multi-byte characters in Content-Length (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
stainless-bot authored and RobertCraigie committed Jul 11, 2023
1 parent 7d54366 commit 8dfff26
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/core.ts
Expand Up @@ -122,6 +122,20 @@ export abstract class APIClient {
return this.requestAPIList(Page, { method: 'get', path, ...opts });
}

private calculateContentLength(body: unknown): string | null {
if (typeof body === 'string') {
if (typeof Buffer !== 'undefined') {
return Buffer.byteLength(body, 'utf8').toString();
}

const encoder = new TextEncoder();
const encoded = encoder.encode(body);
return encoded.length.toString();
}

return null;
}

buildRequest<Req extends {}>(
options: FinalRequestOptions<Req>,
): { req: RequestInit; url: string; timeout: number } {
Expand All @@ -131,7 +145,7 @@ export abstract class APIClient {
isMultipartBody(options.body) ? options.body.body
: options.body ? JSON.stringify(options.body, null, 2)
: null;
const contentLength = typeof body === 'string' ? body.length.toString() : null;
const contentLength = this.calculateContentLength(body);

const url = this.buildURL(path!, query);
if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
Expand Down
16 changes: 16 additions & 0 deletions tests/index.test.ts
Expand Up @@ -144,3 +144,19 @@ describe('instantiate client', () => {
expect(client.apiKey).toBeNull();
});
});

describe('request building', () => {
const client = new Anthropic({ apiKey: 'my api key' });

describe('Content-Length', () => {
test('handles multi-byte characters', () => {
const { req } = client.buildRequest({ path: '/foo', method: 'post', body: { value: '—' } });
expect((req.headers as Record<string, string>)['Content-Length']).toEqual('20');
});

test('handles standard characters', () => {
const { req } = client.buildRequest({ path: '/foo', method: 'post', body: { value: 'hello' } });
expect((req.headers as Record<string, string>)['Content-Length']).toEqual('22');
});
});
});

0 comments on commit 8dfff26

Please sign in to comment.