/** * Returns new empty HTTP headers. */ static HttpHeaders of() { return new DefaultHttpHeaders(); }
private HttpHeaders createAdditionalHeadersIfAbsent() { final HttpHeaders additionalRequestHeaders = this.additionalRequestHeaders; if (additionalRequestHeaders == null) { return this.additionalRequestHeaders = new DefaultHttpHeaders(); } else { return additionalRequestHeaders; } }
private HttpHeaders createAdditionalTrailersIfAbsent() { final HttpHeaders additionalResponseTrailers = this.additionalResponseTrailers; if (additionalResponseTrailers == null) { final HttpHeaders newTrailers = new DefaultHttpHeaders(); if (additionalResponseTrailersUpdater.compareAndSet(this, null, newTrailers)) { return newTrailers; } else { final HttpHeaders additionalResponseTrailersSetByOtherThread = this.additionalResponseTrailers; assert additionalResponseTrailersSetByOtherThread != null; return additionalResponseTrailersSetByOtherThread; } } else { return additionalResponseTrailers; } }
private HttpHeaders createAdditionalHeadersIfAbsent() { final HttpHeaders additionalResponseHeaders = this.additionalResponseHeaders; if (additionalResponseHeaders == null) { final HttpHeaders newHeaders = new DefaultHttpHeaders(); if (additionalResponseHeadersUpdater.compareAndSet(this, null, newHeaders)) { return newHeaders; } else { final HttpHeaders additionalResponseHeadersSetByOtherThread = this.additionalResponseHeaders; assert additionalResponseHeadersSetByOtherThread != null; return additionalResponseHeadersSetByOtherThread; } } else { return additionalResponseHeaders; } }
/** * Returns new HTTP headers with a single entry. */ static HttpHeaders of(AsciiString name, String value) { return new DefaultHttpHeaders().add(name, value); }
/** * Returns new HTTP response headers. */ static HttpHeaders of(HttpStatus status) { return new DefaultHttpHeaders().status(status); }
ArmeriaServerHttpResponse(ServiceRequestContext ctx, CompletableFuture<HttpResponse> future, DataBufferFactoryWrapper<?> factoryWrapper, @Nullable String serverHeader) { super(requireNonNull(factoryWrapper, "factoryWrapper").delegate()); this.ctx = requireNonNull(ctx, "ctx"); this.future = requireNonNull(future, "future"); this.factoryWrapper = factoryWrapper; headers = new DefaultHttpHeaders(); if (!Strings.isNullOrEmpty(serverHeader)) { headers.set(HttpHeaderNames.SERVER, serverHeader); } }
/** * Returns new HTTP request headers. */ static HttpHeaders of(HttpMethod method, String path) { return new DefaultHttpHeaders().method(method).path(path); }
private static HttpHeaders filterHttpHeaders(HttpHeaders headers) { requireNonNull(headers, "headers"); for (AsciiString name : BLACKLISTED_HEADER_NAMES) { if (headers.contains(name)) { throw new IllegalArgumentException("unallowed header name: " + name); } } return new DefaultHttpHeaders().add(headers).asImmutable(); }
/** * Returns new HTTP headers with two entries. */ static HttpHeaders of(AsciiString name1, String value1, AsciiString name2, String value2) { return new DefaultHttpHeaders().add(name1, value1).add(name2, value2); }
/** * Converts the specified Netty HTTP/1 headers into Armeria HTTP/2 headers. */ public static HttpHeaders toArmeria(io.netty.handler.codec.http.HttpHeaders inHeaders) { if (inHeaders.isEmpty()) { return HttpHeaders.EMPTY_HEADERS; } final HttpHeaders out = new DefaultHttpHeaders(true, inHeaders.size()); toArmeria(inHeaders, out); return out; }
/** * Returns new HTTP headers with three entries. */ static HttpHeaders of(AsciiString name1, String value1, AsciiString name2, String value2, AsciiString name3, String value3) { return new DefaultHttpHeaders().add(name1, value1).add(name2, value2) .add(name3, value3); }
/** * Converts the headers of the given Netty HTTP/1.x response into Armeria HTTP/2 headers. */ public static HttpHeaders toArmeria(HttpResponse in) { final io.netty.handler.codec.http.HttpHeaders inHeaders = in.headers(); final HttpHeaders out = new DefaultHttpHeaders(true, inHeaders.size()); out.status(in.status().code()); // Add the HTTP headers which have not been consumed above toArmeria(inHeaders, out); return out; }
/** * Generates immutable HTTP response headers that should be added to a CORS preflight response. * * @return {@link HttpHeaders} the HTTP response headers to be added. */ public HttpHeaders generatePreflightResponseHeaders() { final HttpHeaders headers = new DefaultHttpHeaders(); preflightResponseHeaders.forEach((key, value) -> { final Object val = getValue(value); if (val instanceof Iterable) { headers.addObject(key, (Iterable<?>) val); } else { headers.addObject(key, val); } }); return headers.asImmutable(); }
/** * Converts the specified Netty HTTP/2 into Armeria HTTP/2 headers. */ public static HttpHeaders toArmeria(Http2Headers headers, boolean endOfStream) { final HttpHeaders converted = new DefaultHttpHeaders(false, headers.size(), endOfStream); StringJoiner cookieJoiner = null; for (Entry<CharSequence, CharSequence> e : headers) { final AsciiString name = HttpHeaderNames.of(e.getKey()); final CharSequence value = e.getValue(); // Cookies must be concatenated into a single octet string. // https://tools.ietf.org/html/rfc7540#section-8.1.2.5 if (name.equals(HttpHeaderNames.COOKIE)) { if (cookieJoiner == null) { cookieJoiner = new StringJoiner(COOKIE_SEPARATOR); } COOKIE_SPLITTER.split(value).forEach(cookieJoiner::add); } else { converted.add(name, convertHeaderValue(name, value)); } } if (cookieJoiner != null && cookieJoiner.length() != 0) { converted.add(HttpHeaderNames.COOKIE, cookieJoiner.toString()); } return converted; }
/** * Returns new HTTP headers with four entries. */ static HttpHeaders of(AsciiString name1, String value1, AsciiString name2, String value2, AsciiString name3, String value3, AsciiString name4, String value4) { return new DefaultHttpHeaders().add(name1, value1).add(name2, value2) .add(name3, value3).add(name4, value4); }
private static HttpHeaders fillAdditionalHeaders(HttpHeaders headers, HttpHeaders additionalHeaders) { if (!additionalHeaders.isEmpty()) { if (headers.isImmutable()) { // All headers are already validated. final HttpHeaders temp = headers; headers = new DefaultHttpHeaders(false, temp.size() + additionalHeaders.size()); headers.set(temp); } headers.setAllIfAbsent(additionalHeaders); } return headers; }
static HttpHeaders statusToTrailers(ServiceRequestContext ctx, Status status, boolean headersSent) { final HttpHeaders trailers; if (headersSent) { // Normal trailers. trailers = new DefaultHttpHeaders(); } else { // Trailers only response trailers = new DefaultHttpHeaders(true, 3, true) .status(HttpStatus.OK) .set(HttpHeaderNames.CONTENT_TYPE, "application/grpc+proto"); } trailers.add(GrpcHeaderNames.GRPC_STATUS, Integer.toString(status.getCode().value())); if (status.getDescription() != null) { trailers.add(GrpcHeaderNames.GRPC_MESSAGE, StatusMessageEscaper.escape(status.getDescription())); } if (ctx.server().config().verboseResponses() && status.getCause() != null) { final ThrowableProto proto = GrpcStatus.serializeThrowable(status.getCause()); trailers.add(GrpcHeaderNames.ARMERIA_GRPC_THROWABLEPROTO_BIN, Base64.getEncoder().encodeToString(proto.toByteArray())); } return trailers; }
/** * Converts the headers of the given Netty HTTP/1.x request into Armeria HTTP/2 headers. * The following headers are only used if they can not be found in the {@code HOST} header or the * {@code Request-Line} as defined by <a href="https://tools.ietf.org/html/rfc7230">rfc7230</a> * <ul> * <li>{@link ExtensionHeaderNames#SCHEME}</li> * </ul> * {@link ExtensionHeaderNames#PATH} is ignored and instead extracted from the {@code Request-Line}. */ public static HttpHeaders toArmeria(HttpRequest in) throws URISyntaxException { final URI requestTargetUri = toUri(in); final io.netty.handler.codec.http.HttpHeaders inHeaders = in.headers(); final HttpHeaders out = new DefaultHttpHeaders(true, inHeaders.size()); out.path(toHttp2Path(requestTargetUri)); out.method(HttpMethod.valueOf(in.method().name())); setHttp2Scheme(inHeaders, requestTargetUri, out); if (!isOriginForm(requestTargetUri) && !isAsteriskForm(requestTargetUri)) { // Attempt to take from HOST header before taking from the request-line final String host = inHeaders.getAsString(HttpHeaderNames.HOST); setHttp2Authority(host == null || host.isEmpty() ? requestTargetUri.getAuthority() : host, out); } // Add the HTTP headers which have not been consumed above toArmeria(inHeaders, out); return out; }
@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()); } };