Package com.adito.replacementproxy

Source Code of com.adito.replacementproxy.ProxiedResponseProcessor

        /*
*  Adito
*
*  Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
*  This program is free software; you can redistribute it and/or
*  modify it under the terms of the GNU General Public License
*  as published by the Free Software Foundation; either version 2 of
*  the License, or (at your option) any later version.
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public
*  License along with this program; if not, write to the Free Software
*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
     
package com.adito.replacementproxy;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;
import java.util.zip.GZIPInputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.maverick.http.HttpResponse;
import com.adito.boot.CaseInsensitiveMap;
import com.adito.boot.HttpConstants;
import com.adito.boot.Util;
import com.adito.core.CookieItem;
import com.adito.core.CookieMap;
import com.adito.policyframework.LaunchSession;
import com.adito.util.Utils;

/**
*/
public class ProxiedResponseProcessor {
  final static Log log = LogFactory.getLog(ProxiedResponseProcessor.class);

  private ProxiedRequestDispatcher requestDispatcher;
  private int maxAge;
  private ContentCache cache;
  private SimpleDateFormat sdf;
  private RequestProcessor requestProcessor;
  // private boolean keepAlive;
  private Date expiryDate;
  private CookieMap cookieMap;
  private String contentType;
  private int contentLength;
  private List headers;
  private boolean cacheable;
  private InputStream serverIn;
  private String charset;
  static CaseInsensitiveMap ignoreHeaders = new CaseInsensitiveMap();

  static {
    ignoreHeaders.put(HttpConstants.HDR_PROXY_CONNECTION, Boolean.TRUE);
    ignoreHeaders.put(HttpConstants.HDR_ACCEPT_ENCODING, Boolean.TRUE);
    ignoreHeaders.put(HttpConstants.HDR_TRANSFER_ENCODING, Boolean.TRUE);
    ignoreHeaders.put(HttpConstants.HDR_TE, Boolean.TRUE);
    ignoreHeaders.put(HttpConstants.HDR_TRAILER, Boolean.TRUE);
    ignoreHeaders.put(HttpConstants.HDR_PROXY_AUTHORIZATION, Boolean.TRUE);
    ignoreHeaders.put(HttpConstants.HDR_PROXY_AUTHENTICATE, Boolean.TRUE);
    ignoreHeaders.put(HttpConstants.HDR_UPGRADE, Boolean.TRUE);
    ignoreHeaders.put(HttpConstants.HDR_CONTENT_ENCODING, Boolean.TRUE);
  }

  /**
   *
   */
  public ProxiedResponseProcessor(RequestProcessor requestProcessor, ProxiedRequestDispatcher requestDispatcher, int maxAge,
                  ContentCache cache, CookieMap cookieMap) {
    this.requestDispatcher = requestDispatcher;
    this.requestProcessor = requestProcessor;
    this.maxAge = maxAge;
    this.cache = cache;
    this.cookieMap = cookieMap;
    // keepAlive = requestDispatcher.isKeepAlive();
    sdf = new SimpleDateFormat("EEEE, dd-MMM-yy HH:mm:ss zzz");
  }

  public ProxiedRequestDispatcher getRequestDispatcher() {
    return requestDispatcher;
  }

  public void processResponse() throws Exception {

    HttpResponse serverResponse = requestDispatcher.getServerResponse();
    headers = new ArrayList();

    // Determine if the response can be cached, and if so, for how long
    expiryDate = maxAge == 0 ? null : new Date(System.currentTimeMillis() + maxAge);
    cacheable = false;
    if (cache != null && HttpConstants.METHOD_GET.equals(requestProcessor.getRequestMethod())
      && requestDispatcher.getResponseCode() == HttpConstants.RESP_200_OK) {
      cacheable = true;

      // HTTP 1.0
      String cacheControl = serverResponse.getHeaderField(HttpConstants.HDR_PRAGMA);
      if (cacheControl != null && cacheControl.equalsIgnoreCase("no-cache")) {
        if (log.isDebugEnabled())
          log.debug("Not caching as server explicitly requested not to.");
        cacheable = false;
      } else {
        String expires = serverResponse.getHeaderField(HttpConstants.HDR_EXPIRES);
        if (expires != null) {
          try {
            expiryDate = sdf.parse(expires);
          } catch (Exception e2) {
          }
        }
      }

      // HTTP 1.1
      if (cacheable) {
        cacheControl = serverResponse.getHeaderField(HttpConstants.HDR_CACHE_CONTROL);
        if (cacheControl != null) {
          StringTokenizer tok = new StringTokenizer(cacheControl, ";");
          while (tok.hasMoreTokens()) {
            String t = tok.nextToken().trim();
            String tl = t.toLowerCase();
            if (t.startsWith("no-cache") || t.startsWith("no-store")) {
              cacheable = false;
              if (log.isDebugEnabled())
                log.debug("Not caching as server explicitly requested not to.");
            } else if (tl.startsWith("max-age")) {
              try {
                expiryDate.setTime(expiryDate.getTime() - (Integer.parseInt(Util.valueOfNameValuePair(tl))));
              } catch (Exception e2) {
              }
            }
          }
        }
      }
    }

    String contentEncoding = serverResponse.getHeaderField(HttpConstants.HDR_CONTENT_ENCODING);
    serverIn = serverResponse.getInputStream();

    if ("gzip".equals(contentEncoding)) {
      serverIn = new GZIPInputStream(serverIn);
    } else if ("identity".equals(contentEncoding) || contentEncoding == null) {
      // Plain
    } else {
      throw new Exception("Invalid content encoding " + serverResponse.getHeaderField(HttpConstants.HDR_CONTENT_ENCODING));
    }

    String[] challenges = serverResponse.getHeaderFields("www-authenticate");

    if (challenges != null) {
      serverResponse.removeFields("www-authenticate");

      for (int i = 0; i < challenges.length; i++) {
        if (challenges[i].toLowerCase().startsWith("basic") || challenges[i].toLowerCase().startsWith("digest")
          || challenges[i].toLowerCase().startsWith("ntlm")) {
          if(i==0)
            serverResponse.setHeaderField("WWW-Authenticate", challenges[i]);
          else
            serverResponse.addHeaderField("WWW-Authenticate", challenges[i]);
        }
      }
    }

    // response.setStatus(serverResponse.getStatus());
    // response.setReason(serverResponse.getReason());

    serverResponse.removeFields("Server");
    serverResponse.removeFields("Date");

    for (Enumeration e = serverResponse.getHeaderFieldNames(); e.hasMoreElements();) {
      String hdr = (String) e.nextElement();
      if (log.isDebugEnabled())
        log.debug("Received header " + hdr);
      String[] val = serverResponse.getHeaderFields(hdr);

      for (int i = 0; i < val.length; i++) {

        if (hdr.equalsIgnoreCase("Content-Type")) {

          StringTokenizer tok = new StringTokenizer(val[i], ";");
          while (tok.hasMoreTokens()) {
            String t = tok.nextToken().trim();
            String tl = t.toLowerCase();
            if (tl.startsWith("charset=")) {
              charset = Util.valueOfNameValuePair(t);
            } else {
              contentType = Util.valueOfNameValuePair(t);
            }
          }

          contentType = val[i];
          if (log.isDebugEnabled())
            log.debug("Received content type " + contentType + " (charset = " + charset + ")");
        } else if (hdr.equalsIgnoreCase("Content-Length")) {
          try {
            contentLength = Integer.parseInt(val[i]);
          } catch (Exception ex) {

          }
          if (log.isDebugEnabled())
            log.debug("Received content length " + contentLength);
        } else {
          if (hdr.equalsIgnoreCase("Location")) {
           
            if(log.isDebugEnabled())
              log.debug("Processing Location header value '" + val[i] + "'");
           
            URL actual;
            try {
              actual = new URL(Util.urlDecode(val[i]));
            } catch(MalformedURLException ex) {
              actual = new URL(requestProcessor.getRequestParameters().getProxiedURIDetails().getProxiedURLBase(), Util.urlDecode(val[i]));
            }

            if(cache != null) {
                cache.clear(actual.toExternalForm());
            }
           

                      URL newVal = new URL(requestProcessor.getRequestBaseURL(),
                          "/replacementProxyEngine/" + requestProcessor.getLaunchId() +
                          "/" + Util.urlEncode(Utils.htmlunescape(
                              actual.toExternalForm())));
           
           
//            URL newVal = new URL(requestProcessor.getRequestBaseURL(), "/replacementProxyEngine?" + LaunchSession.LONG_LAUNCH_ID
//              + "="
//              + requestProcessor.getLaunchId()
//              + "&sslex_url="
//              + Util.urlEncode(actual.toExternalForm()));
                     
            if (log.isDebugEnabled())
              log.debug("Found location of header " + val[i]
                + " changing to "
                + newVal
                + " ( removed "
                + actual.toExternalForm()
                + " from cache");
            val[i] = newVal.toExternalForm();
          } else if (hdr.equalsIgnoreCase("Set-Cookie")) {
            val[i] = parseCookie(val[i]);
          }
          if (log.isDebugEnabled())
            log.debug("Adding header " + hdr + " = " + val[i]);
          headers.add(new Header(hdr, val[i]));
        }

      }
    }

  }

  public List getHeaders() {
    return headers;
  }

  /**
   * @return
   */
  public String getContentType() {
    return contentType;
  }

  public String getCharset() {
    return charset;
  }

  public int getContentLength() {
    return contentLength;
  }

  /**
   * @return
   */
  public boolean isCacheable() {
    return cacheable;
  }

  public InputStream getProxiedInputStream() {
    return serverIn;
  }

  /**
   * @return
   */
  public Date getCacheExpiryDate() {
    return expiryDate;
  }
 
  String parseCookie(String val) {
    StringBuffer newVal = new StringBuffer();   
    StringTokenizer t = new StringTokenizer(val, ";");
    String elementName = null;
    String elementValue = null;

    try {
      while (t.hasMoreTokens()) {       
        /* Get the name and value of the cookie field element */
        String name = Util.trimBoth(t.nextToken());
        int idx = name.indexOf('=');
        if (idx > -1) {
          elementValue = name.substring(idx + 1);
          elementName = name.substring(0, idx);
        } else {
          elementName = name;
          elementValue = "";
        }
       
        /* Ignore domain and path, fake cookie names and include all other elements */
       
        if (elementName.equalsIgnoreCase("path") || elementName.equalsIgnoreCase("domain")) {
          // Ignore path and domain
        } else if (elementName.equalsIgnoreCase("expires") ||
                elementName.equalsIgnoreCase("max-age") ||
                elementName.equalsIgnoreCase("secure") ||
                elementName.equalsIgnoreCase("version") ||
                elementName.equalsIgnoreCase("comment") ||
                elementName.equalsIgnoreCase("httponly")) {
          // Include these
          if(newVal.length() > 0) {
            newVal.append("; ");
          }
          newVal.append(elementName);
          if(!elementValue.equals("")) {
            newVal.append("=");
            newVal.append(elementValue);
          }
        } else {
          // Assume to be a cookie name
          String fakeCookieName = Math.abs((requestProcessor.getRequestParameters().getProxiedURIDetails().getProxiedURL().getProtocol()
              + ":"
              + requestProcessor.getRequestParameters().getProxiedURIDetails().getProxiedURL().getHost()).hashCode()) + "_" + elementName;
          CookieItem cookieItem = new CookieItem(elementName, fakeCookieName);
          cookieMap.put(cookieItem);
          if(newVal.length() > 0) {
            newVal.append("; ");
          }
          newVal.append(fakeCookieName);
          if(!elementValue.equals("")) {
            newVal.append("=");
            newVal.append(Util.urlEncode(elementValue));
          }         
        }
      }
    } catch (Exception ex) {
      log.warn("Invalid cookie.", ex);
    }
    return newVal.toString();
  }
 


}
TOP

Related Classes of com.adito.replacementproxy.ProxiedResponseProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.