/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package net.acesinc.convergentui;
import com.netflix.config.DynamicBooleanProperty;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.util.Pair;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.context.RequestContext;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
import org.springframework.util.MimeType;
/**
* A majority of the boilerplate code was stolen from the SendResponseFilter in
* the spring-cloud-netflix project:
* https://github.com/spring-cloud/spring-cloud-netflix/blob/master/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendResponseFilter.java
*
* @author andrewserff
*/
public abstract class BaseFilter extends ZuulFilter {
private static DynamicBooleanProperty INCLUDE_DEBUG_HEADER = DynamicPropertyFactory
.getInstance().getBooleanProperty(ZuulConstants.ZUUL_INCLUDE_DEBUG_HEADER,
false);
private static DynamicIntProperty INITIAL_STREAM_BUFFER_SIZE = DynamicPropertyFactory
.getInstance().getIntProperty(ZuulConstants.ZUUL_INITIAL_STREAM_BUFFER_SIZE,
1024);
private static DynamicBooleanProperty SET_CONTENT_LENGTH = DynamicPropertyFactory
.getInstance().getBooleanProperty(ZuulConstants.ZUUL_SET_CONTENT_LENGTH,
false);
protected boolean isConvergentUIRequest(HttpServletRequest request) {
String path = request.getRequestURI();
return path.startsWith("/cui-req://");
}
protected String getVerb(HttpServletRequest request) {
String method = "GET";
if (request != null && request.getMethod() != null) {
method = request.getMethod();
}
return method;
}
protected MimeType getMimeType(RequestContext context) {
List<Pair<String, String>> headers = context.getZuulResponseHeaders();
String contentType = null;
for (Pair<String, String> pair : headers) {
if ("content-type".equalsIgnoreCase(pair.first())) {
contentType = pair.second();
break;
}
}
if (contentType != null) {
MimeType type = MimeType.valueOf(contentType);
return type;
}
return null;
}
protected String getContentType(RequestContext context) {
String contentType = "unknown";
MimeType type = getMimeType(context);
if (type != null) {
contentType = type.getType() + "/" + type.getSubtype();
}
return contentType;
}
protected void writeResponse(String responseBody, MimeType contentType) throws Exception {
RequestContext context = RequestContext.getCurrentContext();
// there is no body to send
if (responseBody == null || responseBody.isEmpty()) {
return;
}
HttpServletResponse servletResponse = context.getResponse();
servletResponse.setCharacterEncoding("UTF-8");
servletResponse.setContentType(contentType.toString());
OutputStream outStream = servletResponse.getOutputStream();
InputStream is = null;
try {
writeResponse(new ByteArrayInputStream(responseBody.getBytes()), outStream);
} finally {
try {
if (is != null) {
is.close();
}
outStream.flush();
outStream.close();
} catch (IOException ex) {
}
}
}
protected void writeResponse(BufferedImage image, MediaType type) throws Exception {
RequestContext context = RequestContext.getCurrentContext();
// there is no body to send
if (image == null) {
return;
}
HttpServletResponse servletResponse = context.getResponse();
// servletResponse.setCharacterEncoding("UTF-8");
servletResponse.setContentType(type.toString());
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
ImageIO.write(image, type.getSubtype(), tmp);
tmp.close();
Integer contentLength = tmp.size();
servletResponse.setContentLength(contentLength);
OutputStream outStream = servletResponse.getOutputStream();
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, type.getSubtype(), os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
try {
writeResponse(is, outStream);
} finally {
try {
if (is != null) {
is.close();
}
outStream.flush();
outStream.close();
} catch (IOException ex) {
}
}
}
protected void writeResponse(InputStream zin, OutputStream out) throws Exception {
byte[] bytes = new byte[INITIAL_STREAM_BUFFER_SIZE.get()];
int bytesRead = -1;
while ((bytesRead = zin.read(bytes)) != -1) {
try {
out.write(bytes, 0, bytesRead);
out.flush();
} catch (IOException ex) {
// ignore
}
// doubles buffer size if previous read filled it
if (bytesRead == bytes.length) {
bytes = new byte[bytes.length * 2];
}
}
}
protected void addResponseHeaders() {
RequestContext context = RequestContext.getCurrentContext();
HttpServletResponse servletResponse = context.getResponse();
List<Pair<String, String>> zuulResponseHeaders = context.getZuulResponseHeaders();
@SuppressWarnings("unchecked")
List<String> rd = (List<String>) RequestContext.getCurrentContext().get(
"routingDebug");
if (rd != null) {
StringBuilder debugHeader = new StringBuilder();
for (String it : rd) {
debugHeader.append("[[[" + it + "]]]");
}
if (INCLUDE_DEBUG_HEADER.get()) {
servletResponse.addHeader("X-Zuul-Debug-Header", debugHeader.toString());
}
}
if (zuulResponseHeaders != null) {
for (Pair<String, String> it : zuulResponseHeaders) {
servletResponse.addHeader(it.first(), it.second());
}
}
RequestContext ctx = RequestContext.getCurrentContext();
Long contentLength = ctx.getOriginContentLength();
// Only inserts Content-Length if origin provides it and origin response is not
// gzipped
if (SET_CONTENT_LENGTH.get()) {
if (contentLength != null && !ctx.getResponseGZipped()) {
servletResponse.setContentLengthLong(contentLength);
}
}
}
}