Skip to content

Commit

Permalink
Better communication of unsupported methods/headers
Browse files Browse the repository at this point in the history
  • Loading branch information
micahvandeusen committed Nov 6, 2022
1 parent 0a17623 commit 5d6ad62
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
public class JavaScriptRequestBuilder {
// Taken from https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name
public static final List<String> SKIP_HEADERS = List.of("accept-charset", "accept-Encoding", "access-control-request-headers", "access-control-request-method", "connection", "content-length", "cookie", "date", "dnt", "expect", "feature-policy", "host", "keep-alive", "origin", "referer", "te", "trailer", "transfer-encoding", "upgrade", "via");
public static final List<String> SKIP_HEADERS_PREFIX = List.of("sec-", "proxy-");
private final static String[] ESCAPE = new String[256];

static {
Expand All @@ -35,7 +36,7 @@ public StringBuilder build(HttpRequest request) {
List<ParsedHttpParameter> cookies = request.parameters().stream().filter(p -> p.type() == HttpParameterType.COOKIE).collect(Collectors.toList());
boolean hasCookies = cookies.size() > 0;
List<HttpHeader> filteredHeaders = request.headers().subList(1, request.headers().size())
.stream().filter(e -> !(SKIP_HEADERS.contains(e.name().toLowerCase())) && !StringUtils.startsWithAny(e.name().toLowerCase(), "sec-", "proxy-"))
.stream().filter(e -> !(SKIP_HEADERS.contains(e.name().toLowerCase())) && !StringUtils.startsWithAny(e.name().toLowerCase(), SKIP_HEADERS_PREFIX.toArray(new CharSequence[SKIP_HEADERS_PREFIX.size()])))
.collect(Collectors.toList());
boolean hasHeaders = filteredHeaders.size() > 0;
boolean hasBody = request.body().length > 0;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/rsm/reproducer/PowerShellBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public StringBuilder build(HttpRequest request) {
if (!(SUPPORTED_METHODS.contains(method))) {
JOptionPane.showMessageDialog(new JFrame(), "The \"" + StringUtils.abbreviate(request.method(), 16)
+ "\" method is not supported by PowerShell Invoke-WebRequest.", "Error", JOptionPane.ERROR_MESSAGE);
return new StringBuilder("The request method is not supported.");
}

stringBuilder.append("Add-Type -AssemblyName Microsoft.PowerShell.Commands.Utility").append(System.lineSeparator());
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/rsm/reproducer/PythonRequestBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public StringBuilder build(HttpRequest request) {

if (!(SUPPORTED_METHODS.contains(request.method()))) {
JOptionPane.showMessageDialog(new JFrame(), "The \"" + StringUtils.abbreviate(request.method(), 16)
+ "\" method is not supported by PowerShell Invoke-WebRequest.", "Error", JOptionPane.ERROR_MESSAGE);
+ "\" method is not supported by Python Requests.", "Error", JOptionPane.ERROR_MESSAGE);
return new StringBuilder("The request method is not supported.");
}

String requestsMethodPrefix = "\nrequests.";
Expand Down
71 changes: 66 additions & 5 deletions src/main/java/com/rsm/reproducer/ReproducerTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;

public class ReproducerTab {
Expand All @@ -46,8 +47,8 @@ public class ReproducerTab {
private final DefaultTableModel requestSelectorTableModel;


private static final Object[] REQUEST_SELECTOR_HEADERS = new Object[]{"Original HRR", "Simplified HRR", "Analyze Table", "Method", "URL", "Response Code", "Length"};
private static final Object[] ANALYZE_HEADERS = new Object[]{"Analyze HRR", "Type", "Name", "Value", "Include", "Response Code", "Length"};
private static final Object[] REQUEST_SELECTOR_HEADERS = new Object[]{"Original HRR", "Simplified HRR", "Analyze Table", "Method", "URL", "Response Code", "Length", "\u26A0\uFE0F"};
private static final Object[] ANALYZE_HEADERS = new Object[]{"Analyze HRR", "Type", "Name", "Value", "Include", "Response Code", "Length", "\u26A0\uFE0F"};

MontoyaApi api;

Expand Down Expand Up @@ -122,18 +123,35 @@ public Class getColumnClass(int column) {
requestSelectorTable.removeColumn(requestSelectorTable.getColumnModel().getColumn(0));
requestSelectorTable.removeColumn(requestSelectorTable.getColumnModel().getColumn(0));

requestSelectorTable.getColumnModel().getColumn(4).setCellRenderer(
new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (value != null && !((String) value).isEmpty()) {
this.setText("\u26A0\uFE0F");
this.setToolTipText(value.toString());
} else {
this.setToolTipText(null);
}
return this;
}
});

// Set sizing
topSplitPane.setResizeWeight(0.5);
requestSelectorTable.getColumnModel().getColumn(0).setPreferredWidth(150);
requestSelectorTable.getColumnModel().getColumn(1).setPreferredWidth(700);
requestSelectorTable.getColumnModel().getColumn(2).setPreferredWidth(200);
requestSelectorTable.getColumnModel().getColumn(3).setPreferredWidth(150);
requestSelectorTable.getColumnModel().getColumn(4).setPreferredWidth(50);
analyzeTable.getColumnModel().getColumn(0).setPreferredWidth(100);
analyzeTable.getColumnModel().getColumn(1).setPreferredWidth(300);
analyzeTable.getColumnModel().getColumn(2).setPreferredWidth(300);
analyzeTable.getColumnModel().getColumn(3).setPreferredWidth(100);
analyzeTable.getColumnModel().getColumn(4).setPreferredWidth(150);
analyzeTable.getColumnModel().getColumn(5).setPreferredWidth(100);
analyzeTable.getColumnModel().getColumn(6).setPreferredWidth(50);

// Only allow one row to be selected
requestSelectorTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
Expand All @@ -158,12 +176,27 @@ public Class getColumnClass(int column) {

analyzeTable.setModel((DefaultTableModel) requestSelectorTableModel.getValueAt(modelRow, 2));
analyzeTable.removeColumn(analyzeTable.getColumnModel().getColumn(0));
analyzeTable.getColumnModel().getColumn(6).setCellRenderer(
new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (value != null && !((String) value).isEmpty()) {
this.setText("\u26A0\uFE0F");
this.setToolTipText(value.toString());
} else {
this.setToolTipText(null);
}
return this;
}
});
analyzeTable.getColumnModel().getColumn(0).setPreferredWidth(100);
analyzeTable.getColumnModel().getColumn(1).setPreferredWidth(300);
analyzeTable.getColumnModel().getColumn(2).setPreferredWidth(300);
analyzeTable.getColumnModel().getColumn(3).setPreferredWidth(100);
analyzeTable.getColumnModel().getColumn(4).setPreferredWidth(150);
analyzeTable.getColumnModel().getColumn(5).setPreferredWidth(100);
analyzeTable.getColumnModel().getColumn(6).setPreferredWidth(50);
}
});

Expand Down Expand Up @@ -528,11 +561,39 @@ public Class getColumnClass(int column) {
HttpRequest modifiedRequest = request.removeHeader(header);
HttpRequestResponse modifiedHrr = HttpRequestResponse.httpRequestResponse(modifiedRequest, null);

analyzeTableModel.addRow(new Object[]{modifiedHrr, "HEADER", header.name(), header.value(), true, null, null});
StringJoiner analyzeSupportMessage = new StringJoiner("\n");
for (String skipHeader : PowerShellBuilder.SKIP_HEADERS) {
if (header.name().equalsIgnoreCase(skipHeader)) {
analyzeSupportMessage.add(header.name() + " is unsupported in PowerShell");
}
}
for (String skipHeader : JavaScriptRequestBuilder.SKIP_HEADERS) {
if (header.name().equalsIgnoreCase(skipHeader)) {
analyzeSupportMessage.add(header.name() + " is unsupported in JavaScript Fetch");
}
}
for (String skipHeader : JavaScriptRequestBuilder.SKIP_HEADERS_PREFIX) {
if (header.name().toLowerCase().startsWith(skipHeader)) {
analyzeSupportMessage.add(header.name() + " is unsupported in JavaScript Fetch");
}
}
for (String skipHeader : PythonRequestBuilder.SKIP_HEADERS) {
if (header.name().equalsIgnoreCase(skipHeader)) {
analyzeSupportMessage.add(header.name() + " is unsupported in Python Requests");
}
}
analyzeTableModel.addRow(new Object[]{modifiedHrr, "HEADER", header.name(), header.value(), true, null, null, analyzeSupportMessage.toString()});
}
}
StringJoiner requestSupportMessage = new StringJoiner("\n");
if (!PowerShellBuilder.SUPPORTED_METHODS.contains(hrr.httpRequest().method().toUpperCase())) {
requestSupportMessage.add(hrr.httpRequest().method() + " is unsupported in PowerShell");
}
if (!PythonRequestBuilder.SUPPORTED_METHODS.contains(hrr.httpRequest().method().toUpperCase())) {
requestSupportMessage.add(hrr.httpRequest().method() + " is unsupported in Python Requests");
}

requestSelectorTableModel.addRow(new Object[]{hrr, simplifiedEditorDefault, analyzeTableModel, request.method(), request.url(), response.statusCode(), response.body().length});
requestSelectorTableModel.addRow(new Object[]{hrr, simplifiedEditorDefault, analyzeTableModel, request.method(), request.url(), response.statusCode(), response.body().length, requestSupportMessage.toString()});

// Select the newly added row
int lastRow = requestSelectorTable.convertRowIndexToView(requestSelectorTableModel.getRowCount() - 1);
Expand Down

0 comments on commit 5d6ad62

Please sign in to comment.