Passage au socket et possibilité de sauvegarder et reouvrir une requete

This commit is contained in:
Alexis Delhaie
2019-11-04 22:02:12 +01:00
parent 75cf088512
commit 5076bdc965
11 changed files with 496 additions and 250 deletions

View File

@@ -4,6 +4,8 @@
<root id="root"> <root id="root">
<element id="archive" name="cURLing.jar"> <element id="archive" name="cURLing.jar">
<element id="module-output" name="cURLing" /> <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> </element>
</root> </root>
</artifact> </artifact>

View 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>

View 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
View File

@@ -7,16 +7,15 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="e7334e23-5435-4e6d-8822-56d062382d3d" name="Default Changelist" comment=""> <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$/.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$/cURLing.iml" beforeDir="false" afterPath="$PROJECT_DIR$/cURLing.iml" 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$/src/ovh/alexisdelhaie/curling/web/Client.java" beforeDir="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$/src/ovh/alexisdelhaie/curling/web/RequestError.java" beforeDir="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$/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.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" /> <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> </list>
@@ -38,19 +37,27 @@
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component> </component>
<component name="ProjectId" id="1SIKwW06CzaPdxUFr949xYvEVL0" /> <component name="ProjectId" id="1SIKwW06CzaPdxUFr949xYvEVL0" />
<component name="ProjectLevelVcsManager">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="PropertiesComponent"> <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.backupFiles" value="true" />
<property name="GenerateAntBuildDialog.enableUiFormCompile" value="true" /> <property name="GenerateAntBuildDialog.enableUiFormCompile" value="true" />
<property name="GenerateAntBuildDialog.forceTargetJdk" value="true" /> <property name="GenerateAntBuildDialog.forceTargetJdk" value="true" />
<property name="GenerateAntBuildDialog.generateSingleFile" value="true" /> <property name="GenerateAntBuildDialog.generateSingleFile" value="true" />
<property name="GenerateAntBuildDialog.outputFileNameProperty" value="curling" /> <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="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="UI_DESIGNER_EDITOR_MODE.UIDesignerToolWindowManager.SHOW" value="true" /> <property name="UI_DESIGNER_EDITOR_MODE.UIDesignerToolWindowManager.SHOW" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" /> <property name="WebServerToolWindowFactoryState" value="false" />
<property name="aspect.path.notification.shown" value="true" /> <property name="aspect.path.notification.shown" value="true" />
<property name="last_opened_file_path" value="$USER_HOME$/IdeaProjects" /> <property name="last_opened_file_path" value="$USER_HOME$/IdeaProjects" />
<property name="nodejs_package_manager_path" value="npm" /> <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.proportion" value="0.15" />
<property name="project.structure.side.proportion" value="0.2" /> <property name="project.structure.side.proportion" value="0.2" />
<property name="settings.editor.selected.configurable" value="preferences.lookFeel" /> <property name="settings.editor.selected.configurable" value="preferences.lookFeel" />
@@ -104,6 +111,11 @@
<workItem from="1571341924674" duration="72000" /> <workItem from="1571341924674" duration="72000" />
<workItem from="1571416842970" duration="388000" /> <workItem from="1571416842970" duration="388000" />
<workItem from="1571509954096" duration="5286000" /> <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> </task>
<servers /> <servers />
</component> </component>
@@ -123,4 +135,7 @@
</map> </map>
</option> </option>
</component> </component>
<component name="VcsManagerConfiguration">
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
</component>
</project> </project>

View File

@@ -25,5 +25,7 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <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> </component>
</module> </module>

View File

@@ -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;
}
}

View 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;
}
}

View 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;
}
}

View File

@@ -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);
}
}

View File

@@ -110,7 +110,7 @@
</component> </component>
</children> </children>
</grid> </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"/> <margin top="0" left="0" bottom="0" right="0"/>
<constraints> <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"/> <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>
<component id="10f69" class="javax.swing.JProgressBar" binding="progressBar1" default-binding="true"> <component id="10f69" class="javax.swing.JProgressBar" binding="progressBar1" default-binding="true">
<constraints> <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> </constraints>
<properties/> <properties/>
</component> </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> </children>
</grid> </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"/> <margin top="0" left="0" bottom="0" right="0"/>
<constraints> <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"/> <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>
<component id="3d3b2" class="javax.swing.JButton" binding="addAuthButton"> <component id="3d3b2" class="javax.swing.JButton" binding="addAuthButton">
<constraints> <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"> <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="329" height="30"/> <preferred-size width="197" height="30"/>
</grid> </grid>
</constraints> </constraints>
<properties> <properties>
@@ -164,6 +180,14 @@
<text value="Basic authentication"/> <text value="Basic authentication"/>
</properties> </properties>
</component> </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> </children>
</grid> </grid>
<component id="627e7" class="javax.swing.JButton" binding="xFormEncodedButton" default-binding="true"> <component id="627e7" class="javax.swing.JButton" binding="xFormEncodedButton" default-binding="true">

View File

@@ -1,19 +1,18 @@
package ovh.alexisdelhaie.curling.windows; package ovh.alexisdelhaie.curling.windows;
import ovh.alexisdelhaie.curling.dataSet.HeaderModel; 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 ovh.alexisdelhaie.curling.web.Method;
import javax.json.*;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent; import java.awt.event.ItemEvent;
import java.awt.event.ItemListener; import java.io.*;
import java.net.http.HttpClient;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class MainWindow extends JFrame { public class MainWindow extends JFrame {
@@ -36,10 +35,12 @@ public class MainWindow extends JFrame {
private JButton addAuthButton; private JButton addAuthButton;
private JButton runButton; private JButton runButton;
private JCheckBox allowInvalidSSLField; private JCheckBox allowInvalidSSLField;
private JButton clearButton;
private JButton saveButton;
private JButton openButton;
private DefaultListModel<String> model; private DefaultListModel<String> model;
private Map<String, String> headers; private Map<String, String> headers;
private Map<String, String> params;
private boolean allowInvalidSSL; private boolean allowInvalidSSL;
public MainWindow() { 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); runButton.addActionListener(this::start);
} }
@@ -111,24 +132,39 @@ public class MainWindow extends JFrame {
return; return;
} }
startLoading(true); startLoading(true);
Client c = new Client(bodyArea.getText(), headers, getMethod(), urlBuilder(), getAllowInvalidSSL()); new Thread(() -> {
CompletableFuture<String> f = c.run(); try{
new Thread(new Runnable() { String result = "";
@Override if(isHTTPS()) {
public void run() { HttpsClient c = new HttpsClient(urlBuilder(), getMethod(), bodyArea.getText(), headers, getAllowInvalidSSL());
try { if (c.isValid()) {
httpResponseArea.setText(f.get()); if(c.isDomain()) {
} catch (InterruptedException e) { result += String.format("Resolved %s : %s\n", c.getUrl().getHost(), c.getAddr().getHostAddress());
e.printStackTrace(); }
} catch (ExecutionException e) { 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(); e.printStackTrace();
} finally { } finally {
startLoading(false); startLoading(false);
} }
}
}).start(); }).start();
} }
private boolean isHTTPS() {
return httpTypeBox.getSelectedItem().equals("HTTPS");
}
private String urlBuilder() { private String urlBuilder() {
return String.format("%s://%s", ((String) httpTypeBox.getSelectedItem()).toLowerCase(), urlField.getText()); return String.format("%s://%s", ((String) httpTypeBox.getSelectedItem()).toLowerCase(), urlField.getText());
} }
@@ -146,6 +182,20 @@ public class MainWindow extends JFrame {
return Method.GET; 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) { private void setDisabledComponents(boolean b) {
urlField.setEnabled(!b); urlField.setEnabled(!b);
httpTypeBox.setEnabled(!b); httpTypeBox.setEnabled(!b);
@@ -160,7 +210,7 @@ public class MainWindow extends JFrame {
} }
private void setEnableAllowInvalidSSLField(boolean b) { private void setEnableAllowInvalidSSLField(boolean b) {
if(httpTypeBox.getSelectedItem().equals("HTTPS")) { if(isHTTPS()) {
allowInvalidSSLField.setEnabled(b); allowInvalidSSLField.setEnabled(b);
} else { } else {
allowInvalidSSLField.setEnabled(false); allowInvalidSSLField.setEnabled(false);
@@ -168,7 +218,7 @@ public class MainWindow extends JFrame {
} }
private boolean getAllowInvalidSSL() { private boolean getAllowInvalidSSL() {
if(httpTypeBox.getSelectedItem().equals("HTTPS")) { if(isHTTPS()) {
return allowInvalidSSL; return allowInvalidSSL;
} }
@@ -176,8 +226,12 @@ public class MainWindow extends JFrame {
} }
private void startLoading(boolean b) { private void startLoading(boolean b) {
try{
setDisabledComponents(b); setDisabledComponents(b);
progressBar1.setIndeterminate(b); progressBar1.setIndeterminate(b);
} catch (Exception e) {
System.out.println("Trop rapide mec !");
}
} }
public void showFrame() { public void showFrame() {
@@ -192,4 +246,69 @@ public class MainWindow extends JFrame {
int x = (int)( screen.getWidth() / 2 ) - this.getWidth() / 2; int x = (int)( screen.getWidth() / 2 ) - this.getWidth() / 2;
this.setLocation(x, y); 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();
}
}
} }