/** * Writes the specified HTTP response and closes the stream. * * @deprecated Use {@link #close(AggregatedHttpMessage)}. */ @Deprecated default void respond(AggregatedHttpMessage res) { close(res); }
/** * Creates a new failed HTTP response. */ static HttpResponse ofFailure(Throwable cause) { final HttpResponseWriter res = streaming(); res.close(cause); return res; }
private void close(HttpResponseWriter res, Closeable in) { close(in); res.close(); }
private void close(HttpResponseWriter res, Closeable in, Exception cause) { close(in); res.close(cause); }
@Override public void onError(Throwable cause) { if (!writer.isOpen()) { return; } try { writer.close(cause); } catch (Exception e) { // 'subscription.cancel()' would be called by the close future listener of the writer, // so we call it when we failed to close the writer. assert subscription != null; subscription.cancel(); } }
private static HttpResponseWriter aggregateFrom(CompletableFuture<?> future, HttpHeaders headers, HttpHeaders trailingHeaders, Function<Object, HttpData> contentConverter) { final HttpResponseWriter writer = HttpResponse.streaming(); future.handle((result, cause) -> { if (cause != null) { writer.close(cause); return null; } try { final HttpData content = contentConverter.apply(result); writer.write(headers); writer.write(content); if (!trailingHeaders.isEmpty()) { writer.write(trailingHeaders); } writer.close(); } catch (Exception e) { writer.close(e); } return null; }); return writer; }
@Override public void onComplete() { if (!writer.isOpen()) { return; } if (!trailingHeaders.isEmpty()) { writer.write(trailingHeaders); } writer.close(); } }
if (cause != null) { logger.warn("{} Failed to aggregate a request:", ctx, cause); res.close(HttpHeaders.of(HttpStatus.INTERNAL_SERVER_ERROR)); return null; res.close(HttpHeaders.of(HttpStatus.BAD_REQUEST)); return null; logger.warn("{} Failed to produce a response:", ctx, t); } finally { res.close(); res.close();
/** * Writes the HTTP response of the specified {@link HttpStatus} and closes the stream if the * {@link HttpStatusClass} is not {@linkplain HttpStatusClass#INFORMATIONAL informational} (1xx). * * @deprecated Use {@link HttpResponse#of(HttpStatus)}. */ @Deprecated default void respond(HttpStatus status) { requireNonNull(status, "status"); if (status.codeClass() == HttpStatusClass.INFORMATIONAL) { write(HttpHeaders.of(status)); } else if (isContentAlwaysEmpty(status)) { write(HttpHeaders.of(status)); close(); } else { respond(status, MediaType.PLAIN_TEXT_UTF_8, status.toHttpData()); } }
private void invoke(ServiceRequestContext ctx, HttpResponseWriter res, ArmeriaHttpTransport transport, HttpChannel httpChannel) { final Queue<HttpData> out = transport.out; try { server.handle(httpChannel); httpChannel.getResponse().getHttpOutput().flush(); final Throwable cause = transport.cause; if (cause != null) { throw cause; } final HttpHeaders headers = toResponseHeaders(transport); if (res.tryWrite(headers)) { for (;;) { final HttpData data = out.poll(); if (data == null || !res.tryWrite(data)) { break; } } } } catch (Throwable t) { logger.warn("{} Failed to produce a response:", ctx, t); } finally { res.close(); } }
private void doClose(Status status, Metadata unusedGrpcMetadata) { checkState(!closeCalled, "call already closed"); closeCalled = true; if (cancelled) { // No need to write anything to client if cancelled already. closeListener(status); return; } final HttpHeaders trailers = statusToTrailers(status, sendHeadersCalled); final HttpObject trailersObj; if (sendHeadersCalled && GrpcSerializationFormats.isGrpcWeb(serializationFormat)) { // Normal trailers are not supported in grpc-web and must be encoded as a message. // Message compression is not supported in grpc-web, so we don't bother using the normal // ArmeriaMessageFramer. trailersObj = serializeTrailersAsMessage(trailers); } else { trailersObj = trailers; } try { if (res.tryWrite(trailersObj)) { res.close(); } } finally { closeListener(status); } }
final Throwable cause = statusException.getCause(); if (cause != null) { res.close(cause); } else { res.abort();
@Override protected void configure(ServerBuilder sb) { sb.service("/trailers", ((ctx, req) -> { HttpResponseWriter writer = HttpResponse.streaming(); HttpHeaders headers = HttpHeaders.of(HttpStatus.OK); assertThat(headers.isEndOfStream()).isFalse(); HttpHeaders trailers = new DefaultHttpHeaders(true, 1, true) .set(HttpHeaderNames.of("armeria-message"), "error"); assertThat(trailers.isEndOfStream()).isTrue(); writer.write(headers); writer.write(trailers); writer.close(); return writer; })); sb.service("/trailers-only", ((ctx, req) -> { HttpResponseWriter writer = HttpResponse.streaming(); HttpHeaders trailers = new DefaultHttpHeaders(true, 1, true) .status(HttpStatus.OK) .set(HttpHeaderNames.of("armeria-message"), "error"); assertThat(trailers.isEndOfStream()).isTrue(); writer.write(trailers); writer.close(); return writer; })); sb.decorator(LoggingService.newDecorator()); } };
private void doClose(Status status, Metadata unusedGrpcMetadata) { checkState(!closeCalled, "call already closed"); closeCalled = true; if (cancelled) { // No need to write anything to client if cancelled already. closeListener(status); return; } final HttpHeaders trailers = statusToTrailers(status, sendHeadersCalled); final HttpObject trailersObj; if (sendHeadersCalled && GrpcSerializationFormats.isGrpcWeb(serializationFormat)) { // Normal trailers are not supported in grpc-web and must be encoded as a message. // Message compression is not supported in grpc-web, so we don't bother using the normal // ArmeriaMessageFramer. trailersObj = serializeTrailersAsMessage(trailers); } else { trailersObj = trailers; } try { if (res.tryWrite(trailersObj)) { res.close(); } } finally { closeListener(status); } }
final Throwable cause = statusException.getCause(); if (cause != null) { res.close(cause); } else { res.abort();