All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.athaydes.rawhttp.reqinedit.ReqInEditUnit Maven / Gradle / Ivy

There is a newer version: 0.5.0
Show newest version
package com.athaydes.rawhttp.reqinedit;

import com.athaydes.rawhttp.reqinedit.js.JsEnvironment;
import rawhttp.cookies.ClientOptionsWithCookies;
import rawhttp.core.RawHttp;
import rawhttp.core.RawHttpOptions;
import rawhttp.core.RawHttpRequest;
import rawhttp.core.RawHttpResponse;
import rawhttp.core.body.BytesBody;
import rawhttp.core.client.RawHttpClient;
import rawhttp.core.client.TcpRawHttpClient;

import javax.script.ScriptException;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

/**
 * A unit representing a single HTTP file.
 * 

* A HTTP file may contain one or more HTTP requests, as well as response handlers and references to other * files (to either populate request bodies or store responses). These references are resolved at runtime * (i.e. when the {@link ReqInEditUnit#run(List)} or {@link ReqInEditUnit#run(ReqInEditEntry)} methods are called. *

* This class can run {@link ReqInEditEntry} instances, which are normally obtained via the {@link ReqInEditParser} * class by parsing a HTTP file. *

* A {@link ReqInEditUnit} may be run one or more times. The caller is expected to close it once it's done * running requests. *

* The {@link TcpRawHttpClient} and {@link HttpTestsReporter} used by this unit are closed when this unit * is closed. */ public class ReqInEditUnit implements Closeable, AutoCloseable { private static final RawHttp HTTP = new RawHttp(RawHttpOptions.newBuilder() .allowComments() .allowIllegalStartLineCharacters() .build()); private final RawHttp http; private final FileReader fileReader; private final ResponseStorage responseStorage; private final RawHttpClient httpClient; private final HttpTestsReporter testsReporter; private final HttpEnvironment environment; public ReqInEditUnit() { this(new JsEnvironment()); } public ReqInEditUnit(HttpEnvironment environment) { this(environment, HTTP, new TcpRawHttpClient(new ClientOptionsWithCookies(), HTTP), new DefaultFileReader(), new FileResponseStorage(), new DefaultTestReporter()); } public ReqInEditUnit(HttpEnvironment environment, RawHttp http, RawHttpClient httpClient) { this(environment, http, httpClient, new DefaultFileReader(), new FileResponseStorage(), new DefaultTestReporter()); } public ReqInEditUnit(HttpEnvironment environment, RawHttp http, RawHttpClient httpClient, FileReader fileReader, ResponseStorage responseStorage, HttpTestsReporter testsReporter) { this.http = http; this.httpClient = httpClient; this.fileReader = fileReader; this.responseStorage = responseStorage; this.testsReporter = testsReporter; this.environment = environment; } /** * Run all of the given entries. *

* The entries are run in order until either they all execute without errors, or an error occurs, * or a response handler test fails. *

* The results of running an entry can be used by its associated response handler to modify subsequent * requests. * * @param entries to run * @return true if all tests passed or there was no tests, false if any test failed. */ public boolean run(List entries) { for (ReqInEditEntry entry : entries) { boolean allTestsPass = run(entry); if (!allTestsPass) { return false; } } return true; } /** * Run a single entry of a HTTP file. * * @param entry to run * @return true if all tests passed or there was no tests, false if any test failed. */ public boolean run(ReqInEditEntry entry) { RawHttpResponse response; try { response = httpClient.send(toRequest(entry)).eagerly(); } catch (IOException e) { throw new RuntimeException(e); } entry.getResponseRef().ifPresent(responseRef -> storeResponse(responseRef, response)); return entry.getScript() .map(script -> runResponseScript(script, response)) .orElse(true); } private RawHttpRequest toRequest(ReqInEditEntry entry) throws IOException { String requestTop = environment.renderTemplate(entry.getRequest()); ByteArrayOutputStream buffer = new ByteArrayOutputStream(4096); entry.getRequestBody().stream().map(b -> b.match( text -> environment.renderTemplate(text).getBytes(StandardCharsets.UTF_8), this::inputFile) ).forEach(b -> { try { buffer.write(b); } catch (IOException e) { // cannot occur - memory buffer } }); RawHttpRequest request = http.parseRequest(requestTop); if (buffer.size() > 0) { request = request.withBody(new BytesBody(buffer.toByteArray())).eagerly(); } return request; } private void storeResponse(String responseRef, RawHttpResponse response) { try { responseStorage.store(response, responseRef); } catch (IOException e) { throw new RuntimeException(e); } } private boolean runResponseScript(StringOrFile script, RawHttpResponse response) { try { String scriptText = script.match(text -> text, file -> new String(inputFile(file))); return environment.runResponseHandler(scriptText, response, testsReporter); } catch (IOException | ScriptException e) { throw new RuntimeException(e); } } private byte[] inputFile(String path) { try { return fileReader.read(environment.resolvePath(path)); } catch (IOException e) { throw new RuntimeException(e); } } @Override public void close() throws IOException { try { testsReporter.close(); } finally { if (httpClient instanceof Closeable) { ((Closeable) httpClient).close(); } } } private static final class DefaultFileReader implements FileReader { @Override public byte[] read(Path path) throws IOException { return Files.readAllBytes(path); } } private static final class FileResponseStorage implements ResponseStorage { @Override public void store(RawHttpResponse response, String responseRef) throws IOException { try (FileOutputStream out = new FileOutputStream(responseRef)) { response.writeTo(out); } } } private static final class DefaultTestReporter implements HttpTestsReporter { @Override public void report(HttpTestResult result) { long time = result.getEndTime() - result.getStartTime(); if (result.isSuccess()) { System.out.println("TEST OK (" + time + "ms): " + result.getName()); } else { System.out.println("TEST FAILED (" + time + "ms): " + result.getName()); if (!"".equals(result.getError())) { System.err.println(result.getError()); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy