Passage au socket et possibilité de sauvegarder et reouvrir une requete
This commit is contained in:
2
.idea/artifacts/cURLing_jar.xml
generated
2
.idea/artifacts/cURLing_jar.xml
generated
@@ -4,6 +4,8 @@
|
||||
<root id="root">
|
||||
<element id="archive" name="cURLing.jar">
|
||||
<element id="module-output" name="cURLing" />
|
||||
<element id="library" level="project" name="javax.json:javax.json-api:1.0" />
|
||||
<element id="library" level="project" name="org.glassfish:javax.json:1.0" />
|
||||
</element>
|
||||
</root>
|
||||
</artifact>
|
||||
|
||||
10
.idea/libraries/javax_json_javax_json_api_1_0.xml
generated
Normal file
10
.idea/libraries/javax_json_javax_json_api_1_0.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<component name="libraryTable">
|
||||
<library name="javax.json:javax.json-api:1.0" type="repository">
|
||||
<properties maven-id="javax.json:javax.json-api:1.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/javax/json/javax.json-api/1.0/javax.json-api-1.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
10
.idea/libraries/org_glassfish_javax_json_1_0.xml
generated
Normal file
10
.idea/libraries/org_glassfish_javax_json_1_0.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<component name="libraryTable">
|
||||
<library name="org.glassfish:javax.json:1.0" type="repository">
|
||||
<properties maven-id="org.glassfish:javax.json:1.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/glassfish/javax.json/1.0/javax.json-1.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
35
.idea/workspace.xml
generated
35
.idea/workspace.xml
generated
@@ -7,16 +7,15 @@
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="e7334e23-5435-4e6d-8822-56d062382d3d" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/javax_json_javax_json_api_1_0.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/libraries/org_glassfish_javax_json_1_0.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/web/HttpClient.java" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/web/HttpsClient.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/artifacts/cURLing_jar.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/artifacts/cURLing_jar.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/Runtime.class" beforeDir="false" afterPath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/Runtime.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/web/Client$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/web/Client$1.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/web/Client.class" beforeDir="false" afterPath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/web/Client.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/windows/FormEncodedDialog.class" beforeDir="false" afterPath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/windows/FormEncodedDialog.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/windows/MainWindow$1.class" beforeDir="false" afterPath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/windows/MainWindow$1.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/windows/MainWindow.class" beforeDir="false" afterPath="$PROJECT_DIR$/bin/ovh/alexisdelhaie/curling/windows/MainWindow.class" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/Runtime.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/Runtime.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/web/Client.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/web/Client.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/windows/FormEncodedDialog.form" beforeDir="false" afterPath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/windows/FormEncodedDialog.form" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/cURLing.iml" beforeDir="false" afterPath="$PROJECT_DIR$/cURLing.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/web/Client.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/web/RequestError.java" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/windows/MainWindow.form" beforeDir="false" afterPath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/windows/MainWindow.form" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/windows/MainWindow.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/ovh/alexisdelhaie/curling/windows/MainWindow.java" afterDir="false" />
|
||||
</list>
|
||||
@@ -38,19 +37,27 @@
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectId" id="1SIKwW06CzaPdxUFr949xYvEVL0" />
|
||||
<component name="ProjectLevelVcsManager">
|
||||
<ConfirmationsSetting value="2" id="Add" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="ASKED_ADD_EXTERNAL_FILES" value="true" />
|
||||
<property name="Downloaded.Files.Path.Enabled" value="false" />
|
||||
<property name="GenerateAntBuildDialog.backupFiles" value="true" />
|
||||
<property name="GenerateAntBuildDialog.enableUiFormCompile" value="true" />
|
||||
<property name="GenerateAntBuildDialog.forceTargetJdk" value="true" />
|
||||
<property name="GenerateAntBuildDialog.generateSingleFile" value="true" />
|
||||
<property name="GenerateAntBuildDialog.outputFileNameProperty" value="curling" />
|
||||
<property name="Repository.Attach.Annotations" value="false" />
|
||||
<property name="Repository.Attach.JavaDocs" value="false" />
|
||||
<property name="Repository.Attach.Sources" value="false" />
|
||||
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
|
||||
<property name="UI_DESIGNER_EDITOR_MODE.UIDesignerToolWindowManager.SHOW" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="aspect.path.notification.shown" value="true" />
|
||||
<property name="last_opened_file_path" value="$USER_HOME$/IdeaProjects" />
|
||||
<property name="nodejs_package_manager_path" value="npm" />
|
||||
<property name="project.structure.last.edited" value="Artifacts" />
|
||||
<property name="project.structure.last.edited" value="Modules" />
|
||||
<property name="project.structure.proportion" value="0.15" />
|
||||
<property name="project.structure.side.proportion" value="0.2" />
|
||||
<property name="settings.editor.selected.configurable" value="preferences.lookFeel" />
|
||||
@@ -104,6 +111,11 @@
|
||||
<workItem from="1571341924674" duration="72000" />
|
||||
<workItem from="1571416842970" duration="388000" />
|
||||
<workItem from="1571509954096" duration="5286000" />
|
||||
<workItem from="1571516613481" duration="114000" />
|
||||
<workItem from="1572296864463" duration="1673000" />
|
||||
<workItem from="1572539831653" duration="7030000" />
|
||||
<workItem from="1572608101577" duration="843000" />
|
||||
<workItem from="1572891246032" duration="9777000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
@@ -123,4 +135,7 @@
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -25,5 +25,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="org.glassfish:javax.json:1.0" level="project" />
|
||||
<orderEntry type="library" name="javax.json:javax.json-api:1.0" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,178 +0,0 @@
|
||||
package ovh.alexisdelhaie.curling.web;
|
||||
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class Client {
|
||||
|
||||
public static long TIMEOUT = 10000;
|
||||
|
||||
private String body;
|
||||
private Map<String, String> headers;
|
||||
private Method method;
|
||||
private String url;
|
||||
private long timeout;
|
||||
private boolean allowInvalidSSL;
|
||||
private RequestError error;
|
||||
|
||||
private String log;
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public Map<String, String> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public RequestError getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public void setHeaders(Map<String, String> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
public void setMethod(Method method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public Client(String body, Map<String, String> headers, Method method, String url) {
|
||||
this(body, headers, method, url, false, TIMEOUT);
|
||||
}
|
||||
|
||||
public Client(String body, Map<String, String> headers, Method method, String url, boolean allowInvalidSSL) {
|
||||
this(body, headers, method, url, allowInvalidSSL, TIMEOUT);
|
||||
}
|
||||
|
||||
public Client(String body, Map<String, String> headers, Method method, String url, boolean allowInvalidSSL, long timeout) {
|
||||
this.body = body;
|
||||
this.headers = headers;
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
this.timeout = timeout;
|
||||
this.allowInvalidSSL = allowInvalidSSL;
|
||||
this.log = "";
|
||||
}
|
||||
|
||||
public CompletableFuture<String> run() {
|
||||
try {
|
||||
HttpClient httpClient = getClient();
|
||||
HttpRequest request = requestBuilder();
|
||||
|
||||
if (request != null) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
String result = String.format("%s\n---- HTTP Response ----\n", log);
|
||||
try {
|
||||
HttpResponse r = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
result += String.format("> Status : %d\n", r.statusCode());
|
||||
for(Map.Entry<String, List<String>> header : r.headers().map().entrySet()) {
|
||||
result += String.format("> %s: ", header.getKey());
|
||||
for(String s : header.getValue()) {
|
||||
result += s;
|
||||
}
|
||||
result += "\n";
|
||||
}
|
||||
result += String.format("\n---- Body ----\n%s", (String)r.body());
|
||||
} catch (IOException e) {
|
||||
result += String.format("\n/!\\ %s", e.getMessage());
|
||||
error = new RequestError(e.getMessage(), e.getLocalizedMessage(), e);
|
||||
} catch (InterruptedException e) {
|
||||
result += String.format("\n/!\\ %s", e.getMessage());
|
||||
error = new RequestError("Thread interrupted", "The action was stopped (by you maybe)", e);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
} else {
|
||||
error = new RequestError("Requete invalide", "La requete est vide");
|
||||
}
|
||||
|
||||
} catch (URISyntaxException e) {
|
||||
error = new RequestError("URL invalide", "Le format de l'URL est invalide", e);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
} catch (KeyManagementException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private HttpRequest requestBuilder() throws URISyntaxException {
|
||||
log += "< ";
|
||||
HttpRequest.Builder b;
|
||||
b = HttpRequest.newBuilder(new URI(url));
|
||||
switch (method) {
|
||||
case GET: b.GET(); log += "GET"; break;
|
||||
case POST: b.POST(HttpRequest.BodyPublishers.ofString(body)); log += "POST"; break;
|
||||
case PUT: b.PUT(HttpRequest.BodyPublishers.ofString(body)); log += "PUT"; break;
|
||||
case DELETE: b.DELETE(); log += "DELETE"; break;
|
||||
}
|
||||
log += String.format(" %s\n", url);
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
b.setHeader(header.getKey(), header.getValue());
|
||||
log += String.format("< %s: %s\n", header.getKey(), header.getValue());
|
||||
}
|
||||
if(method == Method.POST || method == Method.PUT) {
|
||||
log += String.format("\n---- Body ----\n%s", body);
|
||||
}
|
||||
b.timeout(Duration.ofMillis(timeout));
|
||||
return b.build();
|
||||
}
|
||||
|
||||
private HttpClient getClient() throws KeyManagementException, NoSuchAlgorithmException {
|
||||
HttpClient.Builder b = HttpClient.newBuilder();
|
||||
b.followRedirects(HttpClient.Redirect.NEVER);
|
||||
b.version(HttpClient.Version.HTTP_2);
|
||||
if(allowInvalidSSL) {
|
||||
b.sslContext(getInvalidSSLConfig());
|
||||
}
|
||||
return b.build();
|
||||
}
|
||||
|
||||
private SSLContext getInvalidSSLConfig() throws NoSuchAlgorithmException, KeyManagementException {
|
||||
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());
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
169
src/ovh/alexisdelhaie/curling/web/HttpClient.java
Normal file
169
src/ovh/alexisdelhaie/curling/web/HttpClient.java
Normal file
@@ -0,0 +1,169 @@
|
||||
package ovh.alexisdelhaie.curling.web;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.Map;
|
||||
|
||||
public class HttpClient {
|
||||
|
||||
public static String CRLF = "\r\n";
|
||||
public static int DEFAULT_PORT = 80;
|
||||
public static int DEFAULT_TIMEOUT = 10000;
|
||||
|
||||
protected InetAddress addr;
|
||||
protected URL url;
|
||||
protected boolean valid;
|
||||
protected Method method;
|
||||
protected Map<String, String> headers;
|
||||
protected String body;
|
||||
|
||||
public HttpClient(String u, Method method, String body, Map<String, String> headers) {
|
||||
try {
|
||||
URL url = new URL(u);
|
||||
addr = resolve(url.getHost());
|
||||
this.url = url;
|
||||
this.headers = headers;
|
||||
this.method = method;
|
||||
this.body = body;
|
||||
valid = true;
|
||||
} catch (UnknownHostException | MalformedURLException e) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public InetAddress getAddr() {
|
||||
return addr;
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public Map<String, String> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public boolean isDomain() {
|
||||
if(valid) {
|
||||
String comparable = url.getHost();
|
||||
if(comparable.contains(":")) {
|
||||
comparable = comparable.split(":")[0];
|
||||
}
|
||||
return !(comparable.equals(addr.getHostAddress()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String run() {
|
||||
String result = "";
|
||||
Socket s = null;
|
||||
if (valid) {
|
||||
String request = String.format("%s%s%s", buildHeader(), CRLF, body);
|
||||
result += String.format("--- Request ---\n%s", request);
|
||||
BufferedOutputStream bos = null;
|
||||
BufferedInputStream bis = null;
|
||||
try {
|
||||
s = new Socket(addr, getPort());
|
||||
s.setKeepAlive(false);
|
||||
s.setSoTimeout(DEFAULT_TIMEOUT);
|
||||
if (s.isConnected()) {
|
||||
bos = new BufferedOutputStream(s.getOutputStream());
|
||||
bos.write(request.getBytes());
|
||||
bos.flush();
|
||||
bis = new BufferedInputStream(s.getInputStream());
|
||||
byte[] b = bis.readAllBytes();
|
||||
result += String.format("\n\n--- Response ---\n%s", new String(b, "UTF-8"));
|
||||
} else {
|
||||
result += "/!\\ Not connected";
|
||||
}
|
||||
} catch (IOException io) {
|
||||
result += String.format("\n\n /!\\ %s", io.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if(bos != null) {
|
||||
bos.close();
|
||||
}
|
||||
if(bis != null) {
|
||||
bis.close();
|
||||
}
|
||||
if(s != null && s.isConnected()) {
|
||||
s.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
result += String.format("\n\n /!\\ %s", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private InetAddress resolve(String host) throws UnknownHostException {
|
||||
InetAddress[] addrs = InetAddress.getAllByName(host);
|
||||
return addrs[0];
|
||||
}
|
||||
|
||||
protected String buildHeader() {
|
||||
String result = String.format("%s %s HTTP/1.1%s", method.toString(), getPath(), CRLF);
|
||||
result += getHostHeader();
|
||||
result += String.format("Accept: */*%s", CRLF);
|
||||
result += String.format("Connection: close%s", CRLF);
|
||||
if(method == Method.POST || method == Method.PUT) {
|
||||
result += String.format("Content-Length: %d%s", body.length(), CRLF);
|
||||
}
|
||||
if(!headers.containsKey("User-Agent")) {
|
||||
result += String.format("User-Agent: cURLing/2.0 %s%s", System.getProperty("os.name"), CRLF);
|
||||
}
|
||||
if(headers != null) {
|
||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
if (isAuthorizedHeader(entry.getKey())) {
|
||||
result += String.format("%s: %s%s", entry.getKey(), entry.getValue(), CRLF);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isAuthorizedHeader(String key) {
|
||||
boolean result = true;
|
||||
if (key.toUpperCase().equals("ACCEPT") || key.toUpperCase().equals("HOST") || key.toUpperCase().equals("CONNECTION")) {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
private String getPath() {
|
||||
if(url.getPath().isBlank()) {
|
||||
return "/";
|
||||
}
|
||||
return url.getPath();
|
||||
}
|
||||
|
||||
private String getHostHeader() {
|
||||
String result;
|
||||
if (url.getPort() != -1) {
|
||||
result = String.format("Host: %s:%d%s", url.getHost(), url.getPort(), CRLF);
|
||||
} else {
|
||||
result = String.format("Host: %s%s", url.getHost(), CRLF);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected int getPort() {
|
||||
if(url.getPort() != -1) {
|
||||
return url.getPort();
|
||||
}
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
}
|
||||
107
src/ovh/alexisdelhaie/curling/web/HttpsClient.java
Normal file
107
src/ovh/alexisdelhaie/curling/web/HttpsClient.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package ovh.alexisdelhaie.curling.web;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.security.*;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Map;
|
||||
|
||||
public class HttpsClient extends HttpClient {
|
||||
|
||||
public static int DEFAULT_PORT = 443;
|
||||
|
||||
private boolean badSSL;
|
||||
|
||||
public HttpsClient(String u, Method method, String body, Map<String, String> headers, boolean allowBadSSL) {
|
||||
super(u, method, body, headers);
|
||||
badSSL = allowBadSSL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String run() {
|
||||
String result = "";
|
||||
SSLSocket s = null;
|
||||
if (valid) {
|
||||
String request = String.format("%s%s%s", buildHeader(), CRLF, body);
|
||||
result += String.format("--- Request ---\n%s", request);
|
||||
BufferedOutputStream bos = null;
|
||||
BufferedInputStream bis = null;
|
||||
try {
|
||||
s = getSocket(addr, getPort());
|
||||
s.setKeepAlive(false);
|
||||
s.setSoTimeout(DEFAULT_TIMEOUT);
|
||||
if (s.isConnected()) {
|
||||
bos = new BufferedOutputStream(s.getOutputStream());
|
||||
bos.write(request.getBytes());
|
||||
bos.flush();
|
||||
bis = new BufferedInputStream(s.getInputStream());
|
||||
byte[] b = bis.readAllBytes();
|
||||
result += String.format("\n\n--- Response ---\n%s", new String(b, "UTF-8"));
|
||||
} else {
|
||||
result += "/!\\ Not connected";
|
||||
}
|
||||
} catch (IOException io) {
|
||||
result += String.format("\n\n /!\\ %s", io.getMessage());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
result += String.format("\n\n /!\\ %s", e.getMessage());
|
||||
} catch (KeyManagementException e) {
|
||||
result += String.format("\n\n /!\\ %s", e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if(bos != null) {
|
||||
bos.close();
|
||||
}
|
||||
if(bis != null) {
|
||||
bis.close();
|
||||
}
|
||||
if(s != null && s.isConnected()) {
|
||||
s.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
result += String.format("\n\n /!\\ %s", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private SSLSocket getSocket(InetAddress addr, int port) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
SSLSocketFactory factory = null;
|
||||
if(badSSL) {
|
||||
factory = getInvalidSSLConfig().getSocketFactory();
|
||||
} else {
|
||||
factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
|
||||
}
|
||||
SSLSocket s = (SSLSocket) factory.createSocket(addr, port);
|
||||
s.startHandshake();
|
||||
return s;
|
||||
}
|
||||
|
||||
private SSLContext getInvalidSSLConfig() throws NoSuchAlgorithmException, KeyManagementException {
|
||||
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());
|
||||
return sc;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPort() {
|
||||
int port = super.getPort();
|
||||
if (port == super.DEFAULT_PORT) {
|
||||
return this.DEFAULT_PORT;
|
||||
}
|
||||
return port;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package ovh.alexisdelhaie.curling.web;
|
||||
|
||||
public class RequestError {
|
||||
|
||||
private String title;
|
||||
private String message;
|
||||
private Exception e;
|
||||
|
||||
public RequestError(String title, String message, Exception exception) {
|
||||
this.title = title;
|
||||
this.message = message;
|
||||
this.e = exception;
|
||||
}
|
||||
|
||||
public RequestError(String title, String message) {
|
||||
this(title, message, null);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Exception getException() {
|
||||
return e;
|
||||
}
|
||||
|
||||
public boolean hasException() {
|
||||
return (e != null);
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="37c3f" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="37c3f" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="6" column="4" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -130,13 +130,29 @@
|
||||
</component>
|
||||
<component id="10f69" class="javax.swing.JProgressBar" binding="progressBar1" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="553f1" class="javax.swing.JButton" binding="saveButton">
|
||||
<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="Save"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="1bf20" class="javax.swing.JButton" binding="openButton">
|
||||
<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="Open"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="a2fab" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="a2fab" layout-manager="GridLayoutManager" row-count="1" column-count="4" 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="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
@@ -155,8 +171,8 @@
|
||||
</component>
|
||||
<component id="3d3b2" class="javax.swing.JButton" binding="addAuthButton">
|
||||
<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">
|
||||
<preferred-size width="329" height="30"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="197" height="30"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
@@ -164,6 +180,14 @@
|
||||
<text value="Basic authentication"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="7c4b8" class="javax.swing.JButton" binding="clearButton">
|
||||
<constraints>
|
||||
<grid row="0" column="3" 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="Clear"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<component id="627e7" class="javax.swing.JButton" binding="xFormEncodedButton" default-binding="true">
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package ovh.alexisdelhaie.curling.windows;
|
||||
|
||||
import ovh.alexisdelhaie.curling.dataSet.HeaderModel;
|
||||
import ovh.alexisdelhaie.curling.web.Client;
|
||||
import ovh.alexisdelhaie.curling.web.HttpClient;
|
||||
import ovh.alexisdelhaie.curling.web.HttpsClient;
|
||||
import ovh.alexisdelhaie.curling.web.Method;
|
||||
|
||||
import javax.json.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.net.http.HttpClient;
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class MainWindow extends JFrame {
|
||||
|
||||
@@ -36,10 +35,12 @@ public class MainWindow extends JFrame {
|
||||
private JButton addAuthButton;
|
||||
private JButton runButton;
|
||||
private JCheckBox allowInvalidSSLField;
|
||||
private JButton clearButton;
|
||||
private JButton saveButton;
|
||||
private JButton openButton;
|
||||
|
||||
private DefaultListModel<String> model;
|
||||
private Map<String, String> headers;
|
||||
private Map<String, String> params;
|
||||
private boolean allowInvalidSSL;
|
||||
|
||||
public MainWindow() {
|
||||
@@ -93,6 +94,26 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
});
|
||||
|
||||
clearButton.addActionListener((event) -> {
|
||||
clear();
|
||||
});
|
||||
|
||||
saveButton.addActionListener((event) -> {
|
||||
try {
|
||||
save();
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(this, e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
openButton.addActionListener((event) -> {
|
||||
try {
|
||||
open();
|
||||
} catch (IOException e) {
|
||||
JOptionPane.showMessageDialog(this, e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
runButton.addActionListener(this::start);
|
||||
}
|
||||
|
||||
@@ -111,24 +132,39 @@ public class MainWindow extends JFrame {
|
||||
return;
|
||||
}
|
||||
startLoading(true);
|
||||
Client c = new Client(bodyArea.getText(), headers, getMethod(), urlBuilder(), getAllowInvalidSSL());
|
||||
CompletableFuture<String> f = c.run();
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new Thread(() -> {
|
||||
try{
|
||||
httpResponseArea.setText(f.get());
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ExecutionException e) {
|
||||
String result = "";
|
||||
if(isHTTPS()) {
|
||||
HttpsClient c = new HttpsClient(urlBuilder(), getMethod(), bodyArea.getText(), headers, getAllowInvalidSSL());
|
||||
if (c.isValid()) {
|
||||
if(c.isDomain()) {
|
||||
result += String.format("Resolved %s : %s\n", c.getUrl().getHost(), c.getAddr().getHostAddress());
|
||||
}
|
||||
result += c.run();
|
||||
}
|
||||
} else {
|
||||
HttpClient c = new HttpClient(urlBuilder(), getMethod(), bodyArea.getText(), headers);
|
||||
if (c.isValid()) {
|
||||
if(c.isDomain()) {
|
||||
result += String.format("Resolved %s : %s\n", c.getUrl().getHost(), c.getAddr().getHostAddress());
|
||||
}
|
||||
result += c.run();
|
||||
}
|
||||
}
|
||||
httpResponseArea.setText(result);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
startLoading(false);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private boolean isHTTPS() {
|
||||
return httpTypeBox.getSelectedItem().equals("HTTPS");
|
||||
}
|
||||
|
||||
private String urlBuilder() {
|
||||
return String.format("%s://%s", ((String) httpTypeBox.getSelectedItem()).toLowerCase(), urlField.getText());
|
||||
}
|
||||
@@ -146,6 +182,20 @@ public class MainWindow extends JFrame {
|
||||
return Method.GET;
|
||||
}
|
||||
|
||||
private boolean methodExist(String s) {
|
||||
boolean result = false;
|
||||
for(Method m : Method.values()) {
|
||||
if(s.equals(m.toString())) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean httpExist(String s) {
|
||||
return (s.equals("HTTP") || s.equals("HTTPS"));
|
||||
}
|
||||
|
||||
private void setDisabledComponents(boolean b) {
|
||||
urlField.setEnabled(!b);
|
||||
httpTypeBox.setEnabled(!b);
|
||||
@@ -160,7 +210,7 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
private void setEnableAllowInvalidSSLField(boolean b) {
|
||||
if(httpTypeBox.getSelectedItem().equals("HTTPS")) {
|
||||
if(isHTTPS()) {
|
||||
allowInvalidSSLField.setEnabled(b);
|
||||
} else {
|
||||
allowInvalidSSLField.setEnabled(false);
|
||||
@@ -168,7 +218,7 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
private boolean getAllowInvalidSSL() {
|
||||
if(httpTypeBox.getSelectedItem().equals("HTTPS")) {
|
||||
if(isHTTPS()) {
|
||||
return allowInvalidSSL;
|
||||
}
|
||||
|
||||
@@ -176,8 +226,12 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
private void startLoading(boolean b) {
|
||||
try{
|
||||
setDisabledComponents(b);
|
||||
progressBar1.setIndeterminate(b);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Trop rapide mec !");
|
||||
}
|
||||
}
|
||||
|
||||
public void showFrame() {
|
||||
@@ -192,4 +246,69 @@ public class MainWindow extends JFrame {
|
||||
int x = (int)( screen.getWidth() / 2 ) - this.getWidth() / 2;
|
||||
this.setLocation(x, y);
|
||||
}
|
||||
|
||||
private void save() throws IOException {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setDialogTitle("Specify a file to save");
|
||||
int userSelection = fileChooser.showSaveDialog(this);
|
||||
if (userSelection == JFileChooser.APPROVE_OPTION) {
|
||||
File fileToSave = fileChooser.getSelectedFile();
|
||||
JsonArrayBuilder a = Json.createArrayBuilder();
|
||||
for(Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
a.add(Json.createObjectBuilder()
|
||||
.add("key", entry.getKey())
|
||||
.add("value", entry.getValue())
|
||||
.build());
|
||||
}
|
||||
JsonObject o = Json.createObjectBuilder()
|
||||
.add("url", urlField.getText())
|
||||
.add("method", getMethod().toString())
|
||||
.add("http", (String)httpTypeBox.getSelectedItem())
|
||||
.add("body", bodyArea.getText())
|
||||
.add("headers", a.build())
|
||||
.build();
|
||||
FileWriter fw = new FileWriter(fileToSave);
|
||||
fw.write(o.toString());
|
||||
fw.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
headers.clear();
|
||||
updateHeaderList();
|
||||
bodyArea.setText("");
|
||||
urlField.setText("");
|
||||
httpResponseArea.setText("");
|
||||
}
|
||||
|
||||
private void open() throws IOException {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setDialogTitle("Specify a file to open");
|
||||
int userSelection = fileChooser.showSaveDialog(this);
|
||||
if (userSelection == JFileChooser.APPROVE_OPTION) {
|
||||
File fileToRead = fileChooser.getSelectedFile();
|
||||
FileInputStream fis = new FileInputStream(fileToRead);
|
||||
byte[] data = new byte[(int) fileToRead.length()];
|
||||
fis.read(data);
|
||||
fis.close();
|
||||
String json = new String(data, "UTF-8");
|
||||
JsonReader reader = Json.createReader(new StringReader(json));
|
||||
JsonObject o = reader.readObject();
|
||||
clear();
|
||||
urlField.setText(o.getString("url"));
|
||||
if(methodExist(o.getString("method"))) {
|
||||
methodBox.setSelectedItem(o.getString("method"));
|
||||
}
|
||||
if(httpExist(o.getString("http"))) {
|
||||
httpTypeBox.setSelectedItem(o.getString("http"));
|
||||
}
|
||||
bodyArea.setText(o.getString("body"));
|
||||
JsonArray a = o.getJsonArray("headers");
|
||||
for (JsonValue v : a) {
|
||||
JsonObject vo = (JsonObject) v;
|
||||
headers.put(vo.getString("key"), vo.getString("value"));
|
||||
}
|
||||
updateHeaderList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user