Skip to content

JSON pretty-printing of request and response body #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/main/java/ch/csnc/burp/CopyRequestResponseConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class CopyRequestResponseConfiguration {
private static final String CUT_TEXT_NBSP_KEY = "CopyRequestResponseCutTextNbsp";
private static final String COPY_FULL_FULL_OR_SELECTION_KEY = "CopyRequestResponseCopyFullFullOrSelectionHotKey";
private static final String COPY_FULL_HEADER_KEY = "CopyRequestResponseCopyFullHeaderHotKey";
private static final String ENABLE_JSON_FORMATTING_KEY = "CopyRequestResponseEnableJSONFormatting";

public static String cutText() {
var cutText = CopyRequestResponseExtension.api().persistence().preferences().getString(CUT_TEXT_KEY);
Expand Down Expand Up @@ -62,6 +63,19 @@ public static void setCopyFullHeaderHotKey(String hotKey) {
CopyRequestResponseExtension.api().persistence().preferences().setString(COPY_FULL_HEADER_KEY, hotKey);
}

public static boolean enableJsonFormatting() {
var enableJson = CopyRequestResponseExtension.api().persistence().preferences().getBoolean(ENABLE_JSON_FORMATTING_KEY);
if (enableJson == null) {
enableJson = false;
}
setEnableJsonFormatting(enableJson);
return enableJson;
}

public static void setEnableJsonFormatting(boolean enabled) {
CopyRequestResponseExtension.api().persistence().preferences().setBoolean(ENABLE_JSON_FORMATTING_KEY, enabled);
}

private CopyRequestResponseConfiguration() {
// static class
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public void keyReleased(KeyEvent e) {
useNbspCheckbox.setSelected(CopyRequestResponseConfiguration.useNonBreakableSpace());
useNbspCheckbox.addActionListener(event -> CopyRequestResponseConfiguration.setUseNonBreakableSpace(useNbspCheckbox.isSelected()));

var enableJsonFormattingCheckbox = new JCheckBox("Enable pretty-printing of JSON data");
enableJsonFormattingCheckbox.setSelected(CopyRequestResponseConfiguration.enableJsonFormatting());
enableJsonFormattingCheckbox.addActionListener(event -> CopyRequestResponseConfiguration.setEnableJsonFormatting(enableJsonFormattingCheckbox.isSelected()));

var panel = new JPanel();
panel.setLayout(new MigLayout());
panel.add(cutTextLabel);
Expand All @@ -60,6 +64,7 @@ public void keyReleased(KeyEvent e) {
panel.add(copyFullFullOrSelectionHotKeyTextField, "grow, wrap");
panel.add(copyFullHeaderLabel);
panel.add(copyFullHeaderTextField, "grow, wrap");
panel.add(enableJsonFormattingCheckbox, "grow, wrap");

this.dialog = new JDialog(CopyRequestResponseExtension.api().userInterface().swingUtils().suiteFrame(), true);
this.dialog.setLocationRelativeTo(CopyRequestResponseExtension.api().userInterface().swingUtils().suiteFrame());
Expand Down
33 changes: 29 additions & 4 deletions src/main/java/ch/csnc/burp/CopyRequestResponseCopyActions.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package ch.csnc.burp;

import burp.api.montoya.http.handler.TimingData;
import burp.api.montoya.http.message.HttpMessage;
import burp.api.montoya.http.message.HttpRequestResponse;
import burp.api.montoya.http.message.responses.HttpResponse;
import burp.api.montoya.ui.contextmenu.MessageEditorHttpRequestResponse;
import burp.api.montoya.utilities.json.JsonNode;
import burp.api.montoya.utilities.json.JsonParseException;

import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.time.LocalDateTime;
Expand All @@ -16,15 +20,36 @@

public class CopyRequestResponseCopyActions {

public static String httpMessageBodyToJson(HttpMessage httpMessage) {
if (!CopyRequestResponseConfiguration.enableJsonFormatting()) {
return httpMessage.toString().strip();
}

String messageHeaders = httpMessage.toString().substring(0, httpMessage.bodyOffset()).strip();
String messageBody = httpMessage.bodyToString();

try {
JsonNode jsonNode = JsonNode.jsonNode(messageBody);
messageBody = jsonNode.toJsonString();
} catch (JsonParseException | IllegalArgumentException e) {
// ignore if JSON cannot be parsed or the input is empty
}

return "%s\n\n%s".formatted(
messageHeaders,
messageBody
).strip();
}

public static void copyFullFull(List<HttpRequestResponse> requestResponses) {
var text =
requestResponses
.stream()
.map(requestResponse ->
"%s\n\n%s".formatted(
requestResponse.request().toString().strip(),
httpMessageBodyToJson(requestResponse.request()),
Optional.ofNullable(requestResponse.response())
.map(HttpResponse::toString)
.map(CopyRequestResponseCopyActions::httpMessageBodyToJson)
.map(String::strip)
.orElse("")))
.collect(Collectors.joining("\n\n"));
Expand All @@ -37,7 +62,7 @@ public static void copyFullHeader(List<HttpRequestResponse> requestResponses) {
requestResponses
.stream()
.map(requestResponse -> {
var requestString = requestResponse.request().toString().strip();
var requestString = httpMessageBodyToJson(requestResponse.request());

var responseString = "";
if (requestResponse.hasResponse()) {
Expand All @@ -56,7 +81,7 @@ public static void copyFullHeader(List<HttpRequestResponse> requestResponses) {

public static void copyFullHeaderPlusSelectedData(MessageEditorHttpRequestResponse editor) {
var requestResponse = editor.requestResponse();
var requestString = requestResponse.request().toString().strip();
var requestString = httpMessageBodyToJson(requestResponse.request());

Supplier<String> responseStringSupplier = () -> {
if (!requestResponse.hasResponse()) {
Expand Down