ProxyByHttpClient4.java
package sk.iway.iwcm.components.proxy;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import sk.iway.iwcm.Identity;
import sk.iway.iwcm.Logger;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.components.proxy.jpa.ProxyBean;
import sk.iway.iwcm.doc.DocDB;
import sk.iway.iwcm.doc.DocDetails;
import sk.iway.iwcm.system.context.ContextFilter;
import sk.iway.iwcm.tags.WriteTag;
import sk.iway.iwcm.users.UsersDB;
/**
* ProxyByHttpClient.java - proxy vykonane pomocou JakartaHttpClienta, vie modifikovat encoding
*
*@Title webjet4
*@Company Interway s.r.o. (www.interway.sk)
*@Copyright Interway s.r.o. (c) 2001-2008
*@author $Author: jeeff $
*@version $Revision: 1.4 $
*@created Date: 10.11.2008 13:43:48
*@modified $Date: 2009/09/10 19:59:49 $
*/
@SuppressWarnings("deprecation")
public class ProxyByHttpClient4
{
//public static String AUTH_STATE_KEY = "ProxyByHttpClient.authStateKey";
protected ProxyByHttpClient4() {
//utility class
}
public static void service(ProxyBean proxy, HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
{
Logger.debug(ProxyByHttpClient4.class, "ProxyByHttpClient - service");
String path = null;
String data = null;
try
{
String originalURI = req.getRequestURI();
if (ContextFilter.isRunning(req)) originalURI = ContextFilter.removeContextPath(req.getContextPath(), originalURI);
req.setAttribute("path_filter_orig_path", originalURI);
String localUrl = ProxyDB.getLocalUrl(proxy, originalURI);
path = proxy.getRemoteUrl() + originalURI.substring(localUrl.length());
//path = Tools.replace(path, ".wsp", ".asp");
Logger.debug(ProxyByHttpClient4.class, "path:"+path);
req.setAttribute("path_filter_proxy_path", path);
boolean includeIntoPage = Proxy.isIncludeIntoPage(proxy, path);
String fullPath = null;
if (proxy.getRemoteServer().startsWith("http")==false)
{
fullPath = "http";
if (443==proxy.getRemotePort()) {
fullPath += "s";
}
fullPath += "://"+proxy.getRemoteServer() + ":" + proxy.getRemotePort() + path;
}
else
{
fullPath = proxy.getRemoteServer() + ":" + proxy.getRemotePort() + path;
}
//prekoduj na cielove kodovanie
String pathIncludingQuery = fullPath;
if (req.getQueryString()!=null && req.getQueryString().length()>1)
{
pathIncludingQuery = fullPath + "?" + req.getQueryString();
pathIncludingQuery = Tools.replace(pathIncludingQuery, "{", "%7B");
pathIncludingQuery = Tools.replace(pathIncludingQuery, "}", "%7D");
}
Logger.debug(ProxyByHttpClient4.class, "fullPath:"+fullPath);
CloseableHttpClient client = null;
HttpClientContext context = HttpClientContext.create();
if (client == null)
{
client = HttpClients.createDefault();
}
if (proxy.getRemoteServer().startsWith("https"))
{
//Protocol.registerProtocol("https", new Protocol("https", new EasySSLProtocolSocketFactory(), 443));
}
if ("ntlm".equalsIgnoreCase(proxy.getAuthMethod()))
{
//client.getParams().setAuthenticationPreemptive(true);
//CredentialsProvider defaultcreds = new NTCredentials(proxy.getAuthUsername(), proxy.getAuthPassword(), proxy.getAuthHost(), proxy.getAuthDomain());
//client.getParams().setCredentials(new AuthScope(proxy.getAuthHost(), proxy.getRemotePort(), AuthScope.ANY_REALM), defaultcreds);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new NTCredentials(proxy.getAuthUsername(), proxy.getAuthPassword(), proxy.getAuthHost(), proxy.getAuthDomain()));
context.setCredentialsProvider(credsProvider);
}
else if ("basic".equalsIgnoreCase(proxy.getAuthMethod()))
{
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxy.getAuthUsername(), proxy.getAuthPassword()));
context.setCredentialsProvider(credsProvider);
}
if (Tools.isNotEmpty(proxy.getAllowedMethods()))
{
if (proxy.getAllowedMethods().toLowerCase().contains(req.getMethod().toLowerCase())==false)
{
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
}
//WebJETProxySelector.setProxyForHttpClient(client, fullPath);
HttpRequestBase method = null;
if ("GET".equalsIgnoreCase(req.getMethod()))
{
Logger.debug(ProxyByHttpClient4.class,"JE TO GET: " + pathIncludingQuery);
//method = (GetMethod)req.getSession().getAttribute("proxyHttpClientMethod");
if (method == null)
{
method = new HttpGet(pathIncludingQuery);
//req.getSession().setAttribute("proxyHttpClientMethod", method);
}
}
else
{
if (req.getHeader("Content-type")!=null && req.getHeader("Content-type").indexOf("multipart/form-data")!=-1)
{
/*
Logger.debug(ProxyByHttpClient4.class,"JE TO POST (multipart): " + fullPath);
MultipartPostMethod pmethod = new MultipartPostMethod(fullPath);
pmethod.setRequestHeader("Content-type", "multipart/form-data;");
DiskFileUpload fu = new DiskFileUpload();
// maximum size before a FileUploadException will be thrown
fu.setSizeMax(100000000);
// maximum size that will be stored in memory
fu.setSizeThreshold(0);
// the location for saving data that is larger than getSizeThreshold()
File uploadDir = new File(Tools.getRealPath("/WEB-INF/tmp/upload-"+Tools.getNow()+"/"));
if(uploadDir.mkdirs() == false)
throw new FileUploadException("Unable to create directory "+"/WEB-INF/tmp/upload-"+Tools.getNow()+"/");
fu.setRepositoryPath(uploadDir.getPath());
List<FileItem> fileItems = fu.parseRequest(req);
for (FileItem file : fileItems)
{
if (file.isFormField())
{
Logger.debug(ProxyByHttpClient4.class, "Adding parameter: " + file.getFieldName());
String value = file.getString(SetCharacterEncodingFilter.getEncoding());
Logger.debug(ProxyByHttpClient4.class,"param: " + file.getFieldName()+"="+value);
//pmethod.addParameter(file.getFieldName(), value);
StringPart sp = new StringPart(file.getFieldName(), value, proxy.getEncoding());
//inak nam tam nastavovalo transfer encoding s cim mali ASP uploady problem
sp.setTransferEncoding(null);
pmethod.addPart(sp);
}
}
for (FileItem file : fileItems)
{
if (file.isFormField()==false && file instanceof DefaultFileItem)
{
DefaultFileItem dfi = (DefaultFileItem)file;
Logger.debug(ProxyByHttpClient4.class,"Adding FILE: " + file.getFieldName()+"="+dfi.getStoreLocation().getPath());
//pmethod.addParameter(file.getFieldName(), file.getName(), dfi.getStoreLocation());
FilePart fp = new FilePart(file.getFieldName(), file.getName(), dfi.getStoreLocation());
pmethod.addPart(fp);
}
}
//vymaz subory z tmp adresara
method = pmethod;
*/
}
else
{
Logger.debug(ProxyByHttpClient4.class,"JE TO POST: " + pathIncludingQuery);
HttpPost pmethod = new HttpPost(pathIncludingQuery);
pmethod.setHeader("Content-type", "application/x-www-form-urlencoded; charset="+proxy.getEncoding());
Enumeration<String> params = req.getParameterNames();
int i;
String[] values;
String name;
List<NameValuePair> nvps = new ArrayList<>();
while (params.hasMoreElements())
{
name = params.nextElement();
values = req.getParameterValues(name);
for (i=0; i<values.length; i++)
{
Logger.debug(ProxyByHttpClient4.class,"param: " + name+"="+values[i]);
//pmethod.getParams().setParameter(name, values[i]);
nvps.add(new BasicNameValuePair(name, values[i]));
}
}
pmethod.setEntity(new UrlEncodedFormEntity(nvps, proxy.getEncoding()));
method = pmethod;
}
}
if (method != null) {
//preposli hlavicky
Enumeration<String> en = req.getHeaderNames();
while (en.hasMoreElements())
{
String key = en.nextElement();
// Filter incoming headers:
if ("Host".equalsIgnoreCase(key))
{
String value = proxy.getRemoteServer();
//remove http/s prefix
if (value.startsWith("http")) {
value = value.substring(value.indexOf("://")+3);
}
Logger.debug(ProxyByHttpClient4.class, "header: " + key + ": " + value);
method.addHeader(key, value);
}
else if ("Connection".equalsIgnoreCase(key) || "If-Modified-Since".equalsIgnoreCase(key) ||
"If-None-Match".equalsIgnoreCase(key) || "Accept-Encoding".equalsIgnoreCase(key) ||
"Cookie".equalsIgnoreCase(key) || "content-type".equalsIgnoreCase(key) || "content-length".equalsIgnoreCase(key))
{
//tieto preskakujem
Logger.debug(ProxyByHttpClient4.class, "header: SKIP " + key + ": " + req.getHeader(key));
}
else if ("authorization".equalsIgnoreCase(key))
{
//nastavujeme dole
Logger.debug(ProxyByHttpClient4.class, "header: SKIP " + key + ": " + req.getHeader(key));
}
else
{
String value = req.getHeader(key);
method.addHeader(key, value);
Logger.debug(ProxyByHttpClient4.class, "header: " + key + ": " + value);
}
}
Principal principal = req.getUserPrincipal();
if (principal != null && Tools.isNotEmpty(principal.getName()))
{
Logger.debug(ProxyByHttpClient4.class, "header: AUTH_USER_CMS: " + principal.getName());
method.addHeader("AUTH_USER_CMS", principal.getName());
}
else
{
Identity user = UsersDB.getCurrentUser(req);
if (user != null)
{
Logger.debug(ProxyByHttpClient4.class, "header: AUTH_USER_CMS: " + user.getLogin());
method.addHeader("AUTH_USER_CMS", user.getLogin());
}
}
}
/*
String authState = (String)req.getSession().getAttribute(AUTH_STATE_KEY);
Logger.debug(ProxyByHttpClient.class, "authState: "+authState);
if (authState == null)
{
}
else if ("NTLM".equals(authState))
{
String value = "NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFAs4OAAAADw==";
Logger.debug(ProxyByHttpClient.class, "header: authorization1: " + value);
method.addRequestHeader("authorization", value);
}
else if (authState.startsWith("NTLM"))
{
//String value = Tools.replace(req.getHeader("authorization"), "Negotiate", "NTLM");
String value = req.getHeader("authorization");
Logger.debug(ProxyByHttpClient.class, "header: authorization2: " + value);
method.addRequestHeader("authorization", value);
}
*/
//String responseBody = null;
CloseableHttpResponse hcResponse = null;
try{
//
hcResponse = client.execute(method, context);
//responseBody = method.getResponseBodyAsString();
} catch (IOException ioe){
Logger.error(ProxyByHttpClient4.class,"Unable to connect to '" + path + "'");
Logger.error(ProxyByHttpClient4.class,ioe.getMessage());
sk.iway.iwcm.Logger.error(ioe);
}
/**
Cookie[] cookies = state.getCookies();
// Display the cookies
Logger.debug(ProxyByHttpClient4.class, "STATE Present cookies: ");
for (int i = 0; i < cookies.length; i++)
{
Logger.debug(ProxyByHttpClient4.class, " - " + cookies[i].toExternalForm());
}
*/
if (hcResponse != null) {
Logger.debug(ProxyByHttpClient4.class,"*** Response ***");
Logger.debug(ProxyByHttpClient4.class,"Status Line: " + hcResponse.getStatusLine());
Header[] responseHeaders = hcResponse.getAllHeaders();
Header h;
for (int i=0; i<responseHeaders.length; i++)
{
h = responseHeaders[i];
//Logger.debug(this,responseHeaders[i]);
if (h.getName()!=null && h.getValue() != null)
{
Logger.debug(ProxyByHttpClient4.class,h.getName()+": "+h.getValue());
}
/*
if (h.getName().indexOf("Authenticate")!=-1)
{
response.setStatus(401);
response.setHeader(h.getName(), h.getValue());
req.getSession().setAttribute(AUTH_STATE_KEY, h.getValue());
includeIntoPage = false;
}
*/
if (h.getName().equalsIgnoreCase("Location"))
{
String value = h.getValue();
Logger.debug(ProxyByHttpClient4.class, "Original location: " + value);
if (value.startsWith("http"))
{
value = value.substring(value.indexOf('/', 10));
}
//urci nove URL
if (value.startsWith(proxy.getRemoteUrl())) value = localUrl + value.substring(proxy.getRemoteUrl().length());
//dopln nasu cestu
if (value.charAt(0)!='/') value = localUrl + value;
Logger.debug(ProxyByHttpClient4.class, "Redirecting to: " + value);
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
response.setHeader(h.getName(), value);
}
}
HttpEntity entity = hcResponse.getEntity();
if (includeIntoPage)
{
//vkladam vystup do WebJETu
StringBuilder sb = new StringBuilder();
BufferedInputStream is = new BufferedInputStream(entity.getContent());
InputStreamReader in = new InputStreamReader(is, proxy.getEncoding());
char[] buffer = new char[8000];
int n = 0;
while (true)
{
n = in.read(buffer);
if (n < 1) break;
sb.append(buffer, 0, n);
}
in.close();
data = sb.toString();
req.setAttribute("proxyOutputDataNoCrop", data);
//Logger.debug(ProxyByHttpClient4.class, "Proxy response:\n"+data);
if (Tools.isNotEmpty(proxy.getCropStart()) && Tools.isNotEmpty(proxy.getCropEnd()))
{
try
{
if (proxy.isKeepCropEnd()==false) data = ProxyDB.getCleanBodyIncludeStartNoEnd(data, proxy.getCropStart(), proxy.getCropEnd());
else data = ProxyDB.getCleanBodyIncludeStartEnd(data, proxy.getCropStart(), proxy.getCropEnd());
if (proxy.isKeepCropStart()==false) data = data.substring(proxy.getCropStart().length());
}
catch (Exception ex)
{
sk.iway.iwcm.Logger.error(ex);
}
}
req.setAttribute("proxyOutputData", data);
//ziskaj docid
//stranka ma nastavenu takuto virtualnu cestu
DocDB docDB = DocDB.getInstance();
//kvoli sharepointu kde mapujeme priecinky podla roznych parametrov #16338
String testURL = originalURI+"?"+req.getQueryString();
int docId = docDB.getVirtualPathDocId(testURL, DocDB.getDomain(req));
//musime spravit toto inak sa nam vrati * URL a nikdy sa nevojde do bloku docId < 1
DocDetails testDoc = docDB.getBasicDocDetails(docId, false);
if (testDoc != null && testDoc.getVirtualPath().indexOf("*")!=-1) docId = -1;
Logger.debug(ProxyByHttpClient4.class, "Tested URL "+testURL+" returned docId="+docId);
if (docId < 1)
{
testURL = originalURI+"?RootFolder="+Tools.replace(Tools.URLEncode(req.getParameter("RootFolder")), "_", "%5F");
docId = docDB.getVirtualPathDocId(testURL, DocDB.getDomain(req));
testDoc = docDB.getBasicDocDetails(docId, false);
if (testDoc != null && testDoc.getVirtualPath().indexOf("*")!=-1) docId = -1;
Logger.debug(ProxyByHttpClient4.class, "Tested URL "+testURL+" returned docId="+docId);
}
if (docId < 1)
{
testURL = originalURI;
docId = docDB.getVirtualPathDocId(testURL, DocDB.getDomain(req));
Logger.debug(ProxyByHttpClient4.class, "Tested URL "+testURL+" returned docId="+docId);
}
String wjforward = req.getParameter("wjforward");
if (Tools.isNotEmpty(wjforward) && wjforward.startsWith("/components") && wjforward.indexOf("search")!=-1 && wjforward.indexOf("ajax")!=-1 && wjforward.endsWith(".jsp"))
{
testURL = wjforward;
testURL = WriteTag.getCustomPage(testURL, req);
Logger.debug(ProxyByHttpClient4.class, "Forwarding to: " + testURL );
req.getRequestDispatcher(testURL).forward(req, response);
}
else
{
Logger.debug(ProxyByHttpClient4.class, "Forwarding to: " + testURL + " (" + docId + ")");
req.getRequestDispatcher("/showdoc.do?docid="+docId).forward(req, response);
}
}
else
{
response.setContentType(entity.getContentType().getValue());
copyStream(entity.getContent(), response.getOutputStream());
}
/*
*
state = client.getState();
req.getSession().setAttribute(STATE_KEY, state);
*/
//clean up the connection resources
hcResponse.close();
}
if (method != null) method.releaseConnection();
client.close();
req.setAttribute("proxyOutputData", data);
}
catch (Exception e)
{
sk.iway.iwcm.Logger.error(e);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Socket opening: " + proxy.getRemoteServer() + ":" + proxy.getRemotePort()+path);
}
}
private static void copyStream(InputStream in, OutputStream out) throws IOException
{
BufferedInputStream bin = new BufferedInputStream(in);
Logger.debug(ProxyByHttpClient4.class, "REQUEST: ------------------------------");
StringBuilder sb = new StringBuilder();
byte[] buff = new byte[8000];
int len;
while ((len = bin.read(buff)) != -1)
{
Logger.debug(ProxyByHttpClient4.class, "Writing "+len+" bytes");
out.write(buff, 0, len);
sb.append(new String(buff, 0, len));
}
Logger.debug(ProxyByHttpClient4.class, sb.toString());
Logger.debug(ProxyByHttpClient4.class, "REQUEST KONIEC-------------------------");
}
}