diff --git a/src/controllers/requestController.ts b/src/controllers/requestController.ts index 3726ca2d..53177e77 100644 --- a/src/controllers/requestController.ts +++ b/src/controllers/requestController.ts @@ -2,6 +2,7 @@ import { ExtensionContext, Range, TextDocument, ViewColumn, window } from 'vscod import Logger from '../logger'; import { IRestClientSettings, RequestSettings, RestClientSettings } from '../models/configurationSettings'; import { HistoricalHttpRequest, HttpRequest } from '../models/httpRequest'; +import { HttpResponse } from '../models/httpResponse'; import { RequestMetadata } from '../models/requestMetadata'; import { RequestParserFactory } from '../models/requestParserFactory'; import { trace } from "../utils/decorator"; @@ -92,7 +93,9 @@ export class RequestController { private async runCore(httpRequest: HttpRequest, settings: IRestClientSettings, document?: TextDocument) { // clear status bar this._requestStatusEntry.update({ state: RequestState.Pending }); - + const previewColumn = this.getPreviewColumn(settings); + this.renderView(settings, httpRequest, previewColumn); + // set last request and last pending request this._lastPendingRequest = httpRequest; this._lastRequestSettingTuple = [httpRequest, settings]; @@ -112,20 +115,7 @@ export class RequestController { RequestVariableCache.add(document, httpRequest.name, response); } - try { - const activeColumn = window.activeTextEditor!.viewColumn; - const previewColumn = settings.previewColumn === ViewColumn.Active - ? activeColumn - : ((activeColumn as number) + 1) as ViewColumn; - if (settings.previewResponseInUntitledDocument) { - this._textDocumentView.render(response, previewColumn); - } else if (previewColumn) { - this._webview.render(response, previewColumn); - } - } catch (reason) { - Logger.error('Unable to preview response:', reason); - window.showErrorMessage(reason); - } + this.renderView(settings, response, previewColumn); // persist to history json file await UserDataManager.addToRequestHistory(HistoricalHttpRequest.convertFromHttpRequest(httpRequest)); @@ -152,6 +142,26 @@ export class RequestController { } } + private getPreviewColumn(settings: IRestClientSettings) { + const activeColumn = window.activeTextEditor!.viewColumn; + return settings.previewColumn === ViewColumn.Active + ? activeColumn + : ((activeColumn as number) + 1) as ViewColumn; + } + + private renderView(settings: IRestClientSettings, responseOrRequest: HttpResponse | HttpRequest, previewColumn?: ViewColumn) { + try { + if (settings.previewResponseInUntitledDocument) { + this._textDocumentView.render(responseOrRequest, previewColumn); + } else if (previewColumn) { + this._webview.render(responseOrRequest, previewColumn); + } + } catch (reason) { + Logger.error('Unable to preview response:', reason); + window.showErrorMessage(reason); + } + } + public dispose() { this._requestStatusEntry.dispose(); this._webview.dispose(); diff --git a/src/views/httpResponseTextDocumentView.ts b/src/views/httpResponseTextDocumentView.ts index 2da19997..5583e90d 100644 --- a/src/views/httpResponseTextDocumentView.ts +++ b/src/views/httpResponseTextDocumentView.ts @@ -2,6 +2,7 @@ import { EOL } from 'os'; import { languages, Position, Range, TextDocument, ViewColumn, window, workspace } from 'vscode'; import { RequestHeaders, ResponseHeaders } from '../models/base'; import { SystemSettings } from '../models/configurationSettings'; +import { HttpRequest } from '../models/httpRequest'; import { HttpResponse } from '../models/httpResponse'; import { PreviewOption } from '../models/previewOption'; import { MimeUtility } from '../utils/mimeUtility'; @@ -22,9 +23,9 @@ export class HttpResponseTextDocumentView { }); } - public async render(response: HttpResponse, column?: ViewColumn) { - const content = this.getTextDocumentContent(response); - const language = this.getVSCodeDocumentLanguageId(response); + public async render(responseOrRequest: HttpResponse | HttpRequest, column?: ViewColumn) { + const content = this.getTextDocumentContent(responseOrRequest); + const language = this.getVSCodeDocumentLanguageId(responseOrRequest); let document: TextDocument; if (this.settings.showResponseInDifferentTab || this.documents.length === 0) { document = await workspace.openTextDocument({ language, content }); @@ -42,12 +43,15 @@ export class HttpResponseTextDocumentView { } } - private getTextDocumentContent(response: HttpResponse): string { + private getTextDocumentContent(responseOrRequest: HttpResponse | HttpRequest): string { + if (responseOrRequest instanceof HttpRequest) { + return `Loading ${responseOrRequest.method} ${responseOrRequest.url}`; + } let content = ''; const previewOption = this.settings.previewOption; if (previewOption === PreviewOption.Exchange) { // for add request details - const request = response.request; + const request = responseOrRequest.request; content += `${request.method} ${request.url} HTTP/1.1${EOL}`; content += this.formatHeaders(request.headers); if (request.body) { @@ -61,13 +65,13 @@ export class HttpResponseTextDocumentView { } if (previewOption !== PreviewOption.Body) { - content += `HTTP/${response.httpVersion} ${response.statusCode} ${response.statusMessage}${EOL}`; - content += this.formatHeaders(response.headers); + content += `HTTP/${responseOrRequest.httpVersion} ${responseOrRequest.statusCode} ${responseOrRequest.statusMessage}${EOL}`; + content += this.formatHeaders(responseOrRequest.headers); } if (previewOption !== PreviewOption.Headers) { const prefix = previewOption === PreviewOption.Body ? '' : EOL; - content += `${prefix}${ResponseFormatUtility.formatBody(response.body, response.contentType, true)}`; + content += `${prefix}${ResponseFormatUtility.formatBody(responseOrRequest.body, responseOrRequest.contentType, true)}`; } return content; @@ -82,9 +86,9 @@ export class HttpResponseTextDocumentView { return headerString; } - private getVSCodeDocumentLanguageId(response: HttpResponse) { + private getVSCodeDocumentLanguageId(responseOrRequest: HttpResponse | HttpRequest) { if (this.settings.previewOption === PreviewOption.Body) { - const contentType = response.contentType; + const contentType = responseOrRequest.contentType; if (MimeUtility.isJSON(contentType)) { return 'json'; } else if (MimeUtility.isJavaScript(contentType)) { diff --git a/src/views/httpResponseWebview.ts b/src/views/httpResponseWebview.ts index 6dbc2148..b52e3718 100644 --- a/src/views/httpResponseWebview.ts +++ b/src/views/httpResponseWebview.ts @@ -1,5 +1,6 @@ import * as fs from 'fs-extra'; import * as os from 'os'; +import { Readable } from 'stream'; import { Clipboard, commands, env, ExtensionContext, Uri, ViewColumn, WebviewPanel, window, workspace } from 'vscode'; import { RequestHeaders, ResponseHeaders } from '../models/base'; import { SystemSettings } from '../models/configurationSettings'; @@ -70,12 +71,12 @@ export class HttpResponseWebview extends BaseWebview { this.context.subscriptions.push(commands.registerCommand('rest-client.save-response-body', this.saveBody, this)); } - public async render(response: HttpResponse, column: ViewColumn) { + public async render(responseOrRequest: HttpResponse | HttpRequest, column: ViewColumn) { let panel: WebviewPanel; if (this.settings.showResponseInDifferentTab || this.panels.length === 0) { panel = window.createWebviewPanel( this.viewType, - this.getTitle(response), + this.getTitle(responseOrRequest), { viewColumn: column, preserveFocus: !this.settings.previewResponsePanelTakeFocus }, { enableFindWidget: true, @@ -112,16 +113,18 @@ export class HttpResponseWebview extends BaseWebview { this.panels.push(panel); } else { panel = this.panels[this.panels.length - 1]; - panel.title = this.getTitle(response); + panel.title = this.getTitle(responseOrRequest); } - panel.webview.html = this.getHtmlForWebview(panel, response); - + panel.webview.html = this.getHtmlForWebview(panel, responseOrRequest); this.setPreviewActiveContext(this.settings.previewResponsePanelTakeFocus); - panel.reveal(column, !this.settings.previewResponsePanelTakeFocus); - this.panelResponses.set(panel, response); + if (responseOrRequest instanceof HttpResponse) { + this.panelResponses.set(panel, responseOrRequest); + } + + this.activePanel = panel; this.setIsHTMLResponse(this.activeResponse); @@ -206,9 +209,12 @@ export class HttpResponseWebview extends BaseWebview { return defaultFileName; } - private getTitle(response: HttpResponse): string { - const prefix = (this.settings.requestNameAsResponseTabTitle && response.request.name) || 'Response'; - return `${prefix}(${response.timingPhases.total ?? 0}ms)`; + private getTitle(responseOrrequest: HttpResponse | HttpRequest): string { + if (responseOrrequest instanceof HttpRequest) { + return `Running request...`; + } + const prefix = (this.settings.requestNameAsResponseTabTitle && responseOrrequest.request.name) || 'Response'; + return `${prefix}(${responseOrrequest.timingPhases.total ?? 0}ms)`; } private getFullResponseString(response: HttpResponse): string { @@ -234,7 +240,20 @@ export class HttpResponseWebview extends BaseWebview { } } - private getHtmlForWebview(panel: WebviewPanel, response: HttpResponse): string { + private getHtmlForWebview(panel: WebviewPanel, responseOrRequest: HttpResponse | HttpRequest): string { + if (responseOrRequest instanceof HttpRequest) { + var message = 'Running...\n' + + `${responseOrRequest.method} ${responseOrRequest.url}` + + '\n'; + if (typeof responseOrRequest.body === 'string') { + message += `Body-Length: ${responseOrRequest.body.length} bytes`; + } + if (responseOrRequest.body instanceof Readable) { + message += `Body-Length: ${responseOrRequest.body.readableLength} bytes`; + } + return this.getHtml(panel, `
${this.addUrlLinks(this.addLineNums(message))}`, 1);
+ }
+ let response = responseOrRequest;
let innerHtml: string;
let width = 2;
let contentType = response.contentType;
@@ -249,6 +268,12 @@ export class HttpResponseWebview extends BaseWebview {
innerHtml = `${this.addLineNums(code)}`;
}
+ return this.getHtml(panel, this.settings.disableAddingHrefLinkForLargeResponse && response.bodySizeInBytes > this.settings.largeResponseBodySizeLimitInMB * 1024 * 1024
+ ? innerHtml
+ : this.addUrlLinks(innerHtml), width);
+ }
+
+ private getHtml(panel: WebviewPanel, body: string, width: number) {
// Content Security Policy
const nonce = new Date().getTime() + '' + new Date().getMilliseconds();
const csp = this.getCsp(nonce);
@@ -268,9 +293,7 @@ export class HttpResponseWebview extends BaseWebview {