* Makes a raw http request. * All other methods such as get, post, patch, and request ultimately call this. * Prefer get, del, post and patch
(verb, requestUrl, data, headers)
| 2706 | * Prefer get, del, post and patch |
| 2707 | */ |
| 2708 | request(verb, requestUrl, data, headers) { |
| 2709 | return __awaiter(this, void 0, void 0, function* () { |
| 2710 | if (this._disposed) { |
| 2711 | throw new Error('Client has already been disposed.'); |
| 2712 | } |
| 2713 | const parsedUrl = new URL(requestUrl); |
| 2714 | let info = this._prepareRequest(verb, parsedUrl, headers); |
| 2715 | // Only perform retries on reads since writes may not be idempotent. |
| 2716 | const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) |
| 2717 | ? this._maxRetries + 1 |
| 2718 | : 1; |
| 2719 | let numTries = 0; |
| 2720 | let response; |
| 2721 | do { |
| 2722 | response = yield this.requestRaw(info, data); |
| 2723 | // Check if it's an authentication challenge |
| 2724 | if (response && |
| 2725 | response.message && |
| 2726 | response.message.statusCode === HttpCodes.Unauthorized) { |
| 2727 | let authenticationHandler; |
| 2728 | for (const handler of this.handlers) { |
| 2729 | if (handler.canHandleAuthentication(response)) { |
| 2730 | authenticationHandler = handler; |
| 2731 | break; |
| 2732 | } |
| 2733 | } |
| 2734 | if (authenticationHandler) { |
| 2735 | return authenticationHandler.handleAuthentication(this, info, data); |
| 2736 | } |
| 2737 | else { |
| 2738 | // We have received an unauthorized response but have no handlers to handle it. |
| 2739 | // Let the response return to the caller. |
| 2740 | return response; |
| 2741 | } |
| 2742 | } |
| 2743 | let redirectsRemaining = this._maxRedirects; |
| 2744 | while (response.message.statusCode && |
| 2745 | HttpRedirectCodes.includes(response.message.statusCode) && |
| 2746 | this._allowRedirects && |
| 2747 | redirectsRemaining > 0) { |
| 2748 | const redirectUrl = response.message.headers['location']; |
| 2749 | if (!redirectUrl) { |
| 2750 | // if there's no location to redirect to, we won't |
| 2751 | break; |
| 2752 | } |
| 2753 | const parsedRedirectUrl = new URL(redirectUrl); |
| 2754 | if (parsedUrl.protocol === 'https:' && |
| 2755 | parsedUrl.protocol !== parsedRedirectUrl.protocol && |
| 2756 | !this._allowRedirectDowngrade) { |
| 2757 | throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); |
| 2758 | } |
| 2759 | // we need to finish reading the response before reassigning response |
| 2760 | // which will leak the open socket. |
| 2761 | yield response.readBody(); |
| 2762 | // strip authorization header if redirected to a different hostname |
| 2763 | if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { |
| 2764 | for (const header in headers) { |
| 2765 | // header names are case insensitive |
no test coverage detected