All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aspectran.undertow.adapter.TowResponseAdapter Maven / Gradle / Ivy

There is a newer version: 8.1.5
Show newest version
/*
 * Copyright (c) 2008-2022 The Aspectran Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.aspectran.undertow.adapter;

import com.aspectran.core.activity.Translet;
import com.aspectran.core.adapter.AbstractResponseAdapter;
import com.aspectran.core.context.rule.RedirectRule;
import com.aspectran.core.util.Assert;
import com.aspectran.undertow.activity.TowActivity;
import com.aspectran.web.adapter.HttpServletResponseAdapter;
import com.aspectran.web.support.http.HttpStatus;
import com.aspectran.web.support.http.MediaType;
import com.aspectran.web.support.util.SendRedirectBasedOnXForwardedProtocol;
import io.undertow.server.HttpServerExchange;
import io.undertow.util.CanonicalPathUtils;
import io.undertow.util.HeaderMap;
import io.undertow.util.Headers;
import io.undertow.util.HttpString;
import io.undertow.util.URLUtils;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.stream.Collectors;

import static com.aspectran.web.adapter.HttpServletResponseAdapter.PROXY_PROTOCOL_AWARE_SETTING_NAME;

/**
 * The Class TowResponseAdapter.
 *
 * 

Created: 2019-07-27

*/ public class TowResponseAdapter extends AbstractResponseAdapter { private final TowActivity activity; private String contentType; private String charset; private Writer writer; private ResponseState responseState = ResponseState.NONE; public TowResponseAdapter(HttpServerExchange exchange, TowActivity activity) { super(exchange); this.activity = activity; } @Override public String getHeader(String name) { return getHttpServerExchange().getResponseHeaders().getFirst(name); } @Override public Collection getHeaders(String name) { return getHttpServerExchange().getResponseHeaders().get(name); } @Override public Collection getHeaderNames() { return getHttpServerExchange() .getResponseHeaders() .getHeaderNames() .stream() .map(HttpString::toString) .collect(Collectors.toSet()); } @Override public boolean containsHeader(String name) { return getHttpServerExchange().getResponseHeaders().contains(name); } @Override public void setHeader(String name, String value) { setHeader(HttpString.tryFromString(name), value); } private void setHeader(HttpString name, String value) { if (name == null) { throw new IllegalArgumentException("Header name must not be null"); } if (name.equals(Headers.CONTENT_TYPE)) { setContentType(value); } else { getHttpServerExchange().getResponseHeaders().put(name, value); } } @Override public void addHeader(String name, String value) { addHeader(HttpString.tryFromString(name), value); } private void addHeader(final HttpString name, final String value) { if (name == null) { throw new IllegalArgumentException("Header name must not be null"); } if (name.equals(Headers.CONTENT_TYPE) && !getHttpServerExchange().getResponseHeaders().contains(Headers.CONTENT_TYPE)) { setContentType(value); } else { getHttpServerExchange().getResponseHeaders().add(name, value); } } @Override public String getEncoding() { if (charset != null) { return charset; } return StandardCharsets.ISO_8859_1.name(); } @Override public void setEncoding(String encoding) throws UnsupportedEncodingException { this.charset = encoding; if (contentType != null) { getHttpServerExchange().getResponseHeaders().put(Headers.CONTENT_TYPE, getContentType()); } } @Override public String getContentType() { if (contentType != null) { if (charset != null) { return contentType + ";charset=" + charset; } else { return contentType; } } return null; } @Override public void setContentType(String contentType) { if (contentType == null) { return; } MediaType type = MediaType.parseMediaType(contentType); String charset = type.getParameter(MediaType.PARAM_CHARSET); this.contentType = type.getType() + '/' + type.getSubtype(); if (charset != null) { this.charset = charset; } if (this.charset != null) { String fullContentType = this.contentType + "; " + MediaType.PARAM_CHARSET + "=" + this.charset; getHttpServerExchange().getResponseHeaders().put(Headers.CONTENT_TYPE, fullContentType); } else { getHttpServerExchange().getResponseHeaders().put(Headers.CONTENT_TYPE, this.contentType); } } @Override public OutputStream getOutputStream() throws IOException { Assert.state(responseState != ResponseState.WRITER, "Cannot call getOutputStream(), getWriter() already called"); responseState = ResponseState.STREAM; ifStartBlocking(); return getHttpServerExchange().getOutputStream(); } @Override public Writer getWriter() throws IOException { if (writer == null) { Assert.state(responseState != ResponseState.STREAM, "Cannot call getWriter(), getOutputStream() already called"); responseState = ResponseState.WRITER; ifStartBlocking(); writer = new OutputStreamWriter(getHttpServerExchange().getOutputStream(), getEncoding()); } return writer; } @Override public void flush() throws IOException { if (writer != null) { writer.flush(); } else if (getHttpServerExchange().isResponseStarted()) { getHttpServerExchange().getOutputStream().flush(); } } @Override public void redirect(String location) throws IOException { setStatus(HttpStatus.FOUND.value()); if (URLUtils.isAbsoluteUrl(location)) { //absolute url getHttpServerExchange().getResponseHeaders().put(Headers.LOCATION, location); } else { boolean proxyProtocolAware = Boolean.parseBoolean(activity.getSetting(PROXY_PROTOCOL_AWARE_SETTING_NAME)); if (proxyProtocolAware) { Translet translet = activity.getTranslet(); String locationForwarded = SendRedirectBasedOnXForwardedProtocol.getLocationForwarded(translet, location); if (locationForwarded != null) { getHttpServerExchange().getResponseHeaders().put(Headers.LOCATION, locationForwarded); return; } } String realPath; if (location.startsWith("/")) { realPath = location; } else { realPath = CanonicalPathUtils.canonicalize(location); } String url = getHttpServerExchange().getRequestScheme() + "://" + getHttpServerExchange().getHostAndPort() + realPath; getHttpServerExchange().getResponseHeaders().put(Headers.LOCATION, url); } } @Override public String redirect(RedirectRule redirectRule) throws IOException { String path = HttpServletResponseAdapter.makeRedirectPath(redirectRule, activity); redirect(path); return path; } @Override public int getStatus() { return getHttpServerExchange().getStatusCode(); } @Override public void setStatus(int status) { getHttpServerExchange().setStatusCode(status); } private void ifSetChunked() { HeaderMap responseHeaders = getHttpServerExchange().getResponseHeaders(); if (!responseHeaders.contains(Headers.CONTENT_LENGTH)) { getHttpServerExchange().getResponseHeaders().put(Headers.TRANSFER_ENCODING, Headers.CHUNKED.toString()); } } private void ifStartBlocking() { if (!getHttpServerExchange().isBlocking()) { getHttpServerExchange().startBlocking(); } } private HttpServerExchange getHttpServerExchange() { return getAdaptee(); } public enum ResponseState { NONE, STREAM, WRITER } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy