Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.hyperfoil.http.html.EmbeddedResourceProcessor Maven / Gradle / Ivy
package io.hyperfoil.http.html;
import java.nio.charset.StandardCharsets;
import io.hyperfoil.api.processor.Processor;
import io.hyperfoil.api.session.ResourceUtilizer;
import io.hyperfoil.api.session.Session;
import io.hyperfoil.core.util.Util;
import io.hyperfoil.http.HttpUtil;
import io.hyperfoil.http.api.HttpDestinationTable;
import io.hyperfoil.http.api.HttpRequest;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.util.internal.AppendableCharSequence;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
class EmbeddedResourceProcessor extends Processor.BaseDelegating {
private static final Logger log = LoggerFactory.getLogger(EmbeddedResourceProcessor.class);
private static final boolean trace = log.isTraceEnabled();
private static final byte[] HTTP_PREFIX = HttpUtil.HTTP_PREFIX.getBytes(StandardCharsets.UTF_8);
private static final byte[] HTTPS_PREFIX = HttpUtil.HTTP_PREFIX.getBytes(StandardCharsets.UTF_8);
private final boolean ignoreExternal;
private final FetchResourceHandler fetchResource;
EmbeddedResourceProcessor(boolean ignoreExternal, Processor delegate, FetchResourceHandler fetchResource) {
super(delegate);
this.ignoreExternal = ignoreExternal;
this.fetchResource = fetchResource;
}
@Override
public void before(Session session) {
if (fetchResource != null) {
fetchResource.before(session);
}
if (delegate != null) {
super.before(session);
}
}
@Override
public void after(Session session) {
if (delegate != null) {
super.after(session);
}
if (fetchResource != null) {
fetchResource.after(session);
}
}
@Override
public void reserve(Session session) {
super.reserve(session);
ResourceUtilizer.reserve(session, fetchResource);
}
@Override
public void process(Session session, ByteBuf data, int offset, int length, boolean isLastPart) {
assert isLastPart;
// TODO: here we should normalize the URL, remove escapes etc...
HttpRequest request = (HttpRequest) session.currentRequest();
boolean isHttp = Util.hasPrefix(data, offset, length, HTTP_PREFIX);
boolean isHttps = Util.hasPrefix(data, offset, length, HTTPS_PREFIX);
if (isHttp || isHttps) {
String authority = null;
HttpDestinationTable destinations = HttpDestinationTable.get(session);
byte[][] authorityBytes = destinations.authorityBytes();
for (int i = 0; i < authorityBytes.length; i++) {
if (HttpUtil.authorityMatch(data, offset, length, authorityBytes[i], isHttp)) {
authority = destinations.authorities()[i];
break;
}
}
if (authority == null && ignoreExternal) {
if (trace) {
log.trace("#{} Ignoring external URL {}", session.uniqueId(), Util.toString(data, offset, length));
}
return;
}
if (trace) {
log.trace("#{} Matched URL {}", session.uniqueId(), Util.toString(data, offset, length));
}
if (fetchResource != null) {
int pathStart = data.indexOf(offset + (isHttp ? HTTP_PREFIX.length : HTTPS_PREFIX.length), offset + length, (byte) '/');
CharSequence path = pathStart < 0 ? "/" : data.toString(pathStart, offset + length - pathStart, StandardCharsets.UTF_8);
fetchResource.handle(session, authority, path);
}
if (delegate != null) {
delegate.process(session, data, offset, length, true);
}
} else if (data.getByte(offset) == '/') {
// No need to rewrite relative URL
if (trace) {
log.trace("#{} Matched URL {}", session.uniqueId(), Util.toString(data, offset, length));
}
if (fetchResource != null) {
fetchResource.handle(session, request.authority, data.toString(offset, length, StandardCharsets.UTF_8));
}
if (delegate != null) {
delegate.process(session, data, offset, length, true);
}
} else {
if (trace) {
log.trace("#{} Matched URL {}", session.uniqueId(), Util.toString(data, offset, length));
}
if (fetchResource != null) {
AppendableCharSequence newPath = new AppendableCharSequence(request.path.length() + length);
int end = request.path.lastIndexOf('/');
if (end < 0) {
newPath.append(request.path).append('/');
} else {
newPath.append(request.path, 0, end + 1);
}
// TODO allocation
newPath.append(Util.toString(data, offset, length));
if (trace) {
log.trace("#{} Rewritten relative URL to {}", session.uniqueId(), newPath);
}
fetchResource.handle(session, request.authority, newPath);
}
if (delegate != null) {
ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer(request.path.length() + length);
Util.string2byteBuf(request.path, buffer);
for (int i = buffer.writerIndex() - 1; i >= 0; --i) {
if (buffer.getByte(i) == '/') {
buffer.writerIndex(i + 1);
break;
}
}
buffer.ensureWritable(length);
buffer.writeBytes(data, offset, length);
if (trace) {
log.trace("#{} Rewritten relative URL to {}", session.uniqueId(), Util.toString(buffer, buffer.readerIndex(), buffer.readableBytes()));
}
delegate.process(session, buffer, buffer.readerIndex(), buffer.readableBytes(), true);
buffer.release();
}
}
}
}