Skip to content

Commit

Permalink
fix: preserve multiple set-cookie headers
Browse files Browse the repository at this point in the history
  • Loading branch information
jordanbtucker committed Jun 21, 2024
1 parent e7f1635 commit 8662e7f
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 39 deletions.
10 changes: 2 additions & 8 deletions src/controllers/historyController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as path from 'path';
import { QuickPickItem, window, workspace } from 'vscode';
import { HistoricalHttpRequest } from '../models/httpRequest';
import { trace } from "../utils/decorator";
import { formatHeaders } from '../utils/misc';
import { UserDataManager } from '../utils/userDataManager';

dayjs.extend(relativeTime);
Expand Down Expand Up @@ -62,14 +63,7 @@ export class HistoryController {
private async createRequestInTempFile(request: HistoricalHttpRequest): Promise<string> {
const file = await this.createTempFile();
let output = `${request.method.toUpperCase()} ${request.url}${EOL}`;
if (request.headers) {
for (const header in request.headers) {
if (request.headers.hasOwnProperty(header)) {
const value = request.headers[header];
output += `${header}: ${value}${EOL}`;
}
}
}
output += formatHeaders(request.headers);
if (request.body) {
output += `${EOL}${request.body}`;
}
Expand Down
26 changes: 26 additions & 0 deletions src/utils/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,32 @@ export function removeHeader(headers: RequestHeaders | ResponseHeaders, name: st
}
}

export function formatHeaders(headers: RequestHeaders | ResponseHeaders): string {
let headerString = '';
for (const header in headers) {
if (headers.hasOwnProperty(header)) {
let value = headers[header];
// Handle set-cookie as a special case since multiple entries
// should appear as their own header. For example:
// set-cookie: a=b
// set-cookie: c=d
// Not:
// set-cookie: a=b,c=d
if (header.toLowerCase() === 'set-cookie') {
if (typeof value === 'string') {
value = [value];
}
for (const cookie of <Array<string>>value) {
headerString += `${header}: ${cookie}\n`;
}
} else {
headerString += `${header}: ${value}\n`;
}
}
}
return headerString;
}

export function md5(text: string | Buffer): string {
return crypto.createHash('md5').update(text).digest('hex');
}
Expand Down
15 changes: 3 additions & 12 deletions src/views/httpResponseTextDocumentView.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
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 { HttpResponse } from '../models/httpResponse';
import { PreviewOption } from '../models/previewOption';
import { MimeUtility } from '../utils/mimeUtility';
import { formatHeaders } from '../utils/misc';
import { ResponseFormatUtility } from '../utils/responseFormatUtility';

export class HttpResponseTextDocumentView {
Expand Down Expand Up @@ -49,7 +49,7 @@ export class HttpResponseTextDocumentView {
// for add request details
const request = response.request;
content += `${request.method} ${request.url} HTTP/1.1${EOL}`;
content += this.formatHeaders(request.headers);
content += formatHeaders(request.headers);
if (request.body) {
if (typeof request.body !== 'string') {
request.body = 'NOTE: Request Body From Is File Not Shown';
Expand All @@ -62,7 +62,7 @@ export class HttpResponseTextDocumentView {

if (previewOption !== PreviewOption.Body) {
content += `HTTP/${response.httpVersion} ${response.statusCode} ${response.statusMessage}${EOL}`;
content += this.formatHeaders(response.headers);
content += formatHeaders(response.headers);
}

if (previewOption !== PreviewOption.Headers) {
Expand All @@ -73,15 +73,6 @@ export class HttpResponseTextDocumentView {
return content;
}

private formatHeaders(headers: RequestHeaders | ResponseHeaders): string {
let headerString = '';
for (const header in headers) {
const value = headers[header] as string;
headerString += `${header}: ${value}${EOL}`;
}
return headerString;
}

private getVSCodeDocumentLanguageId(response: HttpResponse) {
if (this.settings.previewOption === PreviewOption.Body) {
const contentType = response.contentType;
Expand Down
23 changes: 4 additions & 19 deletions src/views/httpResponseWebview.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import * as fs from 'fs-extra';
import * as os from 'os';
import { Clipboard, commands, env, ExtensionContext, Uri, ViewColumn, WebviewPanel, 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 { trace } from '../utils/decorator';
import { disposeAll } from '../utils/dispose';
import { MimeUtility } from '../utils/mimeUtility';
import { base64, getHeader, isJSONString } from '../utils/misc';
import { base64, formatHeaders, getHeader, isJSONString } from '../utils/misc';
import { ResponseFormatUtility } from '../utils/responseFormatUtility';
import { UserDataManager } from '../utils/userDataManager';
import { BaseWebview } from './baseWebview';
Expand Down Expand Up @@ -213,7 +212,7 @@ export class HttpResponseWebview extends BaseWebview {

private getFullResponseString(response: HttpResponse): string {
const statusLine = `HTTP/${response.httpVersion} ${response.statusCode} ${response.statusMessage}${os.EOL}`;
const headerString = Object.entries(response.headers).reduce((acc, [name, value]) => acc + `${name}: ${value}${os.EOL}`, '');
const headerString = formatHeaders(response.headers);
const body = response.body ? `${os.EOL}${response.body}` : '';
return `${statusLine}${headerString}${body}`;
}
Expand Down Expand Up @@ -284,7 +283,7 @@ export class HttpResponseWebview extends BaseWebview {
// for add request details
const request = response.request;
const requestNonBodyPart = `${request.method} ${request.url} HTTP/1.1
${HttpResponseWebview.formatHeaders(request.headers)}`;
${formatHeaders(request.headers)}`;
code += hljs.highlight('http', requestNonBodyPart + '\r\n').value;
if (request.body) {
if (typeof request.body !== 'string') {
Expand All @@ -305,7 +304,7 @@ ${HttpResponseWebview.formatHeaders(request.headers)}`;

if (previewOption !== PreviewOption.Body) {
const responseNonBodyPart = `HTTP/${response.httpVersion} ${response.statusCode} ${response.statusMessage}
${HttpResponseWebview.formatHeaders(response.headers)}`;
${formatHeaders(response.headers)}`;
code += hljs.highlight('http', responseNonBodyPart + (previewOption !== PreviewOption.Headers ? '\r\n' : '')).value;
}

Expand Down Expand Up @@ -448,20 +447,6 @@ ${HttpResponseWebview.formatHeaders(response.headers)}`;
return result;
}

private static formatHeaders(headers: RequestHeaders | ResponseHeaders): string {
let headerString = '';
for (const header in headers) {
if (headers.hasOwnProperty(header)) {
let value = headers[header];
if (typeof headers[header] !== 'string') {
value = <string>headers[header];
}
headerString += `${header}: ${value}\n`;
}
}
return headerString;
}

private static getHighlightLanguageAlias(contentType: string | undefined, content: string | null = null): string | null {
if (MimeUtility.isJSON(contentType)) {
return 'json';
Expand Down

0 comments on commit 8662e7f

Please sign in to comment.