
org.apache.sling.bgservlets.BackgroundHttpServletRequest Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.sling.bgservlets;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Principal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.sling.api.SlingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Minimal HttpServletRequest for background processing */
public class BackgroundHttpServletRequest implements HttpServletRequest {
private static final Logger log = LoggerFactory.getLogger(BackgroundHttpServletRequest.class);
private final String contextPath;
private final String method;
private final String pathInfo;
private final String servletPath;
private final String queryString;
private final String requestURI;
private final StringBuffer requestURL;
private String characterEncoding;
private final int contentLength;
private final String contentType;
private final Locale locale;
private final String protocol;
private final String remoteAddr;
private final String remoteHost;
private final int remotePort;
private final int serverPort;
private final String scheme;
private final String remoteUser;
private final String serverName;
private final Map attributes;
private final Map parameters;
static class IteratorEnumeration implements Enumeration {
private final Iterator it;
IteratorEnumeration(Iterator it) {
this.it = it;
}
public boolean hasMoreElements() {
return it.hasNext();
}
public T nextElement() {
return it.next();
}
}
/**
* We throw this for any method for which we do not have data that's safe to
* use outside of the container's request/response cycle. Start by throwing
* this everywhere and implement methods as needed, if their data is safe to
* use.
*/
@SuppressWarnings("serial")
class UnsupportedBackgroundOperationException extends
UnsupportedOperationException {
UnsupportedBackgroundOperationException() {
super("This operation is not supported for background requests");
}
}
@SuppressWarnings("unchecked")
public BackgroundHttpServletRequest(HttpServletRequest r,
String[] parametersToRemove) {
// Store objects which are safe to use outside
// of the container's request/response cycle - the
// goal is to release r once this request starts
// executing in the background
contextPath = r.getContextPath();
method = r.getMethod();
pathInfo = r.getPathInfo();
servletPath = r.getServletPath();
queryString = filterQueryString(r.getQueryString(), parametersToRemove);
requestURI = r.getRequestURI();
requestURL = r.getRequestURL();
characterEncoding = r.getCharacterEncoding();
contentLength = r.getContentLength();
contentType = r.getContentType();
locale = r.getLocale();
protocol = r.getProtocol();
remoteAddr = r.getRemoteAddr();
remoteHost = r.getRemoteHost();
remotePort = r.getRemotePort();
serverPort = r.getServerPort();
scheme = r.getScheme();
remoteUser = r.getRemoteUser();
serverName = r.getServerName();
attributes = new HashMap();
//
// Don't copy attributes, we consider this to be a "fresh" request final
// Enumeration> e = r.getAttributeNames(); while(e.hasMoreElements())
// { final String key = (String)e.nextElement(); attributes.put(key,
// r.getAttribute(key)); }
//
parameters = new HashMap();
parameters.putAll(r.getParameterMap());
for (String key : parametersToRemove) {
parameters.remove(key);
}
}
private String filterQueryString(String original, String [] parametersToRemove) {
if(original == null) {
return null;
}
final String encoding = "UTF-8"; // recommended as per URLDecoder javadocs
final StringBuilder sb = new StringBuilder(original.length());
final String SEP = "&";
final String [] params = original.split(SEP);
for(String param : params) {
String name = null;
try {
name = URLDecoder.decode(param.split("=")[0].trim(), encoding);
} catch(UnsupportedEncodingException uee) {
throw new SlingException("Unexpected UnsupportedEncodingException for " + encoding, uee);
}
boolean ignore = false;
for(String p : parametersToRemove) {
if(name.equals(p)) {
ignore=true;
break;
}
}
if(!ignore) {
sb.append(param).append(SEP);
}
}
final String result = sb.toString();
log.debug("Filtered query string to '{}'", result);
return result;
}
public String getAuthType() {
return null;
}
public String getContextPath() {
return contextPath;
}
public Cookie[] getCookies() {
return null;
}
public long getDateHeader(String arg0) {
return 0;
}
public String getHeader(String arg0) {
return null;
}
public Enumeration> getHeaderNames() {
return null;
}
public Enumeration> getHeaders(String name) {
return null;
}
public int getIntHeader(String name) {
return 0;
}
public String getMethod() {
return method;
}
public String getPathInfo() {
return pathInfo;
}
public String getPathTranslated() {
throw new UnsupportedBackgroundOperationException();
}
public String getQueryString() {
return queryString;
}
public String getRemoteUser() {
return remoteUser;
}
public String getRequestedSessionId() {
throw new UnsupportedBackgroundOperationException();
}
public String getRequestURI() {
return requestURI;
}
public StringBuffer getRequestURL() {
return requestURL;
}
public String getServletPath() {
return servletPath;
}
public HttpSession getSession() {
throw new UnsupportedBackgroundOperationException();
}
public HttpSession getSession(boolean arg0) {
throw new UnsupportedBackgroundOperationException();
}
public Principal getUserPrincipal() {
throw new UnsupportedBackgroundOperationException();
}
public boolean isRequestedSessionIdFromCookie() {
throw new UnsupportedBackgroundOperationException();
}
public boolean isRequestedSessionIdFromUrl() {
throw new UnsupportedBackgroundOperationException();
}
public boolean isRequestedSessionIdFromURL() {
throw new UnsupportedBackgroundOperationException();
}
public boolean isRequestedSessionIdValid() {
throw new UnsupportedBackgroundOperationException();
}
public boolean isUserInRole(String arg0) {
throw new UnsupportedBackgroundOperationException();
}
public Object getAttribute(String name) {
return attributes.get(name);
}
public Enumeration> getAttributeNames() {
return new IteratorEnumeration(attributes.keySet().iterator());
}
public String getCharacterEncoding() {
return characterEncoding;
}
public int getContentLength() {
return contentLength;
}
public String getContentType() {
return contentType;
}
private static final String encode(final String value) {
try {
return URLEncoder.encode(value, "UTF-8");
} catch ( final UnsupportedEncodingException uee) {
return value;
}
}
private boolean append(final StringBuilder sb, final String key, final String val, final boolean first) {
if ( !first ) {
sb.append('&');
}
sb.append(key);
sb.append('=');
sb.append(encode(val));
return false;
}
public ServletInputStream getInputStream() throws IOException {
// create byte array of all parameters
boolean first = true;
final StringBuilder sb = new StringBuilder();
for(final Map.Entry entry : this.parameters.entrySet()) {
if ( entry.getValue() instanceof String[] ) {
for(final String val : (String[])entry.getValue()) {
first = append(sb, entry.getKey(), val, first);
}
} else {
first = append(sb, entry.getKey(), (String)entry.getValue(), first);
}
}
return new ByteArrayServletInputStream(new ByteArrayInputStream(sb.toString().getBytes(this.characterEncoding)));
}
private static final class ByteArrayServletInputStream extends ServletInputStream {
private final ByteArrayInputStream stream;
public ByteArrayServletInputStream(final ByteArrayInputStream stream) {
this.stream = stream;
}
@Override
public int available() throws IOException {
return this.stream.available();
}
@Override
public void close() throws IOException {
this.stream.close();
}
@Override
public synchronized void mark(final int arg0) {
this.stream.mark(arg0);
}
@Override
public boolean markSupported() {
return this.stream.markSupported();
}
@Override
public int read() throws IOException {
return this.stream.read();
}
@Override
public int read(final byte[] arg0, final int arg1, final int arg2) throws IOException {
return this.stream.read(arg0, arg1, arg2);
}
@Override
public int read(final byte[] arg0) throws IOException {
return this.stream.read(arg0);
}
@Override
public synchronized void reset() throws IOException {
this.stream.reset();
}
@Override
public long skip(final long arg0) throws IOException {
return this.stream.skip(arg0);
}
}
public String getLocalAddr() {
throw new UnsupportedBackgroundOperationException();
}
public Locale getLocale() {
return locale;
}
public Enumeration> getLocales() {
throw new UnsupportedBackgroundOperationException();
}
public String getLocalName() {
throw new UnsupportedBackgroundOperationException();
}
public int getLocalPort() {
throw new UnsupportedBackgroundOperationException();
}
public String getParameter(String name) {
final Object obj = parameters.get(name);
if (obj instanceof String[]) {
return ((String[]) obj)[0];
}
return (String) obj;
}
public Map, ?> getParameterMap() {
return parameters;
}
public Enumeration> getParameterNames() {
return new IteratorEnumeration(parameters.keySet().iterator());
}
public String[] getParameterValues(String key) {
throw new UnsupportedBackgroundOperationException();
}
public String getProtocol() {
return protocol;
}
public BufferedReader getReader() throws IOException {
throw new UnsupportedBackgroundOperationException();
}
public String getRealPath(String arg0) {
throw new UnsupportedBackgroundOperationException();
}
public String getRemoteAddr() {
return remoteAddr;
}
public String getRemoteHost() {
return remoteHost;
}
public int getRemotePort() {
return remotePort;
}
public RequestDispatcher getRequestDispatcher(String arg0) {
throw new UnsupportedBackgroundOperationException();
}
public String getScheme() {
return scheme;
}
public String getServerName() {
return serverName;
}
public int getServerPort() {
return serverPort;
}
public boolean isSecure() {
return false;
}
public void removeAttribute(String name) {
attributes.remove(name);
}
public void setAttribute(String key, Object value) {
attributes.put(key, value);
}
public void setCharacterEncoding(final String encoding)
throws UnsupportedEncodingException {
this.characterEncoding = encoding;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy