Skip to content

Commit

Permalink
Add methodRewriting option (#942)
Browse files Browse the repository at this point in the history
  • Loading branch information
szmarczak authored and sindresorhus committed Nov 25, 2019
1 parent 966e7ff commit b82358f
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 3 deletions.
7 changes: 6 additions & 1 deletion readme.md
Expand Up @@ -410,7 +410,12 @@ Defines if redirect responses should be followed automatically.

Note that if a `303` is sent by the server in response to any request type (`POST`, `DELETE`, etc.), Got will automatically request the resource pointed to in the location header via `GET`. This is in accordance with [the spec](https://tools.ietf.org/html/rfc7231#section-6.4.4).

This supports [method rewriting](https://tools.ietf.org/html/rfc7231#section-6.4). For example, when sending a POST request and receiving a `302`, it will resend that request to the new location.
###### methodRewriting

Type: `boolean`<br>
Default: `true`

By default, redirects will use [method rewriting](https://tools.ietf.org/html/rfc7231#section-6.4). For example, when sending a POST request and receiving a `302`, it will resend the body to the new location using the same HTTP method (`POST` in this case).

###### maxRedirects

Expand Down
3 changes: 2 additions & 1 deletion source/index.ts
Expand Up @@ -58,7 +58,8 @@ const defaults: Defaults = {
responseType: 'default',
resolveBodyOnly: false,
maxRedirects: 10,
prefixUrl: ''
prefixUrl: '',
methodRewriting: true
},
handlers: [defaultHandler],
mutableDefaults: false
Expand Down
2 changes: 1 addition & 1 deletion source/request-as-event-emitter.ts
Expand Up @@ -97,7 +97,7 @@ export default (options: NormalizedOptions) => {
if (options.followRedirect && Reflect.has(typedResponse.headers, 'location') && redirectCodes.has(statusCode)) {
typedResponse.resume(); // We're being redirected, we don't care about the response.

if (statusCode === 303) {
if (statusCode === 303 || options.methodRewriting === false) {
if (options.method !== 'GET' && options.method !== 'HEAD') {
// Server responded with "see other", indicating that the resource exists at another location,
// and the client should request it from that location via GET or HEAD.
Expand Down
1 change: 1 addition & 0 deletions source/utils/types.ts
Expand Up @@ -177,6 +177,7 @@ export interface Options extends Partial<Except<DefaultOptions, 'retry'>>, Merge
context?: {[key: string]: any};
maxRedirects?: number;
lookup?: CacheableLookup['lookup'];
methodRewriting?: boolean;
}

export interface NormalizedOptions extends Except<DefaultOptions, 'dnsCache'>, Except<Options, keyof DefaultOptions> {
Expand Down
27 changes: 27 additions & 0 deletions test/redirects.ts
Expand Up @@ -362,3 +362,30 @@ test('body is passed on POST redirect', withServer, async (t, server, got) => {

t.is(body, 'foobar');
});

test('method overwriting can be turned off', withServer, async (t, server, got) => {
server.post('/redirect', (_request, response) => {
response.writeHead(302, {
location: '/'
});
response.end();
});

server.get('/', (_request, response) => {
response.end();
});

const {body} = await got.post('redirect', {
body: 'foobar',
methodRewriting: false,
hooks: {
beforeRedirect: [
options => {
t.is(options.body, undefined);
}
]
}
});

t.is(body, '');
});

0 comments on commit b82358f

Please sign in to comment.