@Override public void onNext(T value) { if (!writer.isOpen()) { return; } try { // To get an exception from the converter before sending the headers. final HttpData content = contentConverter.apply(value); if (!headersSent) { writer.write(headers); headersSent = true; } writer.write(content); } catch (Exception e) { onError(e); } }
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(); } }
/** * 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()); } }
@Override protected final HttpResponse doRead(HttpHeaders headers, long length, Executor fileReadExecutor, ByteBufAllocator alloc) throws IOException { final T in = newStream(); if (in == null) { return null; } boolean submitted = false; try { final HttpResponseWriter res = HttpResponse.streaming(); res.write(headers); fileReadExecutor.execute(() -> doRead(res, in, 0, length, fileReadExecutor, alloc)); submitted = true; return res; } finally { if (!submitted) { close(in); } } }
private void doSendHeaders(Metadata unusedGrpcMetadata) { checkState(!sendHeadersCalled, "sendHeaders already called"); checkState(!closeCalled, "call is closed"); final HttpHeaders headers = HttpHeaders.of(HttpStatus.OK); headers.contentType(serializationFormat.mediaType()); if (compressor == null || !messageCompression || clientAcceptEncoding == null) { compressor = Codec.Identity.NONE; } else { final List<String> acceptedEncodingsList = ACCEPT_ENCODING_SPLITTER.splitToList(clientAcceptEncoding); if (!acceptedEncodingsList.contains(compressor.getMessageEncoding())) { // resort to using no compression. compressor = Codec.Identity.NONE; } } messageFramer.setCompressor(compressor); // Always put compressor, even if it's identity. headers.add(GrpcHeaderNames.GRPC_ENCODING, compressor.getMessageEncoding()); if (!advertisedEncodingsHeader.isEmpty()) { headers.add(GrpcHeaderNames.GRPC_ACCEPT_ENCODING, advertisedEncodingsHeader); } sendHeadersCalled = true; res.write(headers); }
private void doSendMessage(O message) { checkState(sendHeadersCalled, "sendHeaders has not been called"); checkState(!closeCalled, "call is closed"); if (firstResponse == null) { firstResponse = message; } try { res.write(messageFramer.writePayload(marshaller.serializeResponse(message))); res.onDemand(() -> { if (pendingMessagesUpdater.decrementAndGet(this) == 0) { if (useBlockingTaskExecutor) { ctx.blockingTaskExecutor().execute(this::invokeOnReady); } else { invokeOnReady(); } } }); } catch (RuntimeException e) { close(Status.fromThrowable(e), EMPTY_METADATA); throw e; } catch (Throwable t) { close(Status.fromThrowable(t), EMPTY_METADATA); throw new RuntimeException(t); } }
/** * Creates a new HTTP response of the specified {@link HttpStatus} and closes the stream if the * {@link HttpStatusClass} is not {@linkplain HttpStatusClass#INFORMATIONAL informational} (1xx). */ static HttpResponse of(HttpStatus status) { requireNonNull(status, "status"); if (status.codeClass() == HttpStatusClass.INFORMATIONAL) { final HttpResponseWriter res = streaming(); res.write(HttpHeaders.of(status)); return res; } else if (isContentAlwaysEmpty(status)) { return new OneElementFixedHttpResponse(HttpHeaders.of(status)); } else { return of(status, MediaType.PLAIN_TEXT_UTF_8, status.toHttpData()); } }
@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 doSendHeaders(Metadata unusedGrpcMetadata) { checkState(!sendHeadersCalled, "sendHeaders already called"); checkState(!closeCalled, "call is closed"); final HttpHeaders headers = HttpHeaders.of(HttpStatus.OK); headers.contentType(serializationFormat.mediaType()); if (compressor == null || !messageCompression || clientAcceptEncoding == null) { compressor = Codec.Identity.NONE; } else { final List<String> acceptedEncodingsList = ACCEPT_ENCODING_SPLITTER.splitToList(clientAcceptEncoding); if (!acceptedEncodingsList.contains(compressor.getMessageEncoding())) { // resort to using no compression. compressor = Codec.Identity.NONE; } } messageFramer.setCompressor(compressor); // Always put compressor, even if it's identity. headers.add(GrpcHeaderNames.GRPC_ENCODING, compressor.getMessageEncoding()); if (!advertisedEncodingsHeader.isEmpty()) { headers.add(GrpcHeaderNames.GRPC_ACCEPT_ENCODING, advertisedEncodingsHeader); } sendHeadersCalled = true; res.write(headers); }
private void doSendMessage(O message) { checkState(sendHeadersCalled, "sendHeaders has not been called"); checkState(!closeCalled, "call is closed"); if (firstResponse == null) { firstResponse = message; } try { res.write(messageFramer.writePayload(marshaller.serializeResponse(message))); res.onDemand(() -> { if (pendingMessagesUpdater.decrementAndGet(this) == 0) { if (useBlockingTaskExecutor) { ctx.blockingTaskExecutor().execute(this::invokeOnReady); } else { invokeOnReady(); } } }); } catch (RuntimeException e) { close(Status.fromThrowable(e), EMPTY_METADATA); throw e; } catch (Throwable t) { close(Status.fromThrowable(t), EMPTY_METADATA); throw new RuntimeException(t); } }