Skip to content

Commit

Permalink
Update to support proxy setting multiple Cookies (#779)
Browse files Browse the repository at this point in the history
  • Loading branch information
phuongnq authored Feb 4, 2025
1 parent 1371db2 commit 765bf1c
Showing 1 changed file with 27 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
* Copyright (C) 2007-2025 Crafter Software Corporation. 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 version 3 as published by
Expand All @@ -15,10 +15,7 @@
*/
package org.craftercms.engine.util.servlet;

import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.*;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.craftercms.engine.websocket.WsUpgradeHandler;
Expand Down Expand Up @@ -96,20 +93,34 @@ protected HttpRequest newProxyRequestWithEntity(String method, String proxyReque
}

/**
* Override how ProxyServlet copy response headers.
* If a header is added via HttpProxyFilter, do not add it again
* Overrides how ProxyServlet copies response headers from the proxied response to the client response.
* This method ensures that headers added by HttpProxyFilter are not duplicated.
* Additionally, it handles special cases for headers like SET_COOKIE, SET_COOKIE2, and LOCATION.
*
* @param proxyResponse
* @param servletRequest
* @param servletResponse
* @param servletRequest The HttpServletRequest from the client.
* @param servletResponse The HttpServletResponse to the client.
* @param header The header from the proxied response that needs to be copied.
* Special handling includes:
* - Skip copying hop-by-hop headers as they are not meant to be forwarded.
* - For SET_COOKIE and SET_COOKIE2 headers, cookies are processed and set in the client response.
* - For the LOCATION header, the URL is rewritten to ensure it points to the correct destination.
* - For other headers, the header is only added if it does not already exist in the client response.
*/
@Override
protected void copyResponseHeaders(HttpResponse proxyResponse, HttpServletRequest servletRequest,
HttpServletResponse servletResponse) {
for (Header header : proxyResponse.getAllHeaders()) {
if (!servletResponse.containsHeader(header.getName())) {
copyResponseHeader(servletRequest, servletResponse, header);
}
protected void copyResponseHeader(HttpServletRequest servletRequest,
HttpServletResponse servletResponse, Header header) {
String headerName = header.getName();
if (hopByHopHeaders.containsHeader(headerName))
return;
String headerValue = header.getValue();
if (headerName.equalsIgnoreCase(org.apache.http.cookie.SM.SET_COOKIE) ||
headerName.equalsIgnoreCase(org.apache.http.cookie.SM.SET_COOKIE2)) {
copyProxyCookie(servletRequest, servletResponse, headerValue);
} else if (headerName.equalsIgnoreCase(HttpHeaders.LOCATION)) {
// LOCATION Header may have to be rewritten.
servletResponse.addHeader(headerName, rewriteUrlFromResponse(servletRequest, headerValue));
} else if (!servletResponse.containsHeader(header.getName())) {
servletResponse.addHeader(headerName, headerValue);
}
}

Expand Down

0 comments on commit 765bf1c

Please sign in to comment.