package net.pterodactylus.rhynodge.queries;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import net.pterodactylus.rhynodge.Query;
import net.pterodactylus.rhynodge.State;
+import net.pterodactylus.rhynodge.states.AbstractState;
import net.pterodactylus.rhynodge.states.FailedState;
import net.pterodactylus.rhynodge.states.HttpState;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.core5.ssl.SSLContexts;
import org.jspecify.annotations.Nullable;
+import static java.util.Arrays.asList;
+import static java.util.Arrays.stream;
+
/**
* {@link Query} that performs an HTTP GET request to a fixed uri.
*
*/
public class HttpQuery implements Query {
- private final String uri;
private final @Nullable String proxyHost;
private final int proxyPort;
+ private List<String> uris = new ArrayList<>();
public HttpQuery(String uri) {
this(uri, null, -1);
}
+ public HttpQuery(String uri, String... additionalUris) {
+ this(uri, null, -1, additionalUris);
+ }
+
public HttpQuery(String uri, @Nullable String proxyHost, int proxyPort) {
- this.uri = uri;
+ this(uri, proxyHost, proxyPort, new String[0]);
+ }
+
+ public HttpQuery(String uri, @Nullable String proxyHost, int proxyPort, String... additionalUris) {
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;
+ this.uris.add(uri);
+ this.uris.addAll(asList(additionalUris));
}
//
if ((proxyHost != null) && (proxyPort != -1)) {
httpClientBuilder.setProxy(new HttpHost(proxyHost, proxyPort));
}
- var get = new HttpGet(uri);
+ List<AbstractState> states = new ArrayList<>();
try (var httpClient = httpClientBuilder.build()) {
- /* make request. */
- get.addHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Ubuntu/12.04 Chromium/20.0.1132.47 Chrome/20.0.1132.47 Safari/536.11");
- var response = httpClient.execute(get);
- if (response.getCode() != HttpStatus.SC_OK) {
- return new FailedState(new IllegalStateException(String.format("Invalid HTTP Status: %d", response.getCode())));
- }
- var entity = response.getEntity();
+ for (var uri : uris) {
+ var get = new HttpGet(uri);
+ /* make request. */
+ get.addHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Ubuntu/12.04 Chromium/20.0.1132.47 Chrome/20.0.1132.47 Safari/536.11");
+ var response = httpClient.execute(get);
+ if (response.getCode() != HttpStatus.SC_OK) {
+ states.add(new FailedState(new IllegalStateException(String.format("Invalid HTTP Status: %d", response.getCode()))));
+ continue;
+ }
+ var entity = response.getEntity();
+
+ states.add(new HttpState(uri, response.getCode(), entity.getContentType(), EntityUtils.toByteArray(entity)));
- /* yay, done! */
- return new HttpState(uri, response.getCode(), entity.getContentType(), EntityUtils.toByteArray(entity));
+ }
} catch (IOException ioe1) {
- return new FailedState(ioe1);
+ states.add(new FailedState(ioe1));
}
+
+ /* collapse states */
+ return states.stream().reduce((state, newState) -> {
+ state.addState(newState);
+ return state;
+ }).get();
}
}
--- /dev/null
+package net.pterodactylus.rhynodge.queries
+
+import com.sun.net.httpserver.HttpExchange
+import com.sun.net.httpserver.HttpServer
+import java.net.InetSocketAddress
+import net.pterodactylus.rhynodge.states.HttpState
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.equalTo
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.Test
+
+class HttpQueryTest {
+
+ @Test
+ fun `http query returns content in state`() {
+ val query = HttpQuery("http://localhost:${httpServer.address.port}/url.test1")
+ val httpState = query.state() as HttpState
+ assertThat(httpState.protocolCode(), equalTo(200))
+ assertThat(httpState.contentType(), equalTo("text/test1"))
+ assertThat(httpState.content(), equalTo("first-response"))
+ }
+
+ @Test
+ fun `http query returns multiple states when multiple urls are given`() {
+ val query = HttpQuery("http://localhost:${httpServer.address.port}/url.test1", "http://localhost:${httpServer.address.port}/url.test2")
+ val httpState = query.state() as HttpState
+ assertThat(httpState.protocolCode(), equalTo(200))
+ assertThat(httpState.contentType(), equalTo("text/test1"))
+ assertThat(httpState.content(), equalTo("first-response"))
+ val secondHttpState = httpState.additionalStates.single() as HttpState
+ assertThat(secondHttpState.protocolCode(), equalTo(200))
+ assertThat(secondHttpState.contentType(), equalTo("text/test2"))
+ assertThat(secondHttpState.content(), equalTo("second-response"))
+ }
+
+ private val httpServer = HttpServer.create(InetSocketAddress("localhost", 0), 0)
+
+ init {
+ httpServer.createContext("/url.test1", sendResponse("text/test1", "first-response"))
+ httpServer.createContext("/url.test2", sendResponse("text/test2", "second-response"))
+ httpServer.start()
+ }
+
+ @AfterEach
+ fun shutdownHttpServer() {
+ httpServer.stop(0)
+ }
+
+}
+
+val sendResponse = { contentType: String, response: String ->
+ { httpExchange: HttpExchange ->
+ httpExchange.responseHeaders.add("content-type", contentType)
+ httpExchange.sendResponseHeaders(200, response.toByteArray().size.toLong())
+ httpExchange.responseBody.use {
+ it.write(response.toByteArray())
+ }
+ }
+}