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

io.github.mike10004.vhs.bmp.HarReplayManufacturer Maven / Gradle / Ivy

There is a newer version: 0.32
Show newest version
package io.github.mike10004.vhs.bmp;

import com.google.common.collect.ImmutableList;
import com.google.common.io.CharSource;
import com.google.common.net.MediaType;
import io.github.mike10004.vhs.EntryMatcher;
import io.github.mike10004.vhs.HttpRespondable;
import io.github.mike10004.vhs.ReplaySessionState;
import io.github.mike10004.vhs.ResponseInterceptor;
import io.github.mike10004.vhs.harbridge.ParsedRequest;
import io.netty.handler.codec.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.function.Supplier;

import static java.util.Objects.requireNonNull;

/**
 * Implementation of a response manufacturer that manufactures responses
 * based on the content of a HAR file.
 */
public class HarReplayManufacturer implements BmpResponseManufacturer {

    private static final Logger log = LoggerFactory.getLogger(HarReplayManufacturer.class);
    private static final Charset OUTGOING_CHARSET = StandardCharsets.UTF_8;

    private final Supplier sessionStateFactory;
    private final EntryMatcher entryMatcher;
    private final ImmutableList responseInterceptors;
    private final HttpAssistant bmpAssistant;

    /**
     * Constructs an instance.
     * @param entryMatcher the entry matcher
     * @param responseInterceptors a list of response interceptors
     */
    public HarReplayManufacturer(EntryMatcher entryMatcher, Iterable responseInterceptors) {
        this(entryMatcher, responseInterceptors, ReplaySessionState::countingUrlMethodPairs);
    }

    public HarReplayManufacturer(EntryMatcher entryMatcher, Iterable responseInterceptors, Supplier sessionStateFactory) {
        this(entryMatcher, responseInterceptors, new BmpHttpAssistant(), sessionStateFactory);
    }

    protected HarReplayManufacturer(EntryMatcher entryMatcher, Iterable responseInterceptors, HttpAssistant bmpAssistant, Supplier sessionStateFactory) {
        this.entryMatcher = requireNonNull(entryMatcher);
        this.responseInterceptors = ImmutableList.copyOf(responseInterceptors);
        this.bmpAssistant = requireNonNull(bmpAssistant);
        this.sessionStateFactory = requireNonNull(sessionStateFactory);
    }

    @Override
    public ReplaySessionState createFreshState() {
        return sessionStateFactory.get();
    }

    @Override
    public ResponseCapture manufacture(ReplaySessionState state, RequestCapture capture) {
        state.register(capture.request);
        return manufacture(state, bmpAssistant, capture);
    }

    protected ImmutableHttpResponse createNotFoundResponse() {
        MediaType contentType = MediaType.PLAIN_TEXT_UTF_8.withCharset(OUTGOING_CHARSET);
        return ImmutableHttpResponse.builder(404)
                .content(contentType, CharSource.wrap("404 Not Found").asByteSource(OUTGOING_CHARSET))
                .build();
    }

    protected ImmutableHttpResponse createParsingFailedResponse() {
        MediaType contentType = MediaType.PLAIN_TEXT_UTF_8.withCharset(OUTGOING_CHARSET);
        return ImmutableHttpResponse.builder(500)
                .content(contentType, CharSource.wrap("500 Internal Server Error").asByteSource(OUTGOING_CHARSET))
                .build();
    }

    protected  ResponseCapture manufacture(ReplaySessionState sessionState, HttpAssistant assistant, Q incoming) {
        ParsedRequest request;
        try {
            request = assistant.parseRequest(incoming);
        } catch (IOException e) {
            log.error("failed to read from incoming request", e);
            ImmutableHttpResponse outgoing = createParsingFailedResponse();
            HttpResponse netty = assistant.constructResponse(incoming, outgoing);
            return ResponseCapture.error(netty);
        }
        @Nullable HttpRespondable bestEntry = entryMatcher.findTopEntry(sessionState, request);
        if (bestEntry != null) {
            for (ResponseInterceptor interceptor : responseInterceptors) {
                bestEntry = interceptor.intercept(request, bestEntry);
            }
        }
        if (bestEntry == null) {
            ImmutableHttpResponse response = createNotFoundResponse();
            return ResponseCapture.unmatched(assistant.constructResponse(incoming, response));
        } else {
            try {
                return ResponseCapture.matched(assistant.transformRespondable(incoming, bestEntry));
            } catch (IOException e) {
                log.warn("failed to construct response", e);
                ImmutableHttpResponse response = HttpAssistant.standardServerErrorResponse();
                return ResponseCapture.error(assistant.constructResponse(incoming, response));
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy