Chunk parsing algo, HTTP/1.0, fixing http status with tomcat
This commit is contained in:
@@ -1,12 +1,14 @@
|
|||||||
package ovh.alexisdelhaie.endpoint.controllers;
|
package ovh.alexisdelhaie.endpoint.controllers;
|
||||||
|
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.CheckBox;
|
import javafx.scene.control.CheckBox;
|
||||||
|
import javafx.scene.control.ChoiceBox;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.stage.Modality;
|
import javafx.stage.Modality;
|
||||||
@@ -14,8 +16,6 @@ import javafx.stage.Stage;
|
|||||||
import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties;
|
import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
|
|
||||||
public class ConfigurationController
|
public class ConfigurationController
|
||||||
{
|
{
|
||||||
@@ -27,15 +27,21 @@ public class ConfigurationController
|
|||||||
private CheckBox allowInvalidSsl;
|
private CheckBox allowInvalidSsl;
|
||||||
@FXML
|
@FXML
|
||||||
private CheckBox allowDowngrade;
|
private CheckBox allowDowngrade;
|
||||||
|
@FXML
|
||||||
|
private ChoiceBox<String> httpVersion;
|
||||||
|
|
||||||
public void setStageAndSetupListeners(Stage s) {
|
public void setStageAndSetupListeners(Stage s) {
|
||||||
primaryStage = s;
|
primaryStage = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConfigurationProperties(ConfigurationProperties properties) {
|
public void setConfigurationProperties(ConfigurationProperties properties) {
|
||||||
|
String[] versions = { "HTTP/1.1", "HTTP/1.0" };
|
||||||
|
httpVersion.setItems(FXCollections.observableArrayList(versions));
|
||||||
configurationProperties = properties;
|
configurationProperties = properties;
|
||||||
allowInvalidSsl.setSelected(properties.getBooleanProperty("allowInvalidSsl", false));
|
allowInvalidSsl.setSelected(properties.getBooleanProperty("allowInvalidSsl", false));
|
||||||
allowDowngrade.setSelected(properties.getBooleanProperty("allowDowngrade", true));
|
allowDowngrade.setSelected(properties.getBooleanProperty("allowDowngrade", true));
|
||||||
|
httpVersion.setValue(properties.getStringProperty("httpVersion", versions[0]));
|
||||||
|
httpVersion.setOnAction(this::onChoiceBoxValueChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@@ -44,13 +50,19 @@ public class ConfigurationController
|
|||||||
configurationProperties.setProperty(c.getId(), String.valueOf(c.isSelected()));
|
configurationProperties.setProperty(c.getId(), String.valueOf(c.isSelected()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void onChoiceBoxValueChanged(ActionEvent event) {
|
||||||
|
ChoiceBox<String> c = (ChoiceBox<String>) event.getSource();
|
||||||
|
configurationProperties.setProperty(c.getId(), c.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void showAboutDialog() {
|
private void showAboutDialog() {
|
||||||
try {
|
try {
|
||||||
Stage dialog = new Stage();
|
Stage dialog = new Stage();
|
||||||
Parent xml = FXMLLoader.load(getClass().getResource("about.fxml"));
|
Parent xml = FXMLLoader.load(getClass().getResource("about.fxml"));
|
||||||
dialog.initOwner(primaryStage);
|
dialog.initOwner(primaryStage);
|
||||||
dialog.setScene(new Scene(xml, 677, 365));
|
dialog.setScene(new Scene(xml, 707, 365));
|
||||||
dialog.setMaxHeight(365);
|
dialog.setMaxHeight(365);
|
||||||
dialog.setMinHeight(365);
|
dialog.setMinHeight(365);
|
||||||
dialog.setMaxWidth(707);
|
dialog.setMaxWidth(707);
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ public class Controller implements Initializable {
|
|||||||
|
|
||||||
private Stage primaryStage;
|
private Stage primaryStage;
|
||||||
private HashMap<Integer, String> requests;
|
private HashMap<Integer, String> requests;
|
||||||
|
private HashMap<Integer, String> methods;
|
||||||
|
|
||||||
private ConfigurationProperties properties;
|
private ConfigurationProperties properties;
|
||||||
|
|
||||||
@@ -91,11 +92,16 @@ public class Controller implements Initializable {
|
|||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
properties = new ConfigurationProperties();
|
properties = new ConfigurationProperties();
|
||||||
requests = new HashMap<>();
|
requests = new HashMap<>();
|
||||||
|
methods = new HashMap<>();
|
||||||
String[] method = { "GET", "POST", "HEAD", "PUT", "DELETE" };
|
String[] method = { "GET", "POST", "HEAD", "PUT", "DELETE" };
|
||||||
httpMethod.setItems(FXCollections.observableArrayList(method));
|
httpMethod.setItems(FXCollections.observableArrayList(method));
|
||||||
httpMethod.setValue(method[0]);
|
httpMethod.setValue(method[0]);
|
||||||
|
httpMethod.setOnAction(actionEvent -> httpMethodChanged());
|
||||||
tabs.getSelectionModel().selectedItemProperty().addListener(
|
tabs.getSelectionModel().selectedItemProperty().addListener(
|
||||||
(ov, t, t1) -> requestInput.setText((t1 != null) ? requests.get(t1.hashCode()) : "")
|
(ov, t, t1) -> {
|
||||||
|
requestInput.setText((t1 != null) ? requests.get(t1.hashCode()) : "");
|
||||||
|
httpMethod.setValue((t1 != null) ? methods.get(t1.hashCode()) : httpMethod.getValue());
|
||||||
|
}
|
||||||
);
|
);
|
||||||
createNewTab();
|
createNewTab();
|
||||||
}
|
}
|
||||||
@@ -111,6 +117,7 @@ public class Controller implements Initializable {
|
|||||||
|
|
||||||
TabPane options = new TabPane();
|
TabPane options = new TabPane();
|
||||||
TextArea ta = new TextArea();
|
TextArea ta = new TextArea();
|
||||||
|
ta.setEditable(false);
|
||||||
|
|
||||||
options.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
|
options.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
|
||||||
options.getTabs().addAll(params, auth, headers, body, response);
|
options.getTabs().addAll(params, auth, headers, body, response);
|
||||||
@@ -121,6 +128,7 @@ public class Controller implements Initializable {
|
|||||||
Tab tab = new Tab("untitled", sp);
|
Tab tab = new Tab("untitled", sp);
|
||||||
tab.setOnCloseRequest(arg0 -> {
|
tab.setOnCloseRequest(arg0 -> {
|
||||||
requests.remove(tab.hashCode());
|
requests.remove(tab.hashCode());
|
||||||
|
methods.remove(tab.hashCode());
|
||||||
});
|
});
|
||||||
|
|
||||||
return tab;
|
return tab;
|
||||||
@@ -209,10 +217,7 @@ public class Controller implements Initializable {
|
|||||||
Request r = new RequestBuilder(requestInput.getText())
|
Request r = new RequestBuilder(requestInput.getText())
|
||||||
.setCustomHeaders(getCustomHeaders())
|
.setCustomHeaders(getCustomHeaders())
|
||||||
.build();
|
.build();
|
||||||
HttpClient hc = new HttpClient(
|
HttpClient hc = new HttpClient(properties);
|
||||||
properties.getBooleanProperty("allowInvalidSsl", false),
|
|
||||||
properties.getBooleanProperty("allowDowngrade", true)
|
|
||||||
);
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case "GET" -> response = hc.get(r);
|
case "GET" -> response = hc.get(r);
|
||||||
case "POST" -> response = hc.post(r, getBody());
|
case "POST" -> response = hc.post(r, getBody());
|
||||||
@@ -395,6 +400,7 @@ public class Controller implements Initializable {
|
|||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
Tab t = newTab();
|
Tab t = newTab();
|
||||||
requests.put(t.hashCode(), "");
|
requests.put(t.hashCode(), "");
|
||||||
|
methods.put(t.hashCode(), httpMethod.getValue());
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
tabs.getTabs().add(t);
|
tabs.getTabs().add(t);
|
||||||
tabs.getSelectionModel().select(t);
|
tabs.getSelectionModel().select(t);
|
||||||
@@ -436,6 +442,11 @@ public class Controller implements Initializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void httpMethodChanged() {
|
||||||
|
Tab tab = tabs.getSelectionModel().getSelectedItem();
|
||||||
|
methods.put(tab.hashCode(), httpMethod.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private void requestInputOnKeyPressed() {
|
private void requestInputOnKeyPressed() {
|
||||||
Tab tab = tabs.getSelectionModel().getSelectedItem();
|
Tab tab = tabs.getSelectionModel().getSelectedItem();
|
||||||
|
|||||||
@@ -11,17 +11,13 @@
|
|||||||
<image>
|
<image>
|
||||||
<Image url="@banner.png" />
|
<Image url="@banner.png" />
|
||||||
</image></ImageView>
|
</image></ImageView>
|
||||||
<Label layoutX="537.0" layoutY="327.0" text="Version 0.1.1 (Not finished)" AnchorPane.bottomAnchor="16.0" AnchorPane.rightAnchor="16.0">
|
|
||||||
<font>
|
|
||||||
<Font size="13.0" />
|
|
||||||
</font>
|
|
||||||
</Label>
|
|
||||||
<GridPane layoutX="32.0" layoutY="123.0" prefHeight="224.0" prefWidth="348.0">
|
<GridPane layoutX="32.0" layoutY="123.0" prefHeight="224.0" prefWidth="348.0">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
@@ -32,17 +28,22 @@
|
|||||||
<Font size="13.0" />
|
<Font size="13.0" />
|
||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
<Label text="Made with Java 14.0.2 (GUI with JavaFX 15)" GridPane.rowIndex="1">
|
<Label text="Software: Java 14.0.2 (GUI: JavaFX 15)" GridPane.rowIndex="2">
|
||||||
<font>
|
<font>
|
||||||
<Font size="13.0" />
|
<Font size="13.0" />
|
||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
<Label text="Installer made with Delphi 10.3 Community" GridPane.rowIndex="2">
|
<Label text="Installer: Delphi 10.3.3 Community" GridPane.rowIndex="3">
|
||||||
<font>
|
<font>
|
||||||
<Font size="13.0" />
|
<Font size="13.0" />
|
||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
<Label text="Installer Bootstrap made with Python 3" GridPane.rowIndex="3">
|
<Label text="Installer Bootstrap: Python 3.8.5 [MSC v.1924 (AMD64)]" GridPane.rowIndex="4">
|
||||||
|
<font>
|
||||||
|
<Font size="13.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
<Label text="Version: 0.1.2 (Not finished)" GridPane.rowIndex="1">
|
||||||
<font>
|
<font>
|
||||||
<Font size="13.0" />
|
<Font size="13.0" />
|
||||||
</font>
|
</font>
|
||||||
|
|||||||
@@ -1,20 +1,28 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.control.CheckBox?>
|
||||||
<?import javafx.scene.text.*?>
|
<?import javafx.scene.control.ChoiceBox?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.layout.AnchorPane?>
|
||||||
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
<AnchorPane maxHeight="556.0" maxWidth="412.0" minHeight="556.0" minWidth="412.0" prefHeight="556.0" prefWidth="412.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ovh.alexisdelhaie.endpoint.controllers.ConfigurationController">
|
<AnchorPane maxHeight="556.0" maxWidth="412.0" minHeight="556.0" minWidth="412.0" prefHeight="556.0" prefWidth="412.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ovh.alexisdelhaie.endpoint.controllers.ConfigurationController">
|
||||||
<children>
|
<Label layoutX="20.0" layoutY="14.0" text="SSL">
|
||||||
<Label layoutX="12.0" layoutY="11.0" text="SSL">
|
<font>
|
||||||
<font>
|
<Font name="System Bold" size="12.0" />
|
||||||
<Font name="System Bold" size="12.0" />
|
</font>
|
||||||
</font>
|
</Label>
|
||||||
</Label>
|
<Label layoutX="20.0" layoutY="40.0" prefHeight="18.0" prefWidth="148.0" text="Allow invalid SSL certificate" />
|
||||||
<Label layoutX="13.0" layoutY="35.0" text="Allow invalid SSL certificate" />
|
<CheckBox fx:id="allowInvalidSsl" layoutX="381.0" layoutY="41.0" mnemonicParsing="false" onMouseClicked="#onBooleanValueChanged" AnchorPane.rightAnchor="14.199999999999989" AnchorPane.topAnchor="41.0" />
|
||||||
<CheckBox fx:id="allowInvalidSsl" layoutX="381.0" layoutY="31.0" mnemonicParsing="false" onMouseClicked="#onBooleanValueChanged" AnchorPane.rightAnchor="14.333333333333332" AnchorPane.topAnchor="32.0" />
|
<Label layoutX="20.0" layoutY="59.0" prefHeight="18.0" prefWidth="148.0" text="Downgrade when SSL failed" />
|
||||||
<Label layoutX="13.0" layoutY="64.0" text="Downgrade when SSL failed" />
|
<CheckBox fx:id="allowDowngrade" layoutX="381.0" layoutY="60.0" mnemonicParsing="false" onMouseClicked="#onBooleanValueChanged" selected="true" AnchorPane.rightAnchor="14.333333333333332" AnchorPane.topAnchor="60.0" />
|
||||||
<CheckBox fx:id="allowDowngrade" layoutX="381.0" layoutY="60.0" mnemonicParsing="false" onMouseClicked="#onBooleanValueChanged" selected="true" AnchorPane.rightAnchor="14.333333333333332" AnchorPane.topAnchor="60.0" />
|
<Button layoutX="14.0" layoutY="515.0" mnemonicParsing="false" onMouseClicked="#showAboutDialog" prefHeight="26.0" prefWidth="58.0" text="About" AnchorPane.bottomAnchor="15.0" AnchorPane.leftAnchor="14.0" />
|
||||||
<Button layoutX="14.0" layoutY="517.0" mnemonicParsing="false" onMouseClicked="#showAboutDialog" text="About" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" />
|
<Label layoutX="20.0" layoutY="97.0" prefHeight="18.0" prefWidth="72.0" text="Requests">
|
||||||
</children>
|
<font>
|
||||||
|
<Font name="System Bold" size="12.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
<Label layoutX="20.0" layoutY="126.0" prefHeight="18.0" prefWidth="72.0" text="HTTP version" />
|
||||||
|
<ChoiceBox fx:id="httpVersion" layoutX="308.0" layoutY="123.0" prefHeight="26.0" prefWidth="90.0" />
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
<Font name="Consolas" size="12.0" />
|
<Font name="Consolas" size="12.0" />
|
||||||
</font>
|
</font>
|
||||||
</TextArea>
|
</TextArea>
|
||||||
<Label text="Sended request" GridPane.columnIndex="4" GridPane.rowIndex="4" />
|
<Label text="Sent request" GridPane.columnIndex="4" GridPane.rowIndex="4" />
|
||||||
<GridPane fx:id="downgraded_indicator" visible="false" GridPane.columnIndex="4" GridPane.rowIndex="1">
|
<GridPane fx:id="downgraded_indicator" visible="false" GridPane.columnIndex="4" GridPane.rowIndex="1">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="382.0" minWidth="10.0" prefWidth="30.0" />
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="382.0" minWidth="10.0" prefWidth="30.0" />
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package ovh.alexisdelhaie.endpoint.http;
|
package ovh.alexisdelhaie.endpoint.http;
|
||||||
|
|
||||||
|
import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties;
|
||||||
|
|
||||||
import javax.net.ssl.*;
|
import javax.net.ssl.*;
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@@ -18,15 +20,19 @@ public class HttpClient {
|
|||||||
|
|
||||||
public final static String CRLF = "\r\n";
|
public final static String CRLF = "\r\n";
|
||||||
public final static int DEFAULT_TIMEOUT = 10000;
|
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.1";
|
||||||
|
|
||||||
private final boolean allowInvalidSsl;
|
private final boolean allowInvalidSsl;
|
||||||
private final boolean allowDowngrade;
|
private final boolean allowDowngrade;
|
||||||
|
private final String httpVersion;
|
||||||
private boolean downgraded;
|
private boolean downgraded;
|
||||||
|
|
||||||
public HttpClient() { this(false, true); }
|
public HttpClient(ConfigurationProperties props) {
|
||||||
public HttpClient(boolean allowInvalidSsl, boolean allowDowngrade) {
|
this.allowInvalidSsl = props.getBooleanProperty("allowInvalidSsl", DEFAULT_ALLOW_INVALID_SSL);
|
||||||
this.allowInvalidSsl = allowInvalidSsl;
|
this.allowDowngrade = props.getBooleanProperty("allowDowngrade", DEFAULT_ALLOW_DOWNGRADE);
|
||||||
this.allowDowngrade = allowDowngrade;
|
this.httpVersion = props.getStringProperty("httpVersion", DEFAULT_HTTP_VERSION);
|
||||||
this.downgraded = false;
|
this.downgraded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,8 +145,9 @@ public class HttpClient {
|
|||||||
String path = (r.getParams().isEmpty()) ?
|
String path = (r.getParams().isEmpty()) ?
|
||||||
r.getPath() : r.getPathWithParams();
|
r.getPath() : r.getPathWithParams();
|
||||||
final StringBuilder sb = new StringBuilder(method).append(" ").append(path)
|
final StringBuilder sb = new StringBuilder(method).append(" ").append(path)
|
||||||
.append(" HTTP/1.1").append(CRLF);
|
.append(" ").append(httpVersion).append(CRLF);
|
||||||
sb.append("host: ").append(r.getHost()).append(":").append(r.getPort()).append(CRLF);
|
sb.append("host: ").append(r.getHost()).append(":").append(r.getPort()).append(CRLF);
|
||||||
|
|
||||||
sb.append("connection: close").append(CRLF);
|
sb.append("connection: close").append(CRLF);
|
||||||
if (!custom.containsKey("accept")) {
|
if (!custom.containsKey("accept")) {
|
||||||
sb.append("accept: */*").append(CRLF);
|
sb.append("accept: */*").append(CRLF);
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package ovh.alexisdelhaie.endpoint.http;
|
package ovh.alexisdelhaie.endpoint.http;
|
||||||
|
|
||||||
|
import ovh.alexisdelhaie.endpoint.http.parsers.Chunked;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@@ -15,7 +18,7 @@ public class Response {
|
|||||||
private final HashMap<String, String> headers;
|
private final HashMap<String, String> headers;
|
||||||
private final String rawHeaders;
|
private final String rawHeaders;
|
||||||
private String rawResponse;
|
private String rawResponse;
|
||||||
private final String body;
|
private String body;
|
||||||
private int statusCode;
|
private int statusCode;
|
||||||
private String status;
|
private String status;
|
||||||
private final long time;
|
private final long time;
|
||||||
@@ -33,6 +36,7 @@ public class Response {
|
|||||||
this.time = time;
|
this.time = time;
|
||||||
request = r;
|
request = r;
|
||||||
this.downgraded = downgraded;
|
this.downgraded = downgraded;
|
||||||
|
parseBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseHeaders() {
|
private void parseHeaders() {
|
||||||
@@ -53,7 +57,7 @@ public class Response {
|
|||||||
statusCode = Integer.parseInt(m.group(2));
|
statusCode = Integer.parseInt(m.group(2));
|
||||||
status = m.group(3);
|
status = m.group(3);
|
||||||
} else {
|
} else {
|
||||||
p = Pattern.compile("^(HTTP/1.1)\\s([0-9]{3})$");
|
p = Pattern.compile("^(HTTP/1.1)\\s([0-9]{3})?(.*)$");
|
||||||
m = p.matcher(l);
|
m = p.matcher(l);
|
||||||
if (m.matches()) {
|
if (m.matches()) {
|
||||||
statusCode = Integer.parseInt(m.group(2));
|
statusCode = Integer.parseInt(m.group(2));
|
||||||
@@ -66,6 +70,19 @@ public class 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() {
|
private String getEncoding() {
|
||||||
Pattern p = Pattern.compile("(.+);\\s(.+)=(.+)");
|
Pattern p = Pattern.compile("(.+);\\s(.+)=(.+)");
|
||||||
if (headers.containsKey("content-type")) {
|
if (headers.containsKey("content-type")) {
|
||||||
|
|||||||
25
src/ovh/alexisdelhaie/endpoint/http/parsers/Chunked.java
Normal file
25
src/ovh/alexisdelhaie/endpoint/http/parsers/Chunked.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user