com.codename1.corsproxy.CORSProxy.java Source code

Java tutorial

Introduction

Here is the source code for com.codename1.corsproxy.CORSProxy.java

Source

/*
 * 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 com.codename1.corsproxy;

import java.io.IOException;
import java.net.HttpCookie;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;

/**
 *
 * @author shannah
 */
@WebServlet(urlPatterns = { "/cn1-cors-proxy" }, initParams = {
        @WebInitParam(name = "targetUri", value = "{_target}"), @WebInitParam(name = "log", value = "true"),
        @WebInitParam(name = "http.protocol.handle-redirects", value = "false") })
public class CORSProxy extends org.mitre.dsmiley.httpproxy.URITemplateProxyServlet {

    @Override
    public void init() throws ServletException {
        super.init();

    }

    @Override
    protected void copyProxyCookie(HttpServletRequest servletRequest, HttpServletResponse servletResponse,
            Header header) {
        List<HttpCookie> cookies = HttpCookie.parse(header.getValue());
        String path = servletRequest.getContextPath(); // path starts with / or is empty string
        path += servletRequest.getServletPath(); // servlet path starts with / or is empty string

        for (HttpCookie cookie : cookies) {
            //set cookie name prefixed w/ a proxy value so it won't collide w/ other cookies
            String proxyCookieName = getCookieNamePrefix() + cookie.getName();
            Cookie servletCookie = new Cookie(proxyCookieName, cookie.getValue());
            servletCookie.setComment(cookie.getComment());
            servletCookie.setMaxAge((int) cookie.getMaxAge());
            servletCookie.setPath(path); //set to the path of the proxy servlet
            // don't set cookie domain
            //servletCookie.setSecure(cookie.getSecure());
            servletCookie.setSecure(false);
            servletCookie.setVersion(cookie.getVersion());
            servletResponse.addCookie(servletCookie);
        }
    }

    protected String getRealCookie(String cookieValue) {
        StringBuilder escapedCookie = new StringBuilder();
        String cookies[] = cookieValue.split("; ");
        for (String cookie : cookies) {
            String cookieSplit[] = cookie.split("=");
            if (cookieSplit.length == 2) {
                String cookieName = cookieSplit[0];
                if (cookieName.startsWith(getCookieNamePrefix())) {
                    cookieName = cookieName.substring(getCookieNamePrefix().length());
                    if (escapedCookie.length() > 0) {
                        escapedCookie.append("; ");
                    }
                    escapedCookie.append(cookieName).append("=").append(cookieSplit[1]);
                }
            }

            cookieValue = escapedCookie.toString();
        }
        return cookieValue;
    }

    @Override
    protected void copyResponseHeaders(final HttpResponse proxyResponse, final HttpServletRequest servletRequest,
            final HttpServletResponse servletResponse) {

        HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(servletResponse) {

            @Override
            public void addHeader(String name, String value) {
                if ("Location".equalsIgnoreCase(name)) {
                    super.addHeader("X-CN1-" + name, value);

                } else if ("Content-Security-Policy".equalsIgnoreCase(name)) {

                } else {
                    super.addHeader(name, value);
                }
            }

        };
        super.copyResponseHeaders(proxyResponse, servletRequest, responseWrapper); //To change body of generated methods, choose Tools | Templates.
        servletResponse.setHeader("Access-Control-Expose-Headers", "Set-Cookie, Set-Cookie2");
        Collection<String> cookies = servletResponse.getHeaders("Set-Cookie");
        if (cookies != null) {
            for (String cookie : cookies) {
                servletResponse.addHeader("X-CN1-Set-Cookie", cookie);
            }
        }

        //servletResponse.setHeader("Access-Control-Allow-Origin", "*");

    }

    @Override
    protected void service(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
            throws ServletException, IOException {
        super.service(servletRequest, servletResponse);
        if (servletResponse.getStatus() >= 300 && servletResponse.getStatus() < 400) {
            // XMLHTTPRequest automatically follows redirects.  We don't want that, so we'll
            // convert 3xx status to non-standard header that we will parse on the other side.
            servletResponse.setIntHeader("X-CN1-Status", servletResponse.getStatus());
            servletResponse.setStatus(200);
        }
    }

    protected boolean doResponseRedirectOrNotModifiedLogic(HttpServletRequest servletRequest,
            HttpServletResponse servletResponse, HttpResponse proxyResponse, int statusCode)
            throws ServletException, IOException {

        // 304 needs special handling.  See:
        // http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code304
        // We get a 304 whenever passed an 'If-Modified-Since'
        // header and the data on disk has not changed; server
        // responds w/ a 304 saying I'm not going to send the
        // body because the file has not changed.
        if (statusCode == HttpServletResponse.SC_NOT_MODIFIED) {
            servletResponse.setIntHeader(HttpHeaders.CONTENT_LENGTH, 0);
            servletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            return true;
        }
        return false;
    }

    @Override
    protected void copyRequestHeaders(HttpServletRequest servletRequest, HttpRequest proxyRequest) {

        HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(servletRequest) {

            @Override
            public Enumeration<String> getHeaderNames() {
                Enumeration<String> names = super.getHeaderNames();
                Vector<String> filteredNames = new Vector<String>();
                boolean foundCookie = false;
                boolean foundRealCookie = false;
                while (names.hasMoreElements()) {
                    String name = names.nextElement();
                    Enumeration<String> vals = this.getHeaders(name);

                    if (!name.equalsIgnoreCase("Referer") && !name.equalsIgnoreCase("Host")
                            && !name.equalsIgnoreCase("origin")) {
                        filteredNames.add(name);
                    }
                    if (name.equalsIgnoreCase("X-CN1-Cookie")) {
                        foundCookie = true;
                    }
                    if (name.equalsIgnoreCase("Cookie")) {
                        foundRealCookie = true;
                    }
                }

                if (foundCookie && !foundRealCookie) {
                    filteredNames.add("Cookie");
                }

                return filteredNames.elements();
            }

            @Override
            public Enumeration<String> getHeaders(String name) {

                Enumeration<String> headers = super.getHeaders(name);
                Vector<String> out = new Vector<String>();
                while (headers.hasMoreElements()) {
                    out.add(headers.nextElement());
                }
                if ("Cookie".equalsIgnoreCase(name)) {
                    Enumeration<String> xHeaders = getHeaders("X-CN1-Cookie");
                    while (xHeaders.hasMoreElements()) {
                        out.add(xHeaders.nextElement());
                    }
                }
                return out.elements();
            }

        };
        super.copyRequestHeaders(requestWrapper, proxyRequest);
    }

}