Convert to Maven Project
This commit is contained in:
18
src/main/java/ovh/alexisdelhaie/endpoint/Application.java
Normal file
18
src/main/java/ovh/alexisdelhaie/endpoint/Application.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package ovh.alexisdelhaie.endpoint;
|
||||
|
||||
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) throws UnsupportedLookAndFeelException {
|
||||
UIManager.setLookAndFeel(new FlatIntelliJLaf());
|
||||
MainWindow dialog = new MainWindow();
|
||||
dialog.pack();
|
||||
dialog.setTitle("EndPoint");
|
||||
dialog.setVisible(true);
|
||||
dialog.centerFrame();
|
||||
}
|
||||
|
||||
}
|
||||
61
src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form
Normal file
61
src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form
Normal file
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="ovh.alexisdelhaie.endpoint.MainWindow">
|
||||
<grid id="cbd77" binding="contentPane" layout-manager="GridLayoutManager" row-count="3" column-count="3" 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="1098" height="665"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="d63fe" class="javax.swing.JComboBox" binding="comboBox1" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" 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="GET"/>
|
||||
<item value="POST"/>
|
||||
<item value="PUT"/>
|
||||
<item value="DELETE"/>
|
||||
<item value="HEAD"/>
|
||||
</model>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="4f0bf" class="javax.swing.JTextField" binding="textField1" default-binding="true">
|
||||
<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="842fb" class="javax.swing.JButton" binding="sendButton">
|
||||
<constraints>
|
||||
<grid row="0" column="2" 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="Send"/>
|
||||
</properties>
|
||||
</component>
|
||||
<tabbedpane id="59105" binding="tabbedPane1" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="200" height="200"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</tabbedpane>
|
||||
<component id="269e7" class="javax.swing.JButton" binding="newTabButton">
|
||||
<constraints>
|
||||
<grid row="1" column="2" 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="+"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
95
src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java
Normal file
95
src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java
Normal file
@@ -0,0 +1,95 @@
|
||||
package ovh.alexisdelhaie.endpoint;
|
||||
|
||||
import ovh.alexisdelhaie.endpoint.builder.TabBuilder;
|
||||
import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties;
|
||||
import ovh.alexisdelhaie.endpoint.http.HttpClient;
|
||||
import ovh.alexisdelhaie.endpoint.http.Request;
|
||||
import ovh.alexisdelhaie.endpoint.http.RequestBuilder;
|
||||
import ovh.alexisdelhaie.endpoint.http.Response;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MainWindow extends JFrame {
|
||||
|
||||
// Constants
|
||||
public final static int WIDTH = 1280;
|
||||
public final static int HEIGHT = 720;
|
||||
|
||||
private JPanel contentPane;
|
||||
private JComboBox<String> comboBox1;
|
||||
private JTextField textField1;
|
||||
private JButton sendButton;
|
||||
private JTabbedPane tabbedPane1;
|
||||
private JButton newTabButton;
|
||||
|
||||
private ConfigurationProperties props;
|
||||
|
||||
public MainWindow() {
|
||||
props = new ConfigurationProperties();
|
||||
setContentPane(contentPane);
|
||||
setMinimumSize(new Dimension(WIDTH, HEIGHT));
|
||||
setSize(WIDTH, HEIGHT);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
TabBuilder.create(tabbedPane1, "New request");
|
||||
newTabButton.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
super.mouseClicked(e);
|
||||
TabBuilder.create(tabbedPane1, "New request");
|
||||
}
|
||||
});
|
||||
sendButton.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
super.mouseClicked(e);
|
||||
try {
|
||||
sendRequest();
|
||||
} catch (IOException | NoSuchAlgorithmException | KeyManagementException ioException) {
|
||||
ioException.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void centerFrame() {
|
||||
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int y = (int)( screen.getHeight() / 2 ) - this.getHeight() / 2;
|
||||
int x = (int)( screen.getWidth() / 2 ) - this.getWidth() / 2;
|
||||
this.setLocation(x, y);
|
||||
}
|
||||
|
||||
private void sendRequest() throws IOException, NoSuchAlgorithmException, KeyManagementException {
|
||||
Optional<JSplitPane> possibleTab = getSelectedTab();
|
||||
if (possibleTab.isPresent()) {
|
||||
JSplitPane tab = possibleTab.get();
|
||||
String url = textField1.getText();
|
||||
HttpClient h = new HttpClient(props);
|
||||
Request r = new RequestBuilder(url)
|
||||
.build();
|
||||
Optional<Response> possibleRes = h.get(r);
|
||||
if (possibleRes.isPresent()) {
|
||||
Response res = possibleRes.get();
|
||||
int i = tabbedPane1.indexOfComponent(tab);
|
||||
JTextArea t = TabBuilder.getResponseArea(i);
|
||||
t.setText(res.getBody());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Optional<JSplitPane> getSelectedTab() {
|
||||
Component c = tabbedPane1.getSelectedComponent();
|
||||
if (c instanceof JSplitPane) {
|
||||
return Optional.of((JSplitPane) c);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package ovh.alexisdelhaie.endpoint.builder;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableColumn;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class TabBuilder {
|
||||
|
||||
private static HashMap<String, Component> indexes = new HashMap<>();
|
||||
|
||||
public static void create(JTabbedPane tab, String label) {
|
||||
Component c = tab.add("", buildMainPanel());
|
||||
int index = tab.indexOfComponent(c);
|
||||
updateIndexes(index);
|
||||
tab.setTabComponentAt(index, buildTabPanel(tab, c, label));
|
||||
tab.setSelectedComponent(c);
|
||||
}
|
||||
|
||||
private static void updateIndexes(int index) {
|
||||
indexes.put("main[" + index + "].responseTextArea", indexes.get("main[waiting].responseTextArea"));
|
||||
indexes.remove("main[waiting].responseTextArea");
|
||||
}
|
||||
|
||||
private static JPanel buildTabPanel(JTabbedPane tab, Component c, String label) {
|
||||
JPanel p = new JPanel(new GridBagLayout());
|
||||
p.setOpaque(false);
|
||||
JLabel l = new JLabel(label);
|
||||
GridBagConstraints g = new GridBagConstraints();
|
||||
g.gridx = 0;
|
||||
g.gridy = 0;
|
||||
g.weightx = 1;
|
||||
p.add(l, g);
|
||||
g.gridx++;
|
||||
g.weightx = 0;
|
||||
p.add(buildCloseButton(tab, c), g);
|
||||
return p;
|
||||
}
|
||||
|
||||
private static JButton buildCloseButton(JTabbedPane tab, Component c) {
|
||||
JButton b = new JButton("×");
|
||||
b.setBorderPainted(false);
|
||||
b.setFocusPainted(false);
|
||||
b.setOpaque(false);
|
||||
b.setContentAreaFilled(false);
|
||||
b.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
super.mouseClicked(e);
|
||||
tab.remove(c);
|
||||
}
|
||||
});
|
||||
return b;
|
||||
}
|
||||
|
||||
private static JSplitPane buildMainPanel() {
|
||||
JTextArea t = new JTextArea();
|
||||
t.setBackground(Color.WHITE);
|
||||
t.setEditable(false);
|
||||
JScrollPane sp = new JScrollPane(t);
|
||||
indexes.put("main[waiting].responseTextArea", t);
|
||||
return new JSplitPane(
|
||||
JSplitPane.VERTICAL_SPLIT,
|
||||
buildParametersTabbedPane(),
|
||||
sp
|
||||
);
|
||||
}
|
||||
|
||||
private static JTabbedPane buildParametersTabbedPane() {
|
||||
JTabbedPane p = new JTabbedPane();
|
||||
p.add("Params", buildTable());
|
||||
p.add("Authorization", new JPanel());
|
||||
p.add("Headers", buildTable());
|
||||
p.add("Body", new JTextArea());
|
||||
return p;
|
||||
}
|
||||
|
||||
private static JTable buildTable() {
|
||||
JTable t = new JTable();
|
||||
TableColumn keyCol = new TableColumn();
|
||||
keyCol.setHeaderValue("Keys");
|
||||
TableColumn valCol = new TableColumn();
|
||||
valCol.setHeaderValue("Values");
|
||||
t.addColumn(keyCol);
|
||||
t.addColumn(valCol);
|
||||
return t;
|
||||
}
|
||||
|
||||
public static JTextArea getResponseArea(int index) {
|
||||
return (JTextArea) indexes.get("main[" + index + "].responseTextArea");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package ovh.alexisdelhaie.endpoint.configuration;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import ovh.alexisdelhaie.endpoint.utils.MessageDialog;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigurationProperties {
|
||||
|
||||
private Map<String, String> properties;
|
||||
private String osname;
|
||||
private String filepath;
|
||||
private ObjectMapper mapper;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigurationProperties() {
|
||||
osname = System.getProperty("os.name").toUpperCase();
|
||||
properties = new HashMap<>();
|
||||
mapper = new ObjectMapper();
|
||||
filepath = new StringBuilder(getAppData())
|
||||
.append("EndPoint")
|
||||
.append(getSeparator())
|
||||
.append("settings.json")
|
||||
.toString();
|
||||
createAppFolder();
|
||||
load();
|
||||
}
|
||||
|
||||
public void setProperty(String key, String value) {
|
||||
properties.put(key, value);
|
||||
save();
|
||||
}
|
||||
|
||||
public String getStringProperty(String key, String defaultS) {
|
||||
if (properties.containsKey(key)) {
|
||||
return properties.get(key);
|
||||
}
|
||||
return defaultS;
|
||||
}
|
||||
|
||||
public boolean getBooleanProperty(String key, boolean defaultB) {
|
||||
if (properties.containsKey(key)) {
|
||||
return Boolean.parseBoolean(properties.get(key));
|
||||
}
|
||||
return defaultB;
|
||||
}
|
||||
|
||||
private void save() {
|
||||
try {
|
||||
mapper.writeValue(new File(filepath), properties);
|
||||
} catch (Exception e) {
|
||||
MessageDialog.error("Cannot save settings", "There was an error while saving settings file");
|
||||
}
|
||||
}
|
||||
|
||||
private void load() {
|
||||
File f = new File(filepath);
|
||||
try {
|
||||
if (f.exists()) {
|
||||
properties = mapper.readValue(f, new TypeReference<Map<String, String>>() { });
|
||||
}
|
||||
} catch (IOException e) {
|
||||
MessageDialog.error("Cannot initialize settings", "There was an error while initializing settings file");
|
||||
}
|
||||
}
|
||||
|
||||
private void createAppFolder() {
|
||||
try {
|
||||
Path path = Paths.get(new StringBuilder(getAppData())
|
||||
.append("EndPoint")
|
||||
.append(getSeparator()).toString());
|
||||
if (!Files.exists(path)) {
|
||||
Files.createDirectories(path);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
MessageDialog.error("Cannot create app folder", "There was an error while creating appdata folder");
|
||||
}
|
||||
}
|
||||
|
||||
private String getAppData() {
|
||||
String path = "";
|
||||
if (osname.contains("WIN")) {
|
||||
path = System.getenv("APPDATA");
|
||||
path = (path.endsWith("\\") ? path : path + "\\");
|
||||
}
|
||||
else if (osname.contains("MAC")) {
|
||||
path = System.getProperty("user.home") + "/Library/";
|
||||
}
|
||||
else if (osname.contains("NUX")) {
|
||||
path = System.getProperty("user.home");
|
||||
path = (path.endsWith("/") ? path : path + "/");
|
||||
}
|
||||
else {
|
||||
path = System.getProperty("user.dir");
|
||||
path = (path.endsWith("/") ? path : path + "/");
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private String getSeparator() {
|
||||
if (osname.contains("WIN")) {
|
||||
return "\\";
|
||||
}
|
||||
return "/";
|
||||
}
|
||||
|
||||
}
|
||||
164
src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java
Normal file
164
src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java
Normal file
@@ -0,0 +1,164 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class HttpClient {
|
||||
|
||||
public final static String CRLF = "\r\n";
|
||||
public final static int DEFAULT_TIMEOUT = 10000;
|
||||
public final static boolean DEFAULT_ALLOW_INVALID_SSL = false;
|
||||
public final static boolean DEFAULT_ALLOW_DOWNGRADE = true;
|
||||
public final static String DEFAULT_HTTP_VERSION = "HTTP/1.0";
|
||||
|
||||
private final boolean allowInvalidSsl;
|
||||
private final boolean allowDowngrade;
|
||||
private final String httpVersion;
|
||||
private boolean downgraded;
|
||||
|
||||
public HttpClient(ConfigurationProperties props) {
|
||||
this.allowInvalidSsl = props.getBooleanProperty("allowInvalidSsl", DEFAULT_ALLOW_INVALID_SSL);
|
||||
this.allowDowngrade = props.getBooleanProperty("allowDowngrade", DEFAULT_ALLOW_DOWNGRADE);
|
||||
this.httpVersion = props.getStringProperty("httpVersion", DEFAULT_HTTP_VERSION);
|
||||
this.downgraded = false;
|
||||
}
|
||||
|
||||
public Optional<Response> get(Request r) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
return process("GET", r, "");
|
||||
}
|
||||
|
||||
public Optional<Response> post(Request r, String body) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
if (!r.getCustomHeaders().containsKey("content-length")) {
|
||||
r.getCustomHeaders().put("content-length", String.valueOf(body.length()));
|
||||
}
|
||||
return process("POST", r, body);
|
||||
}
|
||||
|
||||
public Optional<Response> put(Request r, String body) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
if (!r.getCustomHeaders().containsKey("content-length")) {
|
||||
r.getCustomHeaders().put("content-length", String.valueOf(body.length()));
|
||||
}
|
||||
return process("PUT", r, body);
|
||||
}
|
||||
|
||||
public Optional<Response> delete(Request r) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
return process("DELETE", r, "");
|
||||
}
|
||||
|
||||
public Optional<Response> head(Request r) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
return process("HEAD", r, "");
|
||||
}
|
||||
|
||||
private Optional<Response> process(String method, Request r, String body) throws IOException, NoSuchAlgorithmException, KeyManagementException {
|
||||
Socket s = (r.getScheme().equals("https")) ?
|
||||
buildSSLSocket(resolve(r.getHost()).getHostAddress(), r.getPort())
|
||||
: buildSocket(resolve(r.getHost()).getHostAddress(), r.getPort());
|
||||
if (allowDowngrade && (s.getPort() != r.getPort())) {
|
||||
r.setPort(s.getPort());
|
||||
}
|
||||
String headers = buildHeaders(method, r);
|
||||
String request = (method.equals("POST") || method.equals("PUT")) ?
|
||||
new StringBuilder(headers).append(body).toString() : headers;
|
||||
if (s.isConnected()) {
|
||||
Instant start = Instant.now();
|
||||
try {
|
||||
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
|
||||
bos.write(request.getBytes(StandardCharsets.UTF_8));
|
||||
bos.flush();
|
||||
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
|
||||
byte[] b = bis.readAllBytes();
|
||||
Instant end = Instant.now();
|
||||
long time = end.toEpochMilli() - start.toEpochMilli();
|
||||
r.setRawRequest(request);
|
||||
return Optional.of(new Response(b, time, downgraded, r));
|
||||
} finally {
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private InetAddress resolve(String host) throws UnknownHostException {
|
||||
InetAddress[] addresses = InetAddress.getAllByName(host);
|
||||
return addresses[0];
|
||||
}
|
||||
|
||||
private Socket buildSocket(String host, int port) throws IOException {
|
||||
Socket s = new Socket(host, port);
|
||||
s.setKeepAlive(false);
|
||||
s.setSoTimeout(DEFAULT_TIMEOUT);
|
||||
return s;
|
||||
}
|
||||
|
||||
private Socket buildSSLSocket(String host, int port) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
System.setProperty("com.sun.net.ssl.rsaPreMasterSecretFix", "true");
|
||||
SSLSocketFactory factory;
|
||||
if(!allowInvalidSsl) {
|
||||
factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
|
||||
} else {
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}
|
||||
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType){}
|
||||
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType){}
|
||||
}
|
||||
};
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
factory = sc.getSocketFactory();
|
||||
}
|
||||
|
||||
SSLSocket s = (SSLSocket) factory.createSocket(host, port);
|
||||
s.setEnabledProtocols(new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" });
|
||||
s.setKeepAlive(false);
|
||||
s.setSoTimeout(DEFAULT_TIMEOUT);
|
||||
if (allowDowngrade) {
|
||||
try {
|
||||
s.startHandshake();
|
||||
return s;
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.getMessage());
|
||||
System.out.println("Downgrade to Non-SSL socket");
|
||||
downgraded = true;
|
||||
return buildSocket(host, (port == 443) ? 80 : port);
|
||||
}
|
||||
}
|
||||
s.startHandshake();
|
||||
return s;
|
||||
}
|
||||
|
||||
private String buildHeaders(String method, Request r) {
|
||||
Map<String, String> custom = r.getCustomHeaders();
|
||||
String path = (r.getParams().isEmpty()) ?
|
||||
r.getPath() : r.getPathWithParams();
|
||||
final StringBuilder sb = new StringBuilder(method).append(" ").append(path)
|
||||
.append(" ").append(httpVersion).append(CRLF);
|
||||
sb.append("host: ").append(r.getHost()).append(":").append(r.getPort()).append(CRLF);
|
||||
|
||||
sb.append("connection: close").append(CRLF);
|
||||
if (!custom.containsKey("accept")) {
|
||||
sb.append("accept: */*").append(CRLF);
|
||||
}
|
||||
if (!custom.containsKey("user-agent")) {
|
||||
sb.append("user-agent: endpoint/1.0").append(CRLF);
|
||||
}
|
||||
for (Map.Entry<String, String> h : custom.entrySet()) {
|
||||
sb.append(h.getKey()).append(": ").append(h.getValue()).append(CRLF);
|
||||
}
|
||||
return sb.append(CRLF).toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum HttpStatus {
|
||||
CONTINUE(100, "Continue"),
|
||||
SWITCHING_PROTOCOLS(101, "Switching Protocols"),
|
||||
|
||||
OK(200, "OK"),
|
||||
CREATED(201, "Created"),
|
||||
ACCEPTED(202, "Accepted"),
|
||||
NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information"),
|
||||
NO_CONTENT(204, "No content"),
|
||||
RESET_CONTENT(205, "Reset Content"),
|
||||
PARTIAL_CONTENT(206, "Partial Content"),
|
||||
|
||||
MULTIPLE_CHOICES(300, "Multiple Choices"),
|
||||
MOVED_PERMANENTLY(301, "Moved Permanently"),
|
||||
FOUND(302, "Found"),
|
||||
SEE_OTHER(303, "See Other"),
|
||||
NOT_MODIFIED(304, "Not Modified"),
|
||||
USE_PROXY(305, "Use Proxy"),
|
||||
SWITCH_PROXY(306, "Switch Proxy"),
|
||||
TEMPORARY_REDIRECT(307, "Temporary Redirect"),
|
||||
PERMANENT_REDIRECT(308, "Permanent Redirect"),
|
||||
TOO_MANY_REDIRECTS(310, "Too many Redirects"),
|
||||
|
||||
BAD_REQUEST(400, "Bad Request"),
|
||||
UNAUTHORIZED(401, "Unauthorized"),
|
||||
PAYMENT_REQUIRED(402, "Payment Required"),
|
||||
FORBIDDEN(403, "Forbidden"),
|
||||
NOT_FOUND(404, "Not Found"),
|
||||
METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
|
||||
NOT_ACCEPTABLE(406, "Not Acceptable"),
|
||||
PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required"),
|
||||
REQUEST_TIME_OUT(408, "Request Timeout"),
|
||||
CONFLICT(409, "Conflict"),
|
||||
GONE(410, "Gone"),
|
||||
LENGTH_REQUIRED(411, "Length Required"),
|
||||
PRECONDITION_FAILED(412, "Precondition Failed"),
|
||||
PAYLOAD_TOO_LARGE(413, "Payload Too Large"),
|
||||
URI_TOO_LONG(414, "URI Too Long"),
|
||||
UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
|
||||
RANGE_NOT_SATISFIABLE(416, "Range Not Satisfiable "),
|
||||
EXPECTATION_FAILED(417, "Expectation Failed"),
|
||||
IM_A_TEAPOT(418, "I'm a teapot"), //for fun
|
||||
MISDIRECTED_REQUEST(421, "Misdirected Request"),
|
||||
TOO_EARLY(425, "Too Early"),
|
||||
UPGRADE_REQUIRED(426, "Upgrade Required"),
|
||||
PRECONDITION_REQUIRED(428, "Precondition Required"),
|
||||
TOO_MANY_REQUESTS(429, "Too Many Requests"),
|
||||
REQUEST_HEADER_FIELDS_TOO_LARGE(431, "Request Header Fields Too Large"),
|
||||
RETRY_WITH(449, "Retry With"),
|
||||
BLOCKED_BY_WINDOWS_PARENTAL_CONTROLS(450, "Blocked by Windows Parental Controls"),
|
||||
UNAVAILABLE_FOR_LEGAL_REASONS(451, "Unavailable For Legal Reasons"),
|
||||
|
||||
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
|
||||
NOT_IMPLEMENTED(501, "Not Implemented"),
|
||||
BAD_GATEWAY(502, "Bad Gateway"),
|
||||
SERVICE_UNAVAILABLE(503, "Service Unavailable"),
|
||||
GATEWAY_TIME_OUT(504, "Gateway Timeout"),
|
||||
HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version Not Supported"),
|
||||
VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates"),
|
||||
BANDWIDTH_LIMIT_EXCEEDED(509, "Bandwidth Limit Exceeded"),
|
||||
NOT_EXTENDED(510, "Not Extended"),
|
||||
NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");
|
||||
|
||||
private final int code;
|
||||
private final String message;
|
||||
private static final Map<Integer, HttpStatus> map;
|
||||
|
||||
HttpStatus(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
static {
|
||||
map = new HashMap<>();
|
||||
for (HttpStatus v : HttpStatus.values()) {
|
||||
map.put(v.code, v);
|
||||
}
|
||||
}
|
||||
|
||||
public static HttpStatus findByCode(int i) {
|
||||
return map.get(i);
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
}
|
||||
104
src/main/java/ovh/alexisdelhaie/endpoint/http/Request.java
Normal file
104
src/main/java/ovh/alexisdelhaie/endpoint/http/Request.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import ovh.alexisdelhaie.endpoint.url.URLGenerator;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Request {
|
||||
|
||||
private final String host;
|
||||
private final String scheme;
|
||||
private final String path;
|
||||
private int port;
|
||||
private final HashMap<String, String> params;
|
||||
private final HashMap<String, String> customHeaders;
|
||||
private final String body;
|
||||
private String rawRequest;
|
||||
|
||||
Request(String host, String scheme, String path, int port,
|
||||
HashMap<String, String> params, HashMap<String, String> customHeaders, String body) {
|
||||
this.host = host;
|
||||
this.scheme = scheme;
|
||||
this.path = path;
|
||||
this.port = port;
|
||||
this.params = params;
|
||||
this.customHeaders = customHeaders;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getPathWithParams() {
|
||||
return String.format("%s%s", path, URLGenerator.generateParamsPartWithEncoding(params));
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getCustomHeaders() {
|
||||
return customHeaders;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public String getRawRequest() {
|
||||
return rawRequest;
|
||||
}
|
||||
|
||||
void setRawRequest(String r) {
|
||||
rawRequest = r;
|
||||
}
|
||||
|
||||
void setPort(int p) { this.port = p; }
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Request request = (Request) o;
|
||||
return getPort() == request.getPort() &&
|
||||
Objects.equals(getHost(), request.getHost()) &&
|
||||
Objects.equals(getScheme(), request.getScheme()) &&
|
||||
Objects.equals(getPath(), request.getPath()) &&
|
||||
Objects.equals(getParams(), request.getParams()) &&
|
||||
Objects.equals(getCustomHeaders(), request.getCustomHeaders()) &&
|
||||
Objects.equals(getBody(), request.getBody());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getHost(), getScheme(), getPath(), getPort(), getParams(), getCustomHeaders(), getBody());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("Request{");
|
||||
sb.append("scheme='").append(scheme).append('\'');
|
||||
sb.append(", host='").append(host).append('\'');
|
||||
sb.append(", port=").append(port);
|
||||
sb.append(", path='").append(path).append('\'');
|
||||
sb.append(", params=").append(params);
|
||||
sb.append(", customHeaders=").append(customHeaders);
|
||||
sb.append(", body='").append(body).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RequestBuilder {
|
||||
|
||||
public static int HTTP_PORT = 80;
|
||||
public static int HTTPS_PORT = 443;
|
||||
public static String HTTP_SCHEME = "http";
|
||||
public static String HTTPS_SCHEME = "https";
|
||||
|
||||
private String host;
|
||||
private String scheme;
|
||||
private String path;
|
||||
private int port;
|
||||
private final HashMap<String, String> params;
|
||||
private final HashMap<String, String> customHeaders;
|
||||
private String body;
|
||||
|
||||
public RequestBuilder (String url) throws MalformedURLException {
|
||||
params = new HashMap<>();
|
||||
customHeaders = new HashMap<>();
|
||||
scheme = (url.toLowerCase().startsWith("https://")) ? HTTPS_SCHEME : HTTP_SCHEME;
|
||||
url = (!url.toLowerCase().startsWith("https://")
|
||||
&& !url.toLowerCase().startsWith("http://")) ? "http://" + url : url;
|
||||
URL u = new URL(url);
|
||||
host = u.getHost();
|
||||
path = (u.getPath().isBlank()) ? "/" : u.getPath();
|
||||
port = u.getPort();
|
||||
if (port == -1) {
|
||||
port = (scheme.equals(HTTPS_SCHEME)) ? HTTPS_PORT : HTTP_PORT;
|
||||
}
|
||||
parseParams(url);
|
||||
}
|
||||
|
||||
private void parseParams(String url) {
|
||||
String[] p = url.split("[?]");
|
||||
if (p.length == 2) {
|
||||
String[] couples = p[1].split("[&]");
|
||||
for (String c: couples) {
|
||||
String[] v = c.split("[=]");
|
||||
if (v.length == 2) {
|
||||
params.put(v[0], v[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RequestBuilder setHost(String host) {
|
||||
this.host = host;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setScheme(String scheme) {
|
||||
this.scheme = scheme;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setPort(int port) {
|
||||
this.port = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setBody(String body) {
|
||||
this.body = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setPath(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setCustomHeaders(HashMap<String, String> custom) {
|
||||
this.customHeaders.clear();
|
||||
for (Map.Entry<String, String> entry : custom.entrySet()) {
|
||||
this.customHeaders.put(entry.getKey().toLowerCase(), entry.getValue());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder addCustomHeader(String key, String value) {
|
||||
this.customHeaders.put(key.toLowerCase(), value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Request build() {
|
||||
return new Request(host, scheme, path, port, params, customHeaders, body);
|
||||
}
|
||||
|
||||
}
|
||||
163
src/main/java/ovh/alexisdelhaie/endpoint/http/Response.java
Normal file
163
src/main/java/ovh/alexisdelhaie/endpoint/http/Response.java
Normal file
@@ -0,0 +1,163 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import ovh.alexisdelhaie.endpoint.http.parsers.Chunked;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Response {
|
||||
|
||||
public final static String CRLF = "\r\n";
|
||||
public final static String DOUBLE_CRLF = "\r\n\r\n";
|
||||
|
||||
private final HashMap<String, String> headers;
|
||||
private final String rawHeaders;
|
||||
private String rawResponse;
|
||||
private String body;
|
||||
private int statusCode;
|
||||
private String status;
|
||||
private final long time;
|
||||
private final Request request;
|
||||
private final boolean downgraded;
|
||||
|
||||
Response(byte[] res, long time, boolean downgraded, Request r) throws UnsupportedEncodingException {
|
||||
headers = new HashMap<>();
|
||||
rawResponse = new String(res, StandardCharsets.UTF_8);
|
||||
int crlf = rawResponse.indexOf(DOUBLE_CRLF);
|
||||
rawHeaders = rawResponse.substring(0, crlf);
|
||||
parseHeaders();
|
||||
rawResponse = new String(res, getEncoding());
|
||||
body = rawResponse.substring(crlf + DOUBLE_CRLF.length());
|
||||
this.time = time;
|
||||
request = r;
|
||||
this.downgraded = downgraded;
|
||||
parseBody();
|
||||
}
|
||||
|
||||
private void parseHeaders() {
|
||||
String[] hh = rawHeaders.split(CRLF);
|
||||
parseStatus(hh[0]);
|
||||
for (String c : hh) {
|
||||
String[] entry = c.split(":\\s");
|
||||
if (entry.length == 2) {
|
||||
headers.put(entry[0].toLowerCase(), entry[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseStatus(String l) {
|
||||
Pattern p = Pattern.compile("^(HTTP/1.1)\\s([0-9]{3})\\s(.+)$");
|
||||
Matcher m = p.matcher(l);
|
||||
if (m.matches()) {
|
||||
statusCode = Integer.parseInt(m.group(2));
|
||||
status = m.group(3);
|
||||
} else {
|
||||
p = Pattern.compile("^(HTTP/1.1)\\s([0-9]{3})?(.*)$");
|
||||
m = p.matcher(l);
|
||||
if (m.matches()) {
|
||||
statusCode = Integer.parseInt(m.group(2));
|
||||
HttpStatus httpStatus = HttpStatus.findByCode(statusCode);
|
||||
status = (httpStatus != null) ? httpStatus.getMessage() : "";
|
||||
} else {
|
||||
statusCode = -1;
|
||||
status = "Cannot get status form HTTP Response";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseBody() {
|
||||
if (headers.containsKey("transfer-encoding")) {
|
||||
if (headers.get("transfer-encoding").toLowerCase().contains("chunked")) {
|
||||
ArrayList<String> chunks = Chunked.parse(body);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (String chunk : chunks) {
|
||||
sb.append(chunk);
|
||||
}
|
||||
body = sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getEncoding() {
|
||||
Pattern p = Pattern.compile("(.+);\\s(.+)=(.+)");
|
||||
if (headers.containsKey("content-type")) {
|
||||
String value = headers.get("content-type");
|
||||
Matcher m = p.matcher(value);
|
||||
if (m.matches()) {
|
||||
return m.group(3);
|
||||
}
|
||||
}
|
||||
return StandardCharsets.UTF_8.toString();
|
||||
}
|
||||
|
||||
public HashMap<String, String> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public String getRawHeaders() {
|
||||
return rawHeaders;
|
||||
}
|
||||
|
||||
public String getRawResponse() {
|
||||
return rawResponse;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public Request getRequest() { return request; }
|
||||
|
||||
public boolean isDowngraded() {
|
||||
return downgraded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Response)) return false;
|
||||
Response response = (Response) o;
|
||||
return statusCode == response.statusCode &&
|
||||
time == response.time &&
|
||||
headers.equals(response.headers) &&
|
||||
rawHeaders.equals(response.rawHeaders) &&
|
||||
rawResponse.equals(response.rawResponse) &&
|
||||
body.equals(response.body) &&
|
||||
status.equals(response.status) &&
|
||||
request.equals(response.request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(headers, rawHeaders, rawResponse, body, statusCode, status, time, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("Response{");
|
||||
sb.append("headers=").append(headers);
|
||||
sb.append(", body='").append(body).append('\'');
|
||||
sb.append(", statusCode=").append(statusCode);
|
||||
sb.append(", status='").append(status).append('\'');
|
||||
sb.append(", time=").append(time);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package ovh.alexisdelhaie.endpoint.http.parsers;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Chunked {
|
||||
|
||||
public static ArrayList<String> parse(String body) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
try {
|
||||
body = body.strip();
|
||||
int length; int pos;
|
||||
do {
|
||||
pos = body.indexOf("\r\n");
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package ovh.alexisdelhaie.endpoint.url;
|
||||
|
||||
public enum SpecialChar {
|
||||
SPACE(' ', "%20"),
|
||||
HASH('#', "%23"),
|
||||
LEFT_BRACE('{', "%7B"),
|
||||
RIGHT_BRACE('}', "%7D"),
|
||||
LEFT_BRACKET('[', "%5B"),
|
||||
RIGHT_BRACKET(']', "%5D"),
|
||||
AT('@', "%40"),
|
||||
CIRCUMFLEX('^', "%5E"),
|
||||
SLASH('/', "%2F"),
|
||||
BACK_SLASH('\\', "%5C"),
|
||||
DOLLAR('$', "%24"),
|
||||
LEFT_CHEVRON('<', "%3C"),
|
||||
RIGHT_CHEVRON('>', "%3E"),
|
||||
PIPE('|', "%7C"),
|
||||
TILDE('~', "%7E"),
|
||||
BACK_QUOTE('`', "%60"),
|
||||
INTERROGATION('?', "%3F"),
|
||||
EQUAL('=', "%3D"),
|
||||
CR('\r', "%0D"),
|
||||
LF('\n', "%0A"),
|
||||
SEMICOLON(';', "%3B"),
|
||||
COLON(':', "%3A"),
|
||||
AND('&', "%26");
|
||||
|
||||
private char decodedChar;
|
||||
private String encodedChar;
|
||||
|
||||
SpecialChar(char decodedChar, String encodedChar) {
|
||||
this.decodedChar = decodedChar;
|
||||
this.encodedChar = encodedChar;
|
||||
}
|
||||
|
||||
public static String encodeString(String decodedString) {
|
||||
String encodedString = decodedString.replace("%", "%25");
|
||||
for (SpecialChar v : SpecialChar.values()) {
|
||||
encodedString = encodedString.replace(Character.toString(v.decodedChar), v.encodedChar);
|
||||
}
|
||||
return encodedString;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package ovh.alexisdelhaie.endpoint.url;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class URLGenerator {
|
||||
|
||||
public static final String HTTP_START = "http://";
|
||||
public static final String HTTPS_START = "https://";
|
||||
|
||||
public static String processNewUrl(HashMap<String, String> p, String url) {
|
||||
try {
|
||||
if (!url.startsWith(HTTP_START) && !url.startsWith(HTTPS_START)) {
|
||||
url = HTTP_START + url;
|
||||
}
|
||||
String newUrl = (url.startsWith(HTTPS_START)) ? HTTPS_START : HTTP_START;
|
||||
URL u = new URL(url);
|
||||
newUrl += u.getHost();
|
||||
if (u.getPort() != -1) {
|
||||
newUrl += ":" + u.getPort();
|
||||
}
|
||||
newUrl += (u.getPath().isBlank()) ? "/" : u.getPath();
|
||||
newUrl += generateParamsPart(p);
|
||||
return newUrl;
|
||||
} catch (MalformedURLException e) {
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
public static String generateParamsPartWithEncoding(HashMap<String, String> p) {
|
||||
String result = "?";
|
||||
for (Map.Entry<String, String> entry : p.entrySet()) {
|
||||
result = new StringBuilder(result)
|
||||
.append(entry.getKey())
|
||||
.append("=")
|
||||
.append(entry.getValue())
|
||||
.append("&").toString();
|
||||
}
|
||||
if (result.equals("?")) {
|
||||
result = "";
|
||||
} else if (result.endsWith("&")) {
|
||||
result = result.substring(0, result.length() - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String generateParamsPart(HashMap<String, String> p) {
|
||||
String result = "?";
|
||||
for (Map.Entry<String, String> entry : p.entrySet()) {
|
||||
String key = SpecialChar.encodeString(entry.getKey());
|
||||
String value = SpecialChar.encodeString(entry.getValue());
|
||||
result = new StringBuilder(result)
|
||||
.append(key)
|
||||
.append("=")
|
||||
.append(value)
|
||||
.append("&").toString();
|
||||
}
|
||||
if (result.equals("?")) {
|
||||
result = "";
|
||||
} else if (result.endsWith("&")) {
|
||||
result = result.substring(0, result.length() - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String addSchemaToUrl(String url) {
|
||||
if (!url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://")) {
|
||||
url = "http://" + url;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package ovh.alexisdelhaie.endpoint.utils;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class MessageDialog {
|
||||
|
||||
public static void error(String title, String message) {
|
||||
JOptionPane.showMessageDialog(new JFrame(), message, title,
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
public static void warning(String title, String message) {
|
||||
JOptionPane.showMessageDialog(new JFrame(), message, title,
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
|
||||
public static void info(String title, String message) {
|
||||
JOptionPane.showMessageDialog(new JFrame(), message, title,
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user