package org.dcache.services.httpd.util;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import dmg.util.HttpRequest;
import java.util.Base64;
/**
* Basic implementation of internal interface used to hold objects for processing
* an Http request.
*
* @author arossi
*/
public class StandardHttpRequest implements HttpRequest {
private static final Splitter PATH_SPLITTER
= Splitter.on('/').omitEmptyStrings();
private static final Logger logger
= LoggerFactory.getLogger(StandardHttpRequest.class);
private final OutputStream out;
private final PrintWriter pw;
private final HttpServletRequest request;
private final HttpServletResponse response;
private final Map<String, String> map = new HashMap<>();
private final int tokenOffset;
private final String[] tokens;
private final boolean isDirectory;
private String userName;
private String password;
private boolean authDone;
public StandardHttpRequest(HttpServletRequest request,
HttpServletResponse response) throws IOException, URISyntaxException {
this.request = request;
this.response = response;
out = response.getOutputStream();
pw = new PrintWriter(new OutputStreamWriter(out));
final Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
final String name = names.nextElement();
map.put(name, request.getHeader(name));
}
final String path = new URI(request.getRequestURI()).getPath();
isDirectory = path.endsWith("/");
tokens = Iterables.toArray(PATH_SPLITTER.split(path), String.class);
tokenOffset = 1;
setContentType("text/html");
}
@Override
public OutputStream getOutputStream() {
return out;
}
@Override
public String getParameter(String parameter) {
return request.getParameter(parameter);
}
@Override
public String getPassword() {
doAuthorization();
return password;
}
@Override
public PrintWriter getPrintWriter() {
return pw;
}
@Override
public Map<String, String> getRequestAttributes() {
return map;
}
@Override
public int getRequestTokenOffset() {
return tokenOffset;
}
@Override
public String[] getRequestTokens() {
return tokens;
}
@Override
public String getUserName() {
return userName;
}
@Override
public boolean isAuthenticated() {
doAuthorization();
return userName != null;
}
@Override
public boolean isDirectory() {
return isDirectory;
}
@Override
public void printHttpHeader(int size) {
if (size > 0) {
response.setContentLength(size);
}
}
@Override
public void setContentType(String type) {
response.setContentType(type);
}
private synchronized void doAuthorization() {
if (authDone) {
return;
}
authDone = true;
String auth = request.getHeader("Authorization");
if (auth == null) {
return;
}
StringTokenizer st = new StringTokenizer(auth);
if (st.countTokens() < 2) {
return;
}
if (!st.nextToken().equals("Basic")) {
return;
}
auth = new String(Base64.getDecoder().decode(st.nextToken()));
logger.info("Authentication : >{}<", auth);
st = new StringTokenizer(auth, ":");
if (st.countTokens() < 2) {
return;
}
userName = st.nextToken();
password = st.nextToken();
}
}