use of com.webpieces.http2.api.streaming.StreamWriter in project webpieces by deanhiller.
the class ProxyHttpStream method incomingRequest.
@Override
public StreamRef incomingRequest(Http2Request request, ResponseStream stream) {
String expect = request.getSingleHeaderValue("Expect");
XFuture<StreamWriter> future = XFuture.completedFuture(null);
if (expect != null && "100-continue".equals(expect.toLowerCase())) {
Http2Response continueResponse = new Http2Response();
continueResponse.setEndOfStream(false);
continueResponse.addHeader(new Http2Header(Http2HeaderName.STATUS, "100"));
future = stream.process(continueResponse);
}
// This is only for streaming to backpressure clients IF we responded OR cancelled so we don't
// waste CPU on a client stream coming in
XFuture<ProxyWriter> futureWriter = new XFuture<>();
ProxyResponseStream proxy = new ProxyResponseStream(request, stream, futureWriter);
StreamRef streamRef = openStream.incomingRequest(request, proxy);
XFuture<StreamWriter> writer = future.thenCompose(w -> {
return createProxy(streamRef.getWriter(), futureWriter);
});
return new ProxyStreamRef(writer, streamRef);
}
use of com.webpieces.http2.api.streaming.StreamWriter in project webpieces by deanhiller.
the class StreamProxy method openStream.
@Override
public RouterStreamRef openStream(MethodMeta meta, ProxyStreamHandle handle) {
RequestContext requestCtx = meta.getCtx();
LoadedController loadedController = meta.getLoadedController();
Object instance = loadedController.getControllerInstance();
Method controllerMethod = loadedController.getControllerMethod();
Parameter[] parameters = loadedController.getParameters();
if (parameters.length != 1)
throw new IllegalArgumentException("Your method='" + controllerMethod + "' MUST one parameter and does not. It needs to take a RouterStreamHandler");
else if (!ResponseStreamHandle.class.equals(parameters[0].getType()))
throw new IllegalArgumentException("The single parameter must be RouterStreamHandle and was not for this method='" + controllerMethod + "'");
else if (!StreamRef.class.equals(controllerMethod.getReturnType()))
throw new IllegalArgumentException("The return value must be a subclass of StreamRef and was not for this method='" + controllerMethod + "'");
StreamRef streamRef = invokeStream(meta, controllerMethod, instance, requestCtx, handle);
XFuture<StreamWriter> writer = streamRef.getWriter();
XFuture<StreamWriter> newFuture = futureUtil.catchBlockWrap(() -> writer, (t) -> convert(loadedController, t));
Function<CancelReason, XFuture<Void>> cancelFunc = (reason) -> streamRef.cancel(reason);
return new RouterStreamRef("streamProxy", newFuture, cancelFunc);
}
use of com.webpieces.http2.api.streaming.StreamWriter in project webpieces by deanhiller.
the class XFileReader method sendHttpChunk.
private XFuture<Void> sendHttpChunk(StreamWriter writer, BufferPool pool, ByteBuffer buf, boolean isEos) {
DataWrapper data = wrapperFactory.wrapByteBuffer(buf);
int len = data.getReadableSize();
if (log.isTraceEnabled())
log.trace("SENDING data to=" + writer + " len=" + len + " isEnd=" + isEos + " content=" + data.createStringFromUtf8(0, len));
DataFrame frame = new DataFrame();
frame.setEndOfStream(isEos);
frame.setData(data);
return writer.processPiece(frame).thenApply(w -> {
// at this point, the buffer was consumed
// after process, release the buffer for re-use
buf.position(buf.limit());
pool.releaseBuffer(buf);
return null;
});
}
use of com.webpieces.http2.api.streaming.StreamWriter in project webpieces by deanhiller.
the class ProxyStreamHandle method createFrame.
private CompletionStage<Void> createFrame(byte[] bytes, StreamWriter writer) {
DataFrame frame = new DataFrame();
frame.setEndOfStream(true);
frame.setData(dataGen.wrapByteArray(bytes));
return writer.processPiece(frame);
}
use of com.webpieces.http2.api.streaming.StreamWriter in project webpieces by deanhiller.
the class RequestResponseStream method openStream.
@Override
public RouterStreamRef openStream(MethodMeta meta, ProxyStreamHandle handle) {
boolean endOfStream = meta.getCtx().getRequest().originalRequest.isEndOfStream();
if (endOfStream) {
// If there is no body, just invoke to process OR IN CASE of InternalError or NotFound, there is NO need
// to wait for the request body and we can respond early, which stops wasting CPU of reading in their body
meta.getCtx().getRequest().body = DataWrapperGeneratorFactory.EMPTY;
XFuture<StreamWriter> invokeSvc = invoker.invokeSvc(meta, i18nBundleName, service, processor, handle).thenApply(voidd -> new NullWriter());
return new RouterStreamRef("reqRespStreamProxy", invokeSvc, null);
}
// At this point, we don't have the end of the stream so return a request writer that calls invoke when complete
RequestStreamWriter2 writer = new RequestStreamWriter2(requestBodyParsers, meta, (newInfo) -> invoker.invokeSvc(newInfo, i18nBundleName, service, processor, handle));
XFuture<StreamWriter> w = XFuture.completedFuture(writer);
return new RouterStreamRef("requestRespStream", w, null);
}
Aggregations