Compare commits

10 Commits

Author SHA1 Message Date
Alexis Delhaie
82fc930c02 Fix empty response error 2021-01-15 11:57:19 +01:00
Alexis Delhaie
d17133bdbd Rename Bootstrap project folder 2020-12-15 15:07:34 +01:00
Alexis Delhaie
b82ce01f9d Fixing Chuncked Encoding 2020-12-10 11:47:40 +01:00
Alexis Delhaie
bb16995dbb Fixing Basic authentication 2020-12-10 10:37:10 +01:00
Alexis Delhaie
12456e3474 Auth dialog, Parsing URL Parameters 2020-11-18 19:16:58 +01:00
Alexis Delhaie
ebf343b063 Merge branch 'master' of https://github.com/alexlegarnd/EndPoint 2020-10-27 22:02:30 +01:00
Alexis Delhaie
c4910722e9 Adding banner, Response tab, fix method combobox 2020-10-27 22:02:13 +01:00
Alexis
3b1510000d Update README.md 2020-10-25 21:55:15 +01:00
Alexis
d06d8f89f0 Update README.md 2020-10-25 21:54:58 +01:00
Alexis
cf9aff4242 Merge pull request #1 from alexlegarnd/swing
Convert project from JavaFX to Swing
2020-10-25 21:52:35 +01:00
30 changed files with 700 additions and 97 deletions

View File

@@ -5,6 +5,9 @@ Just send a GET, POST, PUT or DELETE HTTP request on a server and get it's respo
# Build # Build
⚠ Nothing is working for now
I use the language level 15 of Java, if you want to use Java 11, you need to refactor some Switches/Cases I use the language level 15 of Java, if you want to use Java 11, you need to refactor some Switches/Cases
# Binaries
Compiled binaries with installer downloadable [here](https://alexisdelhaie.ovh/dlcenter/endpoint-installer.exe). (There is no fancy web page now)
This installer are based on [chronos-installer-bootstrap](https://github.com/alexlegarnd/chronos-installer-bootstrap) and [chronos-installer](https://github.com/alexlegarnd/chronos-installer)

View File

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

View File

@@ -6,6 +6,7 @@
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int iCmdShow) int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int iCmdShow)
{ {
int return_code = 0;
STARTUPINFO si; STARTUPINFO si;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
@@ -16,17 +17,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam
LPTSTR command = _tcsdup(TEXT(".\\runtime\\bin\\javaw.exe -cp .\\app\\EndPoint.jar ovh.alexisdelhaie.endpoint.Application")); LPTSTR command = _tcsdup(TEXT(".\\runtime\\bin\\javaw.exe -cp .\\app\\EndPoint.jar ovh.alexisdelhaie.endpoint.Application"));
if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{ {
CloseHandle(&pi.hProcess);
CloseHandle(&pi.hThread);
int msgboxID = MessageBox( int msgboxID = MessageBox(
NULL, NULL,
TEXT("Unable to start the JVM. Try reinstalling the program to fix this problem."), TEXT("Unable to start the JVM. Try reinstalling the program to fix this problem."),
TEXT("EndPoint bootstrap"), TEXT("EndPoint bootstrap"),
MB_ICONHAND | MB_OK | MB_DEFBUTTON1 MB_ICONHAND | MB_OK | MB_DEFBUTTON1
); );
return -1; return_code = -1;
} }
CloseHandle(&pi.hProcess); CloseHandle(&pi.hProcess);
CloseHandle(&pi.hThread); CloseHandle(&pi.hThread);
return 0; return return_code;
} }

23
pom.xml
View File

@@ -6,12 +6,26 @@
<groupId>ovh.alexisdelhaie</groupId> <groupId>ovh.alexisdelhaie</groupId>
<artifactId>EndPoint</artifactId> <artifactId>EndPoint</artifactId>
<version>0.1.3</version> <version>0.1.5.3</version>
<packaging>jar</packaging>
<properties> <properties>
<maven.compiler.release>15</maven.compiler.release> <maven.compiler.release>15</maven.compiler.release>
</properties> </properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>15</release>
</configuration>
</plugin>
</plugins>
</build>
<dependencies> <dependencies>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency> <dependency>
@@ -31,6 +45,13 @@
<artifactId>flatlaf</artifactId> <artifactId>flatlaf</artifactId>
<version>0.43</version> <version>0.43</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient -->
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -1,17 +1,17 @@
package ovh.alexisdelhaie.endpoint; package ovh.alexisdelhaie.endpoint;
import com.formdev.flatlaf.FlatIntelliJLaf; import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties;
import ovh.alexisdelhaie.endpoint.utils.Tools; import ovh.alexisdelhaie.endpoint.utils.Tools;
import javax.swing.*; import javax.swing.*;
import java.awt.*;
import java.io.IOException; import java.io.IOException;
public class Application { public class Application {
public static void main(String[] args) throws UnsupportedLookAndFeelException, IOException { public static void main(String[] args) throws UnsupportedLookAndFeelException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
UIManager.setLookAndFeel(new FlatIntelliJLaf()); ConfigurationProperties props = new ConfigurationProperties();
MainWindow dialog = new MainWindow(); UIManager.setLookAndFeel(Tools.getLookAndFeel(props.getStringProperty("theme", "IntelliJ")));
MainWindow dialog = new MainWindow(props);
dialog.pack(); dialog.pack();
dialog.setTitle("EndPoint"); dialog.setTitle("EndPoint");
dialog.setVisible(true); dialog.setVisible(true);

View File

@@ -116,7 +116,7 @@
</hspacer> </hspacer>
<component id="45ca1" class="javax.swing.JButton" binding="settingsButton" default-binding="true"> <component id="45ca1" class="javax.swing.JButton" binding="settingsButton" default-binding="true">
<constraints> <constraints>
<grid row="1" column="14" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/> <grid row="3" column="15" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
<properties> <properties>
<text value="Settings"/> <text value="Settings"/>

View File

@@ -8,21 +8,26 @@ import ovh.alexisdelhaie.endpoint.http.Request;
import ovh.alexisdelhaie.endpoint.http.RequestBuilder; import ovh.alexisdelhaie.endpoint.http.RequestBuilder;
import ovh.alexisdelhaie.endpoint.http.Response; import ovh.alexisdelhaie.endpoint.http.Response;
import ovh.alexisdelhaie.endpoint.utils.MessageDialog; import ovh.alexisdelhaie.endpoint.utils.MessageDialog;
import ovh.alexisdelhaie.endpoint.utils.RequestTab;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener; import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainWindow extends JFrame { public class MainWindow extends JFrame {
@@ -47,6 +52,7 @@ public class MainWindow extends JFrame {
// Constants // Constants
public final static int WIDTH = 1280; public final static int WIDTH = 1280;
public final static int HEIGHT = 720; public final static int HEIGHT = 720;
public final static String NEW_TAB_NAME = "New request";
private JPanel contentPane; private JPanel contentPane;
private JComboBox<String> methodBox; private JComboBox<String> methodBox;
@@ -59,41 +65,29 @@ public class MainWindow extends JFrame {
private JButton settingsButton; private JButton settingsButton;
private final ConfigurationProperties props; private final ConfigurationProperties props;
private final HashMap<Integer, String> urls; private final ConcurrentHashMap<Integer, RequestTab> tabs;
private final ConcurrentHashMap<Integer, Boolean> controlState; public MainWindow(ConfigurationProperties props) throws IOException {
private final ConcurrentHashMap<Integer, Response> responses; this.props = props;
tabs = new ConcurrentHashMap<>();
public MainWindow() throws IOException {
props = new ConfigurationProperties();
controlState = new ConcurrentHashMap<>();
responses = new ConcurrentHashMap<>();
urls = new HashMap<>();
setIconImage(ImageIO.read(MainWindow.class.getResource("/icon.png"))); setIconImage(ImageIO.read(MainWindow.class.getResource("/icon.png")));
setContentPane(contentPane); setContentPane(contentPane);
setMinimumSize(new Dimension(WIDTH, HEIGHT)); setMinimumSize(new Dimension(WIDTH, HEIGHT));
setSize(WIDTH, HEIGHT); setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TabBuilder.create(tabbedPane1, "New request", urls, urlField); newTab();
Component tab = tabbedPane1.getSelectedComponent();
urls.put(tab.hashCode(), "");
enableControl(true, tab.hashCode());
settingsButton.addMouseListener(new MouseAdapter() { settingsButton.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
super.mouseClicked(e); super.mouseClicked(e);
ConfigurationDialog.showDialog(props); ConfigurationDialog.showDialog(props, MainWindow.this);
} }
}); });
newTabButton.addMouseListener(new MouseAdapter() { newTabButton.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
super.mouseClicked(e); super.mouseClicked(e);
TabBuilder.create(tabbedPane1, "New request", urls, urlField); newTab();
Component tab = tabbedPane1.getSelectedComponent();
urls.put(tab.hashCode(), "");
enableControl(true, tab.hashCode());
showStatus(tab.hashCode());
} }
}); });
sendButton.addMouseListener(new MouseAdapter() { sendButton.addMouseListener(new MouseAdapter() {
@@ -110,9 +104,22 @@ public class MainWindow extends JFrame {
tabbedPane1.addChangeListener(e -> { tabbedPane1.addChangeListener(e -> {
if (tabbedPane1.getSelectedIndex() != -1) { if (tabbedPane1.getSelectedIndex() != -1) {
int hashCode = tabbedPane1.getSelectedComponent().hashCode(); int hashCode = tabbedPane1.getSelectedComponent().hashCode();
urlField.setText(urls.get(hashCode)); RequestTab requestTab = tabs.get(hashCode);
enableControl(controlState.get(hashCode), hashCode); if (Objects.nonNull(requestTab)) {
showStatus(tab.hashCode()); urlField.setText(requestTab.getUrl());
methodBox.setSelectedItem(requestTab.getMethod());
enableControl(requestTab.isRunning(), hashCode);
showStatus(hashCode);
}
}
});
methodBox.addItemListener((e) -> {
if (tabbedPane1.getSelectedIndex() != -1) {
int hashCode = tabbedPane1.getSelectedComponent().hashCode();
RequestTab requestTab = tabs.get(hashCode);
if (Objects.nonNull(requestTab)) {
requestTab.setMethod((String) methodBox.getSelectedItem());
}
} }
}); });
urlField.getDocument().addDocumentListener(new DocumentListener() { urlField.getDocument().addDocumentListener(new DocumentListener() {
@@ -128,23 +135,59 @@ public class MainWindow extends JFrame {
public void warn() { public void warn() {
if (tabbedPane1.getSelectedIndex() != -1) { if (tabbedPane1.getSelectedIndex() != -1) {
urls.put(tabbedPane1.getSelectedComponent().hashCode(), urlField.getText()); int i = tabbedPane1.indexOfComponent(tabbedPane1.getSelectedComponent());
JLabel title = TabBuilder.getLabel(i);
tabs.get(tabbedPane1.getSelectedComponent().hashCode()).setUrl(urlField.getText());
if (Objects.nonNull(title)) {
if (!urlField.getText().isBlank()) {
try {
URL u = new URL((!urlField.getText().toLowerCase().startsWith("http://") &&
!urlField.getText().toLowerCase().startsWith("https://")) ?
"http://" + urlField.getText() : urlField.getText());
parseParamsFromUrl(urlField.getText());
if (u.getPath().isBlank()) {
title.setText(u.getHost());
} else {
title.setText(String.format("%s (%s)", u.getPath(), u.getHost()));
}
} catch (MalformedURLException e) {
title.setText(urlField.getText());
}
} else {
title.setText(NEW_TAB_NAME);
}
}
} }
} }
}); });
} }
private void newTab() {
RequestTab requestTab = new RequestTab((String) methodBox.getSelectedItem());
TabBuilder.create(tabbedPane1, NEW_TAB_NAME, tabs, urlField);
Component tab = tabbedPane1.getSelectedComponent();
tabs.put(tab.hashCode(), requestTab);
enableControl(true, tab.hashCode());
showStatus(tab.hashCode());
urlField.setText("");
}
private void sendRequest() { private void sendRequest() {
Optional<JSplitPane> possibleTab = getSelectedTab(); Optional<JSplitPane> possibleTab = getSelectedTab();
if (possibleTab.isPresent()) { if (possibleTab.isPresent()) {
JSplitPane tab = possibleTab.get(); JSplitPane tab = possibleTab.get();
int tabHashCode = tab.hashCode(); int tabHashCode = tab.hashCode();
RequestTab requestTab = tabs.get(tabHashCode);
statusLabel.setVisible(false); statusLabel.setVisible(false);
enableControl(false, tabHashCode); enableControl(false, tabHashCode);
int i = tabbedPane1.indexOfComponent(tab); int i = tabbedPane1.indexOfComponent(tab);
JTextArea responseBody = TabBuilder.getResponseArea(i); JTextArea responseBody = TabBuilder.getResponseArea(i);
JTextArea responseHeader = TabBuilder.getResponseHeaderTextArea(i);
JTextArea requestHeader = TabBuilder.getRequestHeaderTextArea(i);
responseBody.setForeground(Color.black); responseBody.setForeground(Color.black);
responseBody.setText(""); responseBody.setText("");
responseHeader.setText("");
requestHeader.setText("");
JTextArea bodyField = TabBuilder.getBody(i); JTextArea bodyField = TabBuilder.getBody(i);
new Thread(() -> { new Thread(() -> {
try { try {
@@ -163,14 +206,16 @@ public class MainWindow extends JFrame {
} }
if (possibleRes.isPresent()) { if (possibleRes.isPresent()) {
Response res = possibleRes.get(); Response res = possibleRes.get();
responses.put(tabHashCode, res); requestTab.setRes(res);
responseBody.setText(res.getBody()); responseBody.setText(res.getBody());
requestHeader.setText(res.getRequest().getRawRequest());
responseHeader.setText(res.getRawHeaders());
} }
} catch (KeyManagementException | IOException | NoSuchAlgorithmException e) { } catch (KeyManagementException | IOException | NoSuchAlgorithmException e) {
responseBody.setForeground(Color.red); responseBody.setForeground(Color.red);
responseBody.setText(e.getMessage()); responseBody.setText(e.getMessage());
if (responses.containsKey(tabHashCode)) { if (Objects.nonNull(requestTab.getRes())) {
responses.remove(tabHashCode); requestTab.setRes(null);
showStatus(tabHashCode); showStatus(tabHashCode);
} }
} finally { } finally {
@@ -185,7 +230,7 @@ public class MainWindow extends JFrame {
private void enableControl(Boolean state, int hashCode) { private void enableControl(Boolean state, int hashCode) {
if (Objects.nonNull(state)) { if (Objects.nonNull(state)) {
controlState.put(hashCode, state); tabs.get(hashCode).setRunning(state);
if (tabbedPane1.getSelectedComponent().hashCode() == hashCode) { if (tabbedPane1.getSelectedComponent().hashCode() == hashCode) {
sendButton.setEnabled(state); sendButton.setEnabled(state);
urlField.setEnabled(state); urlField.setEnabled(state);
@@ -196,10 +241,11 @@ public class MainWindow extends JFrame {
} }
private void showStatus(int hashCode) { private void showStatus(int hashCode) {
if (controlState.get(hashCode) && responses.containsKey(hashCode) && RequestTab requestTab = tabs.get(hashCode);
if (requestTab.isRunning() && Objects.nonNull(requestTab.getRes()) &&
tabbedPane1.getSelectedComponent().hashCode() == hashCode) { tabbedPane1.getSelectedComponent().hashCode() == hashCode) {
statusLabel.setForeground(Color.BLACK); statusLabel.setForeground(Color.BLACK);
Response res = responses.get(hashCode); Response res = requestTab.getRes();
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
if (res.getStatusCode() != -1) { if (res.getStatusCode() != -1) {
sb.append(res.getStatusCode()) sb.append(res.getStatusCode())
@@ -240,4 +286,25 @@ public class MainWindow extends JFrame {
return Optional.empty(); return Optional.empty();
} }
private void parseParamsFromUrl(String url) {
Optional<JSplitPane> possibleTab = getSelectedTab();
if (possibleTab.isPresent()) {
int id = tabbedPane1.indexOfComponent(possibleTab.get());
JTable table = TabBuilder.getParamsTable(id);
DefaultTableModel m = (DefaultTableModel) table.getModel();
for (int i = m.getRowCount() - 1; i > -1; i--) {
m.removeRow(i);
}
Pattern pattern = Pattern.compile("[^&?]*?=[^&?]*", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(url);
while (matcher.find()) {
String param = matcher.group();
String[] kv = param.split("=");
if (kv.length == 2) {
m.addRow(new Object[]{kv[0], kv[1]});
}
}
}
}
} }

View File

@@ -0,0 +1,16 @@
package ovh.alexisdelhaie.endpoint.builder;
import javax.swing.table.DefaultTableModel;
public class ReadOnlyTableModel extends DefaultTableModel {
public ReadOnlyTableModel(Object[][] objects, String[] headers) {
super(objects, headers);
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
}

View File

@@ -1,10 +1,8 @@
package ovh.alexisdelhaie.endpoint.builder; package ovh.alexisdelhaie.endpoint.builder;
import ovh.alexisdelhaie.endpoint.utils.RequestTab;
import ovh.alexisdelhaie.endpoint.utils.Tools; import ovh.alexisdelhaie.endpoint.utils.Tools;
import ovh.alexisdelhaie.endpoint.utils.adapter.CustomDeleteMouseAdapter; import ovh.alexisdelhaie.endpoint.utils.adapter.*;
import ovh.alexisdelhaie.endpoint.utils.adapter.CustomNewMouseAdapter;
import ovh.alexisdelhaie.endpoint.utils.adapter.DeleteParamMouseAdapter;
import ovh.alexisdelhaie.endpoint.utils.adapter.NewParamMouseAdapter;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
@@ -12,17 +10,18 @@ import java.awt.*;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public class TabBuilder { public class TabBuilder {
private static final HashMap<String, Component> indexes = new HashMap<>(); public static final ConcurrentHashMap<String, Component> indexes = new ConcurrentHashMap<>();
public static void create(JTabbedPane tab, String label, HashMap<Integer, String> urls, JTextField urlField) { public static void create(JTabbedPane tab, String label, ConcurrentHashMap<Integer, RequestTab> tabs, JTextField urlField) {
Component c = tab.add("", buildMainPanel(urlField)); Component c = tab.add("", buildMainPanel(urlField));
int index = tab.indexOfComponent(c); int index = tab.indexOfComponent(c);
updateIndexes(index); tab.setTabComponentAt(index, buildTabPanel(tab, c, label, tabs));
tab.setTabComponentAt(index, buildTabPanel(tab, c, label, urls));
tab.setSelectedComponent(c); tab.setSelectedComponent(c);
updateIndexes(index);
} }
private static void updateIndexes(int index) { private static void updateIndexes(int index) {
@@ -30,16 +29,23 @@ public class TabBuilder {
indexes.put("main[" + index + "].body", indexes.get("main[waiting].body")); indexes.put("main[" + index + "].body", indexes.get("main[waiting].body"));
indexes.put("main[" + index + "].params", indexes.get("main[waiting].params")); indexes.put("main[" + index + "].params", indexes.get("main[waiting].params"));
indexes.put("main[" + index + "].headers", indexes.get("main[waiting].headers")); indexes.put("main[" + index + "].headers", indexes.get("main[waiting].headers"));
indexes.put("main[" + index + "].tabTitle", indexes.get("main[waiting].tabTitle"));
indexes.put("main[" + index + "].requestHeaderTextArea", indexes.get("main[waiting].requestHeaderTextArea"));
indexes.put("main[" + index + "].responseHeaderTextArea", indexes.get("main[waiting].responseHeaderTextArea"));
indexes.remove("main[waiting].responseTextArea"); indexes.remove("main[waiting].responseTextArea");
indexes.remove("main[waiting].body"); indexes.remove("main[waiting].body");
indexes.remove("main[waiting].params"); indexes.remove("main[waiting].params");
indexes.remove("main[waiting].headers"); indexes.remove("main[waiting].headers");
indexes.remove("main[waiting].tabTitle");
indexes.remove("main[waiting].requestHeaderTextArea");
indexes.remove("main[waiting].responseHeaderTextArea");
} }
private static JPanel buildTabPanel(JTabbedPane tab, Component c, String label, HashMap<Integer, String> urls) { private static JPanel buildTabPanel(JTabbedPane tab, Component c, String label, ConcurrentHashMap<Integer, RequestTab> tabs) {
JPanel p = new JPanel(new GridBagLayout()); JPanel p = new JPanel(new GridBagLayout());
p.setOpaque(false); p.setOpaque(false);
JLabel l = new JLabel(label); JLabel l = new JLabel(label);
indexes.put("main[waiting].tabTitle", l);
GridBagConstraints g = new GridBagConstraints(); GridBagConstraints g = new GridBagConstraints();
g.gridx = 0; g.gridx = 0;
g.gridy = 0; g.gridy = 0;
@@ -47,11 +53,11 @@ public class TabBuilder {
p.add(l, g); p.add(l, g);
g.gridx++; g.gridx++;
g.weightx = 0; g.weightx = 0;
p.add(buildCloseButton(tab, c, urls), g); p.add(buildCloseButton(tab, c, tabs), g);
return p; return p;
} }
private static JButton buildCloseButton(JTabbedPane tab, Component c, HashMap<Integer, String> urls) { private static JButton buildCloseButton(JTabbedPane tab, Component c, ConcurrentHashMap<Integer, RequestTab> tabs) {
JButton b = new JButton("×"); JButton b = new JButton("×");
b.setBorderPainted(false); b.setBorderPainted(false);
b.setFocusPainted(false); b.setFocusPainted(false);
@@ -61,7 +67,7 @@ public class TabBuilder {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
super.mouseClicked(e); super.mouseClicked(e);
urls.remove(c.hashCode()); tabs.remove(c.hashCode());
tab.remove(c); tab.remove(c);
} }
}); });
@@ -84,11 +90,26 @@ public class TabBuilder {
private static JTabbedPane buildParametersTabbedPane(JTextField urlField) { private static JTabbedPane buildParametersTabbedPane(JTextField urlField) {
JTabbedPane p = new JTabbedPane(); JTabbedPane p = new JTabbedPane();
p.add("Params", buildParamsTab(true, urlField)); p.add("Params", buildParamsTab(true, urlField));
p.add("Authorization", new JPanel());
p.add("Headers", buildParamsTab(false, null)); p.add("Headers", buildParamsTab(false, null));
JTextArea body = new JTextArea(); JTextArea body = new JTextArea();
indexes.put("main[waiting].body", body); indexes.put("main[waiting].body", body);
p.add("Body", body); p.add("Body", body);
// Response tab
JTextArea repHeader = new JTextArea();
repHeader.setBackground(Color.WHITE);
repHeader.setEditable(false);
JScrollPane rep = new JScrollPane(repHeader);
JTextArea reqHeader = new JTextArea();
reqHeader.setBackground(Color.WHITE);
reqHeader.setEditable(false);
JScrollPane req = new JScrollPane(reqHeader);
indexes.put("main[waiting].requestHeaderTextArea", reqHeader);
indexes.put("main[waiting].responseHeaderTextArea", repHeader);
p.add("Response", new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
rep,
req
));
return p; return p;
} }
@@ -100,19 +121,36 @@ public class TabBuilder {
return (JTextArea) indexes.get("main[" + index + "].body"); return (JTextArea) indexes.get("main[" + index + "].body");
} }
public static JTextArea getRequestHeaderTextArea(int index) {
return (JTextArea) indexes.get("main[" + index + "].requestHeaderTextArea");
}
public static JTextArea getResponseHeaderTextArea(int index) {
return (JTextArea) indexes.get("main[" + index + "].responseHeaderTextArea");
}
public static HashMap<String, String> getParams(int index) { public static HashMap<String, String> getParams(int index) {
JTable t = (JTable) indexes.get("main[" + index + "].params"); JTable t = (JTable) indexes.get("main[" + index + "].params");
return Tools.tableToHashMap(t); return Tools.tableToHashMap(t);
} }
public static JTable getParamsTable(int index) {
return (JTable) indexes.get("main[" + index + "].params");
}
public static HashMap<String, String> getHeaders(int index) { public static HashMap<String, String> getHeaders(int index) {
JTable t = (JTable) indexes.get("main[" + index + "].headers"); JTable t = (JTable) indexes.get("main[" + index + "].headers");
return Tools.tableToHashMap(t); return Tools.tableToHashMap(t);
} }
public static JLabel getLabel(int index) {
return (JLabel) indexes.get("main[" + index + "].tabTitle");
}
private static JPanel buildParamsTab(boolean isParam, JTextField urlField) { private static JPanel buildParamsTab(boolean isParam, JTextField urlField) {
String[] headers = {"Keys", "Values"}; String[] headers = {"Keys", "Values"};
DefaultTableModel model = new DefaultTableModel(new Object[][]{}, headers); DefaultTableModel model = (isParam)? new ReadOnlyTableModel(new Object[][]{}, headers) :
new DefaultTableModel(new Object[][]{}, headers);
JPanel p = new JPanel(); JPanel p = new JPanel();
JTable t = new JTable(model); JTable t = new JTable(model);
indexes.put((isParam) ? "main[waiting].params" : "main[waiting].headers", t); indexes.put((isParam) ? "main[waiting].params" : "main[waiting].headers", t);
@@ -120,17 +158,19 @@ public class TabBuilder {
JButton delButton = new JButton("Remove"); JButton delButton = new JButton("Remove");
delButton.setEnabled(false); delButton.setEnabled(false);
t.getSelectionModel().addListSelectionListener(event -> delButton.setEnabled(t.getSelectedRows().length > 0)); t.getSelectionModel().addListSelectionListener(event -> delButton.setEnabled(t.getSelectedRows().length > 0));
p.add(addButton);
p.add(delButton);
if (isParam) { if (isParam) {
addButton.addMouseListener(new NewParamMouseAdapter(t, urlField)); addButton.addMouseListener(new NewParamMouseAdapter(t, urlField));
delButton.addMouseListener(new DeleteParamMouseAdapter(t, urlField)); delButton.addMouseListener(new DeleteParamMouseAdapter(t, urlField));
} else { } else {
addButton.addMouseListener(new CustomNewMouseAdapter(t)); addButton.addMouseListener(new CustomNewMouseAdapter(t));
delButton.addMouseListener(new CustomDeleteMouseAdapter(t)); delButton.addMouseListener(new CustomDeleteMouseAdapter(t));
JButton authButton = new JButton("Set authorization");
authButton.addMouseListener(new AuthorizationAdapter(t));
p.add(authButton);
} }
p.add(addButton);
p.add(delButton);
p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
JPanel pp = new JPanel(); JPanel pp = new JPanel();
pp.add(p); pp.add(p);
JScrollPane sp = new JScrollPane(t); JScrollPane sp = new JScrollPane(t);

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="ovh.alexisdelhaie.endpoint.configuration.AboutDialog"> <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="ovh.alexisdelhaie.endpoint.configuration.AboutDialog">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/> <margin top="10" left="10" bottom="10" right="10"/>
<constraints> <constraints>
<xy x="48" y="54" width="451" height="414"/> <xy x="48" y="54" width="864" height="414"/>
</constraints> </constraints>
<properties/> <properties/>
<border type="none"/> <border type="none"/>
@@ -11,7 +11,7 @@
<grid id="e3588" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <grid id="e3588" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/> <margin top="0" left="0" bottom="0" right="0"/>
<constraints> <constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
<properties/> <properties/>
<border type="none"/> <border type="none"/>
@@ -58,6 +58,18 @@
</component> </component>
</children> </children>
</grid> </grid>
<component id="21f05" class="javax.swing.JLabel" binding="banner">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<horizontalAlignment value="2"/>
<horizontalTextPosition value="2"/>
<text value=""/>
<verticalAlignment value="1"/>
<verticalTextPosition value="1"/>
</properties>
</component>
</children> </children>
</grid> </grid>
</form> </form>

View File

@@ -1,20 +1,24 @@
package ovh.alexisdelhaie.endpoint.configuration; package ovh.alexisdelhaie.endpoint.configuration;
import ovh.alexisdelhaie.endpoint.MainWindow;
import ovh.alexisdelhaie.endpoint.utils.Tools; import ovh.alexisdelhaie.endpoint.utils.Tools;
import javax.imageio.ImageIO;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.io.IOException;
public class AboutDialog extends JDialog { public class AboutDialog extends JDialog {
public static final int WIDTH = 450; public static final int WIDTH = 740;
public static final int HEIGHT = 500; public static final int HEIGHT = 500;
public static final String VERSION = "0.1.3"; public static final String VERSION = "0.1.5.3";
private JPanel contentPane; private JPanel contentPane;
private JLabel version; private JLabel version;
private JLabel javaVersion; private JLabel javaVersion;
private JLabel banner;
private AboutDialog() { private AboutDialog() {
setContentPane(contentPane); setContentPane(contentPane);
@@ -22,6 +26,11 @@ public class AboutDialog extends JDialog {
setTitle("About EndPoint"); setTitle("About EndPoint");
version.setText("Version: " + VERSION + " (NOT FINISHED)"); version.setText("Version: " + VERSION + " (NOT FINISHED)");
javaVersion.setText("Software: Java " + System.getProperty("java.version") + " (GUI: Java Swing)"); javaVersion.setText("Software: Java " + System.getProperty("java.version") + " (GUI: Java Swing)");
try {
banner.setIcon(new ImageIcon(ImageIO.read(MainWindow.class.getResource("/banner.png"))));
} catch (IOException e) {
e.printStackTrace();
}
} }
public static void showDialog() { public static void showDialog() {

View File

@@ -49,7 +49,7 @@
</component> </component>
</children> </children>
</grid> </grid>
<grid id="e3588" layout-manager="GridLayoutManager" row-count="7" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <grid id="e3588" layout-manager="GridLayoutManager" row-count="9" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/> <margin top="0" left="0" bottom="0" right="0"/>
<constraints> <constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -73,7 +73,7 @@
</hspacer> </hspacer>
<vspacer id="d1324"> <vspacer id="d1324">
<constraints> <constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/> <grid row="8" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
</vspacer> </vspacer>
<component id="c7f68" class="javax.swing.JLabel"> <component id="c7f68" class="javax.swing.JLabel">
@@ -168,6 +168,40 @@
</constraints> </constraints>
<properties/> <properties/>
</component> </component>
<component id="ff47a" class="javax.swing.JLabel">
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font style="1"/>
<text value="Appearance"/>
</properties>
</component>
<component id="e33fb" class="javax.swing.JLabel">
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Theme"/>
</properties>
</component>
<hspacer id="1d971">
<constraints>
<grid row="7" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="d304c" class="javax.swing.JComboBox" binding="theme">
<constraints>
<grid row="7" column="2" row-span="1" col-span="3" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<model>
<item value="IntelliJ"/>
<item value="Darcula"/>
<item value="System"/>
</model>
</properties>
</component>
</children> </children>
</grid> </grid>
</children> </children>

View File

@@ -1,9 +1,11 @@
package ovh.alexisdelhaie.endpoint.configuration; package ovh.alexisdelhaie.endpoint.configuration;
import ovh.alexisdelhaie.endpoint.utils.MessageDialog;
import ovh.alexisdelhaie.endpoint.utils.Tools; import ovh.alexisdelhaie.endpoint.utils.Tools;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.util.Objects;
public class ConfigurationDialog extends JDialog { public class ConfigurationDialog extends JDialog {
@@ -17,10 +19,11 @@ public class ConfigurationDialog extends JDialog {
private JComboBox<String> httpVersion; private JComboBox<String> httpVersion;
private JSpinner timeout; private JSpinner timeout;
private JButton aboutButton; private JButton aboutButton;
private JComboBox theme;
private final ConfigurationProperties props; private final ConfigurationProperties props;
private ConfigurationDialog(ConfigurationProperties props) { private ConfigurationDialog(ConfigurationProperties props, JFrame frame) {
setContentPane(contentPane); setContentPane(contentPane);
setModal(true); setModal(true);
getRootPane().setDefaultButton(buttonOK); getRootPane().setDefaultButton(buttonOK);
@@ -32,6 +35,7 @@ public class ConfigurationDialog extends JDialog {
allowDowngrade.setSelected(this.props.getBooleanProperty("allowDowngrade", true)); allowDowngrade.setSelected(this.props.getBooleanProperty("allowDowngrade", true));
httpVersion.setSelectedItem(this.props.getStringProperty("httpVersion", "HTTP/1.0")); httpVersion.setSelectedItem(this.props.getStringProperty("httpVersion", "HTTP/1.0"));
timeout.setValue(this.props.getIntegerProperty("timeout", 10000)); timeout.setValue(this.props.getIntegerProperty("timeout", 10000));
theme.setSelectedItem(this.props.getStringProperty("theme", "IntelliJ"));
allowInvalidSsl.addActionListener((e) -> { allowInvalidSsl.addActionListener((e) -> {
this.props.setProperty("allowInvalidSsl", String.valueOf(allowInvalidSsl.isSelected())); this.props.setProperty("allowInvalidSsl", String.valueOf(allowInvalidSsl.isSelected()));
@@ -45,15 +49,24 @@ public class ConfigurationDialog extends JDialog {
timeout.addChangeListener((e) -> { timeout.addChangeListener((e) -> {
this.props.setProperty("timeout", String.valueOf(timeout.getValue())); this.props.setProperty("timeout", String.valueOf(timeout.getValue()));
}); });
theme.addActionListener((e) -> {
String value = (String) theme.getSelectedItem();
this.props.setProperty("theme", value);
try {
UIManager.setLookAndFeel(Tools.getLookAndFeel(Objects.requireNonNull(value)));
SwingUtilities.updateComponentTreeUI(frame);
} catch(UnsupportedLookAndFeelException | InstantiationException | IllegalAccessException | ClassNotFoundException err) {
MessageDialog.error("Error while changing theme", err.getMessage());
}
});
} }
private void onOK() { private void onOK() {
dispose(); dispose();
} }
public static void showDialog(ConfigurationProperties props) { public static void showDialog(ConfigurationProperties props, JFrame frame) {
ConfigurationDialog dialog = new ConfigurationDialog(props); ConfigurationDialog dialog = new ConfigurationDialog(props, frame);
dialog.setModal(true); dialog.setModal(true);
dialog.setMinimumSize(new Dimension(WIDTH, HEIGHT)); dialog.setMinimumSize(new Dimension(WIDTH, HEIGHT));
dialog.setMaximumSize(new Dimension(WIDTH, HEIGHT)); dialog.setMaximumSize(new Dimension(WIDTH, HEIGHT));

View File

@@ -1,6 +1,7 @@
package ovh.alexisdelhaie.endpoint.http; package ovh.alexisdelhaie.endpoint.http;
import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties; import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties;
import ovh.alexisdelhaie.endpoint.utils.MessageDialog;
import javax.net.ssl.*; import javax.net.ssl.*;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@@ -88,6 +89,8 @@ public class HttpClient {
long time = end.toEpochMilli() - start.toEpochMilli(); long time = end.toEpochMilli() - start.toEpochMilli();
r.setRawRequest(request); r.setRawRequest(request);
return Optional.of(new Response(b, time, downgraded, r)); return Optional.of(new Response(b, time, downgraded, r));
} catch (Exception e) {
MessageDialog.error("HTTP Error", e.getMessage());
} finally { } finally {
s.close(); s.close();
} }
@@ -126,7 +129,6 @@ public class HttpClient {
} }
SSLSocket s = (SSLSocket) factory.createSocket(host, port); SSLSocket s = (SSLSocket) factory.createSocket(host, port);
s.setEnabledProtocols(new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" });
s.setKeepAlive(false); s.setKeepAlive(false);
s.setSoTimeout(timeout); s.setSoTimeout(timeout);
if (allowDowngrade) { if (allowDowngrade) {

View File

@@ -29,14 +29,18 @@ public class Response {
headers = new HashMap<>(); headers = new HashMap<>();
rawResponse = new String(res, StandardCharsets.UTF_8); rawResponse = new String(res, StandardCharsets.UTF_8);
int crlf = rawResponse.indexOf(DOUBLE_CRLF); int crlf = rawResponse.indexOf(DOUBLE_CRLF);
rawHeaders = rawResponse.substring(0, crlf); if (crlf > 0) {
parseHeaders(); rawHeaders = rawResponse.substring(0, crlf);
rawResponse = new String(res, getEncoding()); parseHeaders();
body = rawResponse.substring(crlf + DOUBLE_CRLF.length()); rawResponse = new String(res, getEncoding());
body = rawResponse.substring(crlf + DOUBLE_CRLF.length());
parseBody();
} else {
rawHeaders = rawResponse;
}
this.time = time; this.time = time;
request = r; request = r;
this.downgraded = downgraded; this.downgraded = downgraded;
parseBody();
} }
private void parseHeaders() { private void parseHeaders() {
@@ -51,13 +55,13 @@ public class Response {
} }
private void parseStatus(String l) { private void parseStatus(String l) {
Pattern p = Pattern.compile("^(HTTP/1.1)\\s([0-9]{3})\\s(.+)$"); Pattern p = Pattern.compile("^(HTTP/[0-2].[0-1])\\s([0-9]{3})\\s(.+)$");
Matcher m = p.matcher(l); Matcher m = p.matcher(l);
if (m.matches()) { if (m.matches()) {
statusCode = Integer.parseInt(m.group(2)); statusCode = Integer.parseInt(m.group(2));
status = m.group(3); status = m.group(3);
} else { } else {
p = Pattern.compile("^(HTTP/1.1)\\s([0-9]{3})?(.*)$"); p = Pattern.compile("^(HTTP/[0-2].[0-1])\\s([0-9]{3})?(.*)$");
m = p.matcher(l); m = p.matcher(l);
if (m.matches()) { if (m.matches()) {
statusCode = Integer.parseInt(m.group(2)); statusCode = Integer.parseInt(m.group(2));
@@ -73,12 +77,7 @@ public class Response {
private void parseBody() { private void parseBody() {
if (headers.containsKey("transfer-encoding")) { if (headers.containsKey("transfer-encoding")) {
if (headers.get("transfer-encoding").toLowerCase().contains("chunked")) { if (headers.get("transfer-encoding").toLowerCase().contains("chunked")) {
ArrayList<String> chunks = Chunked.parse(body); body = Chunked.parse(body);
final StringBuilder sb = new StringBuilder();
for (String chunk : chunks) {
sb.append(chunk);
}
body = sb.toString();
} }
} }
} }

View File

@@ -1,23 +1,22 @@
package ovh.alexisdelhaie.endpoint.http.parsers; package ovh.alexisdelhaie.endpoint.http.parsers;
import org.apache.commons.httpclient.ChunkedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
public class Chunked { public class Chunked {
public static ArrayList<String> parse(String body) { public static String parse(String body) {
ArrayList<String> result = new ArrayList<>(); String result;
try { try {
body = body.strip(); ChunkedInputStream inputStream = new ChunkedInputStream(new ByteArrayInputStream(body.getBytes()));
int length; int pos; result = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
do { } catch (IOException e) {
pos = body.indexOf("\r\n"); result = e.getLocalizedMessage();
length = Integer.parseInt(body.substring(0, pos), 16);
result.add(body.substring(pos + 2, length));
body = body.substring(pos + 2 + length);
} while (!body.isEmpty());
} catch (NumberFormatException e) {
result.add(body);
} }
return result; return result;
} }

View File

@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="ovh.alexisdelhaie.endpoint.utils.AuthorizationDialog">
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="48" y="54" width="436" height="297"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="94766" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<hspacer id="98af6">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<grid id="9538f" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="true" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="e7465" class="javax.swing.JButton" binding="buttonOK">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="OK"/>
</properties>
</component>
<component id="5723f" class="javax.swing.JButton" binding="buttonCancel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Cancel"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
<grid id="e3588" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="83a13" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font size="24"/>
<text value="Authorization"/>
</properties>
</component>
<hspacer id="b508b">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<grid id="7da3c" binding="bearerPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="f9a92" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Token"/>
</properties>
</component>
<component id="1c1f0" class="javax.swing.JTextField" binding="bearerTokenField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
</children>
</grid>
<component id="1107a" class="javax.swing.JComboBox" binding="typeBox">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<model>
<item value="Bearer"/>
<item value="Basic"/>
</model>
</properties>
</component>
<component id="f7e01" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Type"/>
</properties>
</component>
<grid id="d162d" binding="basicPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<visible value="false"/>
</properties>
<border type="none"/>
<children>
<component id="79b35" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Username"/>
</properties>
</component>
<component id="a6880" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Password"/>
</properties>
</component>
<component id="ae39c" class="javax.swing.JTextField" binding="usernameBasicField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="26ce0" class="javax.swing.JTextField" binding="passwordBasicField">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</form>

View File

@@ -0,0 +1,103 @@
package ovh.alexisdelhaie.endpoint.utils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Objects;
import java.util.Optional;
public class AuthorizationDialog extends JDialog {
public static final int WIDTH = 325;
public static final int HEIGHT = 220;
private JPanel contentPane;
private JButton buttonOK;
private JButton buttonCancel;
private JComboBox<String> typeBox;
private JPanel bearerPanel;
private JTextField bearerTokenField;
private JTextField usernameBasicField;
private JTextField passwordBasicField;
private JPanel basicPanel;
private boolean accepted = false;
private String finalValue = "";
public AuthorizationDialog() {
setTitle("Set authorization");
setContentPane(contentPane);
setModal(true);
getRootPane().setDefaultButton(buttonOK);
buttonOK.addActionListener(e -> onOK());
buttonCancel.addActionListener(e -> onCancel());
typeBox.addItemListener((e) -> {
String type = (String) typeBox.getSelectedItem();
switch (Objects.requireNonNull(type)) {
case "Basic" -> {
bearerPanel.setVisible(false);
basicPanel.setVisible(true);
}
case "Bearer" -> {
basicPanel.setVisible(false);
bearerPanel.setVisible(true);
}
}
});
// call onCancel() when cross is clicked
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
onCancel();
}
});
// call onCancel() on ESCAPE
contentPane.registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
onCancel();
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
}
private void onOK() {
String type = (String) typeBox.getSelectedItem();
switch (Objects.requireNonNull(type)) {
case "Basic" -> finalValue = String.format(
"Basic %s",
Tools.toBase64(
String.format(
"%s:%s",
usernameBasicField.getText(),
passwordBasicField.getText()
)
)
);
case "Bearer" -> finalValue = String.format("Bearer %s", bearerTokenField.getText());
}
accepted = true;
dispose();
}
private void onCancel() {
dispose();
}
public static Optional<KeyValuePair> showDialog() {
AuthorizationDialog dialog = new AuthorizationDialog();
dialog.setModal(true);
dialog.setMinimumSize(new Dimension(WIDTH, HEIGHT));
dialog.setMaximumSize(new Dimension(WIDTH, HEIGHT));
dialog.setResizable(false);
Tools.centerFrame(dialog);
dialog.setVisible(true);
if (dialog.accepted) {
return Optional.of(new KeyValuePair("authorization", dialog.finalValue));
}
return Optional.empty();
}
}

View File

@@ -0,0 +1,55 @@
package ovh.alexisdelhaie.endpoint.utils;
import ovh.alexisdelhaie.endpoint.http.Response;
public class RequestTab {
private String url;
private boolean running;
private Response res;
private String method;
public RequestTab(String method) {
url = "";
running = false;
res = null;
this.method = method;
}
public String getUrl() {
return url;
}
public RequestTab setUrl(String url) {
this.url = url;
return this;
}
public boolean isRunning() {
return running;
}
public RequestTab setRunning(boolean running) {
this.running = running;
return this;
}
public Response getRes() {
return res;
}
public RequestTab setRes(Response res) {
this.res = res;
return this;
}
public String getMethod() {
return method;
}
public RequestTab setMethod(String method) {
this.method = method;
return this;
}
}

View File

@@ -1,8 +1,13 @@
package ovh.alexisdelhaie.endpoint.utils; package ovh.alexisdelhaie.endpoint.utils;
import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import java.awt.*; import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
public class Tools { public class Tools {
@@ -32,4 +37,21 @@ public class Tools {
return result; return result;
} }
public static String toBase64(String decoded) {
byte[] encodedBytes = Base64.getEncoder().encode(decoded.getBytes());
return new String(encodedBytes);
}
public static String getLookAndFeel(String theme) {
switch (theme) {
case "IntelliJ" -> {
return FlatIntelliJLaf.class.getName();
}
case "Darcula" -> {
return FlatDarculaLaf.class.getName();
}
}
return UIManager.getSystemLookAndFeelClassName();
}
} }

View File

@@ -0,0 +1,36 @@
package ovh.alexisdelhaie.endpoint.utils.adapter;
import ovh.alexisdelhaie.endpoint.utils.AuthorizationDialog;
import ovh.alexisdelhaie.endpoint.utils.KeyValuePair;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Optional;
public class AuthorizationAdapter extends MouseAdapter {
protected final JTable table;
public AuthorizationAdapter(JTable table) {
this.table = table;
}
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
Optional<KeyValuePair> result = AuthorizationDialog.showDialog();
if (result.isPresent()) {
DefaultTableModel m = (DefaultTableModel) table.getModel();
for (int i = m.getRowCount() - 1; i > -1; i--) {
String key = (String) m.getValueAt(i,0);
if (key.toLowerCase().equals(result.get().getKey().toLowerCase())) {
m.removeRow(i);
}
}
m.addRow(new Object[]{result.get().getKey(), result.get().getValue()});
}
}
}

View File

@@ -28,6 +28,12 @@ public class CustomNewMouseAdapter extends MouseAdapter {
Optional<KeyValuePair> result = InsertToTableDialog.showDialog("Enter value"); Optional<KeyValuePair> result = InsertToTableDialog.showDialog("Enter value");
if (result.isPresent()) { if (result.isPresent()) {
DefaultTableModel m = (DefaultTableModel) table.getModel(); DefaultTableModel m = (DefaultTableModel) table.getModel();
for (int i = m.getRowCount() - 1; i > -1; i--) {
String key = (String) m.getValueAt(i,0);
if (key.toLowerCase().equals(result.get().getKey().toLowerCase())) {
m.removeRow(i);
}
}
m.addRow(new Object[]{result.get().getKey(), result.get().getValue()}); m.addRow(new Object[]{result.get().getKey(), result.get().getValue()});
valid = true; valid = true;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB