List of usage examples for javax.servlet.http HttpServletRequest getHeaders
public Enumeration<String> getHeaders(String name);
Enumeration
of String
objects. From source file:org.apache.cocoon.servlet.DebugFilter.java
/** * Log debug information about the current environment. * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) *///w ww . j a v a2 s . c o m public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException { // we don't do debug msgs if this is not a http servlet request if (!(req instanceof HttpServletRequest)) { filterChain.doFilter(req, res); return; } try { ++activeRequestCount; final HttpServletRequest request = (HttpServletRequest) req; if (getLogger().isDebugEnabled()) { final StringBuffer msg = new StringBuffer(); msg.append("DEBUGGING INFORMATION:").append(lineSeparator); msg.append("REQUEST: ").append(request.getRequestURI()).append(lineSeparator).append(lineSeparator); msg.append("CONTEXT PATH: ").append(request.getContextPath()).append(lineSeparator); msg.append("SERVLET PATH: ").append(request.getServletPath()).append(lineSeparator); msg.append("PATH INFO: ").append(request.getPathInfo()).append(lineSeparator).append(lineSeparator); msg.append("REMOTE HOST: ").append(request.getRemoteHost()).append(lineSeparator); msg.append("REMOTE ADDRESS: ").append(request.getRemoteAddr()).append(lineSeparator); msg.append("REMOTE USER: ").append(request.getRemoteUser()).append(lineSeparator); msg.append("REQUEST SESSION ID: ").append(request.getRequestedSessionId()).append(lineSeparator); msg.append("REQUEST PREFERRED LOCALE: ").append(request.getLocale().toString()) .append(lineSeparator); msg.append("SERVER HOST: ").append(request.getServerName()).append(lineSeparator); msg.append("SERVER PORT: ").append(request.getServerPort()).append(lineSeparator) .append(lineSeparator); msg.append("METHOD: ").append(request.getMethod()).append(lineSeparator); msg.append("CONTENT LENGTH: ").append(request.getContentLength()).append(lineSeparator); msg.append("PROTOCOL: ").append(request.getProtocol()).append(lineSeparator); msg.append("SCHEME: ").append(request.getScheme()).append(lineSeparator); msg.append("AUTH TYPE: ").append(request.getAuthType()).append(lineSeparator).append(lineSeparator); msg.append("CURRENT ACTIVE REQUESTS: ").append(activeRequestCount).append(lineSeparator); // log all of the request parameters final Enumeration e = request.getParameterNames(); msg.append("REQUEST PARAMETERS:").append(lineSeparator).append(lineSeparator); while (e.hasMoreElements()) { String p = (String) e.nextElement(); msg.append("PARAM: '").append(p).append("' ").append("VALUES: '"); String[] params = request.getParameterValues(p); for (int i = 0; i < params.length; i++) { msg.append("[" + params[i] + "]"); if (i != (params.length - 1)) { msg.append(", "); } } msg.append("'").append(lineSeparator); } // log all of the header parameters final Enumeration e2 = request.getHeaderNames(); msg.append("HEADER PARAMETERS:").append(lineSeparator).append(lineSeparator); while (e2.hasMoreElements()) { String p = (String) e2.nextElement(); msg.append("PARAM: '").append(p).append("' ").append("VALUES: '"); Enumeration e3 = request.getHeaders(p); while (e3.hasMoreElements()) { msg.append("[" + e3.nextElement() + "]"); if (e3.hasMoreElements()) { msg.append(", "); } } msg.append("'").append(lineSeparator); } msg.append(lineSeparator).append("SESSION ATTRIBUTES:").append(lineSeparator).append(lineSeparator); // log all of the session attributes final HttpSession session = ((HttpServletRequest) req).getSession(false); if (session != null) { // Fix bug #12139: Session can be modified while still // being enumerated here synchronized (session) { final Enumeration se = session.getAttributeNames(); while (se.hasMoreElements()) { String p = (String) se.nextElement(); msg.append("PARAM: '").append(p).append("' ").append("VALUE: '") .append(session.getAttribute(p)).append("'").append(lineSeparator); } } } getLogger().debug(msg.toString()); } // Delegate filterChain.doFilter(request, res); } finally { --activeRequestCount; } }
From source file:org.codehaus.wadi.web.impl.StandardHttpProxy.java
protected void doProxy(URI uri, WebInvocation context) throws ProxyingException { HttpServletRequest req = context.getHreq(); HttpServletResponse res = context.getHres(); String requestURI = getRequestURI(req); String qs = req.getQueryString(); if (qs != null) { requestURI = new StringBuffer(requestURI).append("?").append(qs).toString(); }/*from w ww. j a va 2 s. c o m*/ URL url = null; try { url = new URL("http", uri.getHost(), uri.getPort(), requestURI); if (_log.isTraceEnabled()) _log.trace("proxying to: " + url); } catch (MalformedURLException e) { if (_log.isWarnEnabled()) _log.warn("bad proxy url: " + url, e); throw new IrrecoverableException("bad proxy url", e); } long startTime = System.currentTimeMillis(); HttpURLConnection huc = null; String m = req.getMethod(); try { huc = (HttpURLConnection) url.openConnection(); // IOException huc.setRequestMethod(m); // ProtocolException } catch (ProtocolException e) { if (_log.isWarnEnabled()) _log.warn("unsupported http method: " + m, e); throw new IrrecoverableException("unsupported HTTP method: " + m, e); } catch (IOException e) { if (_log.isWarnEnabled()) _log.warn("proxy IO problem", e); throw new RecoverableException("could not open proxy connection", e); } huc.setAllowUserInteraction(false); huc.setInstanceFollowRedirects(false); // check connection header // TODO - this might need some more time: see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html String connectionHdr = req.getHeader("Connection"); // TODO - what if there are multiple values ? if (connectionHdr != null) { connectionHdr = connectionHdr.toLowerCase(); if (connectionHdr.equals("keep-alive") || connectionHdr.equals("close")) connectionHdr = null; // TODO ?? } // copy headers - inefficient, but we are constrained by servlet API { for (Enumeration e = req.getHeaderNames(); e.hasMoreElements();) { String hdr = (String) e.nextElement(); String lhdr = hdr.toLowerCase(); if (_DontProxyHeaders.contains(lhdr)) continue; if (connectionHdr != null && connectionHdr.indexOf(lhdr) >= 0) // what is going on here ? continue; // HTTP/1.1 proxies MUST parse the Connection header field before a message is forwarded and, for each connection-token in this field, remove any header field(s) from the message with the same name as the connection-token. Connection options are signaled by the presence of a connection-token in the Connection header field, not by any corresponding additional header field(s), since the additional header field may not be sent if there are no parameters associated with that connection option if (_WADI_IsSecure.equals(hdr)) // don't worry about case - we should be the only one messing with this header... continue; // strip this out - we may be being spoofed for (Enumeration f = req.getHeaders(hdr); f.hasMoreElements();) { String val = (String) f.nextElement(); if (val != null) { huc.addRequestProperty(hdr, val); } } } } // content ? boolean hasContent = false; { int contentLength = 0; String tmp = huc.getRequestProperty("Content-Length"); if (tmp != null) { try { contentLength = Integer.parseInt(tmp); } catch (NumberFormatException ignore) { // ignore } } if (contentLength > 0) hasContent = true; else hasContent = (huc.getRequestProperty("Content-Type") != null); } // proxy { huc.addRequestProperty("Via", "1.1 " + req.getLocalName() + ":" + req.getLocalPort() + " \"WADI\""); // TODO - should we be giving out personal details ? huc.addRequestProperty("X-Forwarded-For", req.getRemoteAddr()); // adds last link in request chain... // String tmp=uc.getRequestProperty("Max-Forwards"); // TODO - do we really need to bother with this ? } // cache-control { String cacheControl = huc.getRequestProperty("Cache-Control"); if (cacheControl != null && (cacheControl.indexOf("no-cache") >= 0 || cacheControl.indexOf("no-store") >= 0)) huc.setUseCaches(false); } // confidentiality { if (req.isSecure()) { huc.addRequestProperty(_WADI_IsSecure, req.getLocalAddr().toString()); } // at the other end, if this header is present we must : // wrap the request so that req.isSecure()=true, before processing... // mask the header - so it is never seen by the app. // the code for the other end should live in this class. // this code should also confirm that it not being spoofed by confirming that req.getRemoteAddress() is a cluster member... } // customize Connection huc.setDoInput(true); // client->server int client2ServerTotal = 0; { if (hasContent) { huc.setDoOutput(true); OutputStream toServer = null; try { InputStream fromClient = req.getInputStream(); // IOException toServer = huc.getOutputStream(); // IOException client2ServerTotal = copy(fromClient, toServer, 8192); } catch (IOException e) { new IrrecoverableException("problem proxying client request to server", e); } finally { if (toServer != null) { try { toServer.close(); // IOException } catch (IOException e) { _log.warn("problem closing server request stream", e); } } } } } // Connect try { huc.connect(); // IOException } catch (IOException e) { if (_log.isWarnEnabled()) _log.warn("proxy connection problem: " + url, e); throw new RecoverableException("could not connect to proxy target", e); } InputStream fromServer = null; // handler status codes etc. int code = 0; if (huc == null) { try { fromServer = huc.getInputStream(); // IOException } catch (IOException e) { if (_log.isWarnEnabled()) _log.warn("proxying problem", e); throw new IrrecoverableException("problem acquiring client output", e); } } else { code = 502; // String message="Bad Gateway: could not read server response code or message"; try { code = huc.getResponseCode(); // IOException // message=huc.getResponseMessage(); // IOException } catch (IOException e) { if (_log.isWarnEnabled()) _log.warn("proxying problem", e); throw new IrrecoverableException("problem acquiring http server response code/message", e); } finally { // res.setStatus(code, message); - deprecated res.setStatus(code); } if (code < 400) { // 1XX:continue, 2XX:successful, 3XX:multiple-choices... try { fromServer = huc.getInputStream(); // IOException } catch (IOException e) { if (_log.isWarnEnabled()) _log.warn("proxying problem", e); throw new IrrecoverableException("problem acquiring http client output", e); } } else { // 4XX:client, 5XX:server error... fromServer = huc.getErrorStream(); // why does this not throw IOException ? // TODO - do we need to use sendError()? } } // clear response defaults. res.setHeader("Date", null); res.setHeader("Server", null); // set response headers if (false) { int h = 0; String hdr = huc.getHeaderFieldKey(h); String val = huc.getHeaderField(h); while (hdr != null || val != null) { String lhdr = (hdr != null) ? hdr.toLowerCase() : null; if (hdr != null && val != null && !_DontProxyHeaders.contains(lhdr)) res.addHeader(hdr, val); // if (_log.isDebugEnabled()) _log.debug("res " + hdr + ": " + val); h++; hdr = huc.getHeaderFieldKey(h); val = huc.getHeaderField(h); } } else { // TODO - is it a bug in Jetty that I have to start my loop at 1 ? or that key[0]==null ? // Try this inside Tomcat... String key; for (int i = 1; (key = huc.getHeaderFieldKey(i)) != null; i++) { key = key.toLowerCase(); String val = huc.getHeaderField(i); if (val != null && !_DontProxyHeaders.contains(key)) { res.addHeader(key, val); } } } // do we need another Via header in the response... // server->client int server2ClientTotal = 0; { if (fromServer != null) { try { OutputStream toClient = res.getOutputStream();// IOException server2ClientTotal += copy(fromServer, toClient, 8192);// IOException } catch (IOException e) { if (_log.isWarnEnabled()) _log.warn("proxying problem", e); throw new IrrecoverableException("problem proxying server response back to client", e); } finally { try { fromServer.close(); } catch (IOException e) { // well - we did our best... _log.warn("problem closing server response stream", e); } } } } huc.disconnect(); long endTime = System.currentTimeMillis(); long elapsed = endTime - startTime; if (_log.isDebugEnabled()) _log.debug("in:" + client2ServerTotal + ", out:" + server2ClientTotal + ", status:" + code + ", time:" + elapsed + ", url:" + url); }
From source file:com.jpeterson.littles3.S3ObjectRequest.java
/** * Create an <code>S3Object</code> based on the request supporting virtual * hosting of buckets./*from w ww . j a va2 s. co m*/ * * @param req * The original request. * @param baseHost * The <code>baseHost</code> is the HTTP Host header that is * "expected". This is used to help determine how the bucket name * will be interpreted. This is used to implement the "Virtual * Hosting of Buckets". * @param authenticator * The authenticator to use to authenticate this request. * @return An object initialized from the request. * @throws IllegalArgumentException * Invalid request. */ @SuppressWarnings("unchecked") public static S3ObjectRequest create(HttpServletRequest req, String baseHost, Authenticator authenticator) throws IllegalArgumentException, AuthenticatorException { S3ObjectRequest o = new S3ObjectRequest(); String pathInfo = req.getPathInfo(); String contextPath = req.getContextPath(); String requestURI = req.getRequestURI(); String undecodedPathPart = null; int pathInfoLength; String requestURL; String serviceEndpoint; String bucket = null; String key = null; String host; String value; String timestamp; baseHost = baseHost.toLowerCase(); host = req.getHeader("Host"); if (host != null) { host = host.toLowerCase(); } try { requestURL = URLDecoder.decode(req.getRequestURL().toString(), "UTF-8"); } catch (UnsupportedEncodingException e) { // should never happen e.printStackTrace(); IllegalArgumentException t = new IllegalArgumentException("Unsupport encoding: UTF-8"); t.initCause(e); throw t; } if (!requestURL.endsWith(pathInfo)) { String m = "requestURL [" + requestURL + "] does not end with pathInfo [" + pathInfo + "]"; throw new IllegalArgumentException(m); } pathInfoLength = pathInfo.length(); serviceEndpoint = requestURL.substring(0, requestURL.length() - pathInfoLength); if (debug) { System.out.println("---------------"); System.out.println("requestURI: " + requestURI); System.out.println("serviceEndpoint: " + serviceEndpoint); System.out.println("---------------"); } if ((host == null) || // http 1.0 form (host.equals(baseHost))) { // ordinary method // http 1.0 form // bucket first part of path info // key second part of path info if (pathInfoLength > 1) { int index = pathInfo.indexOf('/', 1); if (index > -1) { bucket = pathInfo.substring(1, index); if (pathInfoLength > (index + 1)) { key = pathInfo.substring(index + 1); undecodedPathPart = requestURI.substring(contextPath.length() + 1 + bucket.length(), requestURI.length()); } } else { bucket = pathInfo.substring(1); } } } else if (host.endsWith("." + baseHost)) { // bucket prefix of host // key is path info bucket = host.substring(0, host.length() - 1 - baseHost.length()); if (pathInfoLength > 1) { key = pathInfo.substring(1); undecodedPathPart = requestURI.substring(contextPath.length(), requestURI.length()); } } else { // bucket is host // key is path info bucket = host; if (pathInfoLength > 1) { key = pathInfo.substring(1); undecodedPathPart = requestURI.substring(contextPath.length(), requestURI.length()); } } // timestamp timestamp = req.getHeader("Date"); // CanonicalizedResource StringBuffer canonicalizedResource = new StringBuffer(); canonicalizedResource.append('/'); if (bucket != null) { canonicalizedResource.append(bucket); } if (undecodedPathPart != null) { canonicalizedResource.append(undecodedPathPart); } if (req.getParameter(PARAMETER_ACL) != null) { canonicalizedResource.append("?").append(PARAMETER_ACL); } // CanonicalizedAmzHeaders StringBuffer canonicalizedAmzHeaders = new StringBuffer(); Map<String, String> headers = new TreeMap<String, String>(); String headerName; String headerValue; for (Enumeration headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) { headerName = ((String) headerNames.nextElement()).toLowerCase(); if (headerName.startsWith("x-amz-")) { for (Enumeration headerValues = req.getHeaders(headerName); headerValues.hasMoreElements();) { headerValue = (String) headerValues.nextElement(); String currentValue = headers.get(headerValue); if (currentValue != null) { // combine header fields with the same name headers.put(headerName, currentValue + "," + headerValue); } else { headers.put(headerName, headerValue); } if (headerName.equals("x-amz-date")) { timestamp = headerValue; } } } } for (Iterator<String> iter = headers.keySet().iterator(); iter.hasNext();) { headerName = iter.next(); headerValue = headers.get(headerName); canonicalizedAmzHeaders.append(headerName).append(":").append(headerValue).append("\n"); } StringBuffer stringToSign = new StringBuffer(); stringToSign.append(req.getMethod()).append("\n"); value = req.getHeader("Content-MD5"); if (value != null) { stringToSign.append(value); } stringToSign.append("\n"); value = req.getHeader("Content-Type"); if (value != null) { stringToSign.append(value); } stringToSign.append("\n"); value = req.getHeader("Date"); if (value != null) { stringToSign.append(value); } stringToSign.append("\n"); stringToSign.append(canonicalizedAmzHeaders); stringToSign.append(canonicalizedResource); if (debug) { System.out.println(":v:v:v:v:"); System.out.println("undecodedPathPart: " + undecodedPathPart); System.out.println("canonicalizedAmzHeaders: " + canonicalizedAmzHeaders); System.out.println("canonicalizedResource: " + canonicalizedResource); System.out.println("stringToSign: " + stringToSign); System.out.println(":^:^:^:^:"); } o.setServiceEndpoint(serviceEndpoint); o.setBucket(bucket); o.setKey(key); try { if (timestamp == null) { o.setTimestamp(null); } else { o.setTimestamp(DateUtil.parseDate(timestamp)); } } catch (DateParseException e) { o.setTimestamp(null); } o.setStringToSign(stringToSign.toString()); o.setRequestor(authenticate(req, o)); return o; }
From source file:org.infoscoop.web.ProxyCredentialManageServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String command = request.getParameter("command"); String uid = (String) request.getSession().getAttribute("Uid"); try {//from w ww .ja v a 2 s. c o m if ("list".equals(command)) { response.setHeader("Content-Type", "text/xml; charset=UTF-8"); List<AuthCredential> credentialList = AuthCredentialDAO.newInstance().select(uid); List<OAuthConsumerProp> consumers = OAuthConsumerDAO.newInstance().getConsumersByUid(uid); List<String> idList = new ArrayList<String>(); try { JSONArray json = new JSONArray(); for (Iterator<AuthCredential> it = credentialList.iterator(); it.hasNext();) { AuthCredential c = (AuthCredential) it.next(); json.put(c.toJSON()); } JSONObject oauthJSON; for (Iterator<OAuthConsumerProp> i = consumers.iterator(); i.hasNext();) { oauthJSON = new JSONObject(); OAuthConsumerProp consumerProp = i.next(); String id = consumerProp.getId(); if (idList.contains(id)) continue; oauthJSON.put("service_name", consumerProp.getServiceName()); oauthJSON.put("authType", "OAuth"); oauthJSON.put("description", consumerProp.getDescription()); Set<OAuthGadgetUrl> gadgetUrls = consumerProp.getOAuthGadgetUrl(); JSONArray gadgetUrlArr = new JSONArray(); for (Iterator<OAuthGadgetUrl> j = gadgetUrls.iterator(); j.hasNext();) { gadgetUrlArr.put(j.next().getGadgetUrl()); } oauthJSON.put("gadget_urls", gadgetUrlArr); idList.add(id); json.put(oauthJSON); } response.getWriter().write(json.toString()); response.getWriter().flush(); } catch (JSONException e) { log.error("", e); response.sendError(500); } } else if ("try".equals(command)) { response.setHeader("Content-Type", "text/xml; charset=UTF-8"); String url = request.getParameter("url"); String authType = request.getParameter("authType"); String authCredentialId = AuthCredentialService.getHandle().detectCredential(uid, authType, url); if (authCredentialId != null) { response.getWriter().write(authCredentialId); } else { response.getWriter().write("cannot_detect_credential"); } response.getWriter().flush(); } else if ("add".equals(command)) { response.setHeader("Content-Type", "text/xml; charset=UTF-8"); String authType = request.getParameter("authType"); String authUid = request.getParameter("authUid"); String authPasswd = request.getParameter("authPasswd"); String authDomain = request.getParameter("authDomain"); String url = request.getParameter("url"); MultiHashMap headerMap = new MultiHashMap(); Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); Enumeration<String> headers = request.getHeaders(headerName); while (headers.hasMoreElements()) { headerMap.put(headerName, headers.nextElement()); } } String authCredentialId = AuthCredentialService.getHandle().addCredential(uid, authType, authUid, authPasswd, authDomain, url, headerMap); if (authCredentialId != null) { response.getWriter().write(authCredentialId); } else { response.getWriter().write("add_credential_failed"); } response.getWriter().flush(); } else if ("rst".equals(command)) { response.setHeader("Content-Type", "text/xml; charset=UTF-8"); String credentialId = request.getParameter("id"); String authPasswd = request.getParameter("authPasswd"); String[] urlList = request.getParameterValues("url"); Collection errorUrlList; errorUrlList = AuthCredentialService.getHandle().resetPassword(uid, credentialId, authPasswd, urlList); JSONArray json = new JSONArray(); for (Iterator it = errorUrlList.iterator(); it.hasNext();) { json.put((String) it.next()); } response.getWriter().write(json.toString()); //response.getWriter().write("reset_password_success"); response.getWriter().flush(); } else if ("frst".equals(command)) { String credentialId = request.getParameter("id"); String authPasswd = request.getParameter("authPasswd"); AuthCredentialService.getHandle().forceResetPassword(uid, credentialId, authPasswd); } else if ("del".equals(command)) { String credentialId = request.getParameter("id"); AuthCredentialService.getHandle().removeCredential(uid, credentialId); } else if ("del_oauth".equals(command)) { String serviceName = request.getParameter("service_name"); if (!OAuthService.getHandle().deleteOAuthTokens(uid, serviceName)) { OAuthService.getHandle().deleteOAuth2Tokens(uid, serviceName); } } else { response.sendError(500); } } catch (Exception e) { log.error("", e); response.sendError(500, e.getMessage()); } }
From source file:org.basket3.web.S3ObjectRequest.java
/** * Create an <code>S3Object</code> based on the request supporting virtual * hosting of buckets./*w w w .ja v a2s .c o m*/ * * @param req * The original request. * @param baseHost * The <code>baseHost</code> is the HTTP Host header that is * "expected". This is used to help determine how the bucket name * will be interpreted. This is used to implement the "Virtual * Hosting of Buckets". * @param authenticator * The authenticator to use to authenticate this request. * @return An object initialized from the request. * @throws IllegalArgumentException * Invalid request. */ @SuppressWarnings("unchecked") public static S3ObjectRequest create(HttpServletRequest req, String baseHost, Authenticator authenticator) throws IllegalArgumentException, AuthenticatorException { S3ObjectRequest o = new S3ObjectRequest(); String pathInfo = req.getPathInfo(); String contextPath = req.getContextPath(); String requestURI = req.getRequestURI(); String undecodedPathPart = null; int pathInfoLength; String requestURL; String serviceEndpoint; String bucket = null; String key = null; String host; String value; String timestamp; baseHost = baseHost.toLowerCase(); host = req.getHeader("Host"); if (host != null) { host = host.toLowerCase(); } try { requestURL = URLDecoder.decode(req.getRequestURL().toString(), "UTF-8"); } catch (UnsupportedEncodingException e) { // should never happen e.printStackTrace(); IllegalArgumentException t = new IllegalArgumentException("Unsupport encoding: UTF-8"); t.initCause(e); throw t; } if (!requestURL.endsWith(pathInfo)) { String m = "requestURL [" + requestURL + "] does not end with pathInfo [" + pathInfo + "]"; throw new IllegalArgumentException(m); } pathInfoLength = pathInfo.length(); serviceEndpoint = requestURL.substring(0, requestURL.length() - pathInfoLength); if (debug) { System.out.println("---------------"); System.out.println("requestURI: " + requestURI); System.out.println("serviceEndpoint: " + serviceEndpoint); System.out.println("---------------"); } Preconditions.checkNotNull(contextPath, "Context path cannot be null"); if ((host == null) || // http 1.0 form (host.equals(baseHost))) { // ordinary method // http 1.0 form // bucket first part of path info // key second part of path info if (pathInfoLength > 1) { int index = pathInfo.indexOf('/', 1); if (index > -1) { bucket = pathInfo.substring(1, index); if (pathInfoLength > (index + 1)) { key = pathInfo.substring(index + 1); undecodedPathPart = requestURI.substring(contextPath.length() + 1 + bucket.length(), requestURI.length()); } } else { bucket = pathInfo.substring(1); } } } else if (host.endsWith("." + baseHost)) { // bucket prefix of host // key is path info bucket = host.substring(0, host.length() - 1 - baseHost.length()); if (pathInfoLength > 1) { key = pathInfo.substring(1); undecodedPathPart = requestURI.substring(contextPath.length(), requestURI.length()); } } else { // bucket is host // key is path info bucket = host; if (pathInfoLength > 1) { key = pathInfo.substring(1); undecodedPathPart = requestURI.substring(contextPath.length(), requestURI.length()); } } // timestamp timestamp = req.getHeader("Date"); // CanonicalizedResource StringBuffer canonicalizedResource = new StringBuffer(); canonicalizedResource.append('/'); if (bucket != null) { canonicalizedResource.append(bucket); } if (undecodedPathPart != null) { canonicalizedResource.append(undecodedPathPart); } if (req.getParameter(PARAMETER_ACL) != null) { canonicalizedResource.append("?").append(PARAMETER_ACL); } // CanonicalizedAmzHeaders StringBuffer canonicalizedAmzHeaders = new StringBuffer(); Map<String, String> headers = new TreeMap<String, String>(); String headerName; String headerValue; Preconditions.checkNotNull(req.getHeaderNames(), "Http Request Header names cannot be null"); for (Enumeration headerNames = req.getHeaderNames(); headerNames.hasMoreElements();) { headerName = ((String) headerNames.nextElement()).toLowerCase(); if (headerName.startsWith("x-amz-")) { for (Enumeration headerValues = req.getHeaders(headerName); headerValues.hasMoreElements();) { headerValue = (String) headerValues.nextElement(); String currentValue = headers.get(headerValue); if (currentValue != null) { // combine header fields with the same name headers.put(headerName, currentValue + "," + headerValue); } else { headers.put(headerName, headerValue); } if (headerName.equals("x-amz-date")) { timestamp = headerValue; } } } } for (Iterator<String> iter = headers.keySet().iterator(); iter.hasNext();) { headerName = iter.next(); headerValue = headers.get(headerName); canonicalizedAmzHeaders.append(headerName).append(":").append(headerValue).append("\n"); } StringBuffer stringToSign = new StringBuffer(); stringToSign.append(req.getMethod()).append("\n"); value = req.getHeader("Content-MD5"); if (value != null) { stringToSign.append(value); } stringToSign.append("\n"); value = req.getHeader("Content-Type"); if (value != null) { stringToSign.append(value); } stringToSign.append("\n"); value = req.getHeader("Date"); if (value != null) { stringToSign.append(value); } stringToSign.append("\n"); stringToSign.append(canonicalizedAmzHeaders); stringToSign.append(canonicalizedResource); if (debug) { System.out.println(":v:v:v:v:"); System.out.println("undecodedPathPart: " + undecodedPathPart); System.out.println("canonicalizedAmzHeaders: " + canonicalizedAmzHeaders); System.out.println("canonicalizedResource: " + canonicalizedResource); System.out.println("stringToSign: " + stringToSign); System.out.println(":^:^:^:^:"); } o.setServiceEndpoint(serviceEndpoint); o.setBucket(bucket); o.setKey(key); try { if (timestamp == null) { o.setTimestamp(null); } else { o.setTimestamp(DateUtil.parseDate(timestamp)); } } catch (DateParseException e) { o.setTimestamp(null); } o.setStringToSign(stringToSign.toString()); o.setRequestor(authenticate(req, o)); return o; }
From source file:org.gaul.s3proxy.S3ProxyHandler.java
public final void doHandle(HttpServletRequest baseRequest, HttpServletRequest request, HttpServletResponse response, InputStream is) throws IOException, S3Exception { String method = request.getMethod(); String uri = request.getRequestURI(); if (!this.servicePath.isEmpty()) { if (uri.length() > this.servicePath.length()) { uri = uri.substring(this.servicePath.length()); }//from ww w . j a v a 2 s . c om } logger.debug("request: {}", request); String hostHeader = request.getHeader(HttpHeaders.HOST); if (hostHeader != null && virtualHost.isPresent()) { hostHeader = HostAndPort.fromString(hostHeader).getHostText(); String virtualHostSuffix = "." + virtualHost.get(); if (!hostHeader.equals(virtualHost.get())) { if (hostHeader.endsWith(virtualHostSuffix)) { String bucket = hostHeader.substring(0, hostHeader.length() - virtualHostSuffix.length()); uri = "/" + bucket + uri; } else { String bucket = hostHeader.toLowerCase(); uri = "/" + bucket + uri; } } } boolean hasDateHeader = false; boolean hasXAmzDateHeader = false; for (String headerName : Collections.list(request.getHeaderNames())) { for (String headerValue : Collections.list(request.getHeaders(headerName))) { logger.trace("header: {}: {}", headerName, Strings.nullToEmpty(headerValue)); } if (headerName.equalsIgnoreCase(HttpHeaders.DATE)) { hasDateHeader = true; } else if (headerName.equalsIgnoreCase("x-amz-date")) { hasXAmzDateHeader = true; } } // when access information is not provided in request header, // treat it as anonymous, return all public accessible information if (!anonymousIdentity && (method.equals("GET") || method.equals("HEAD") || method.equals("POST")) && request.getHeader(HttpHeaders.AUTHORIZATION) == null && request.getParameter("X-Amz-Algorithm") == null && request.getParameter("AWSAccessKeyId") == null && defaultBlobStore != null) { doHandleAnonymous(request, response, is, uri, defaultBlobStore); return; } if (!anonymousIdentity && !hasDateHeader && !hasXAmzDateHeader && request.getParameter("X-Amz-Date") == null && request.getParameter("Expires") == null) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED, "AWS authentication requires a valid Date or" + " x-amz-date header"); } // TODO: apply sanity checks to X-Amz-Date if (hasDateHeader) { long date; try { date = request.getDateHeader(HttpHeaders.DATE); } catch (IllegalArgumentException iae) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED, iae); } if (date < 0) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED); } long now = System.currentTimeMillis(); if (now + TimeUnit.DAYS.toMillis(1) < date || now - TimeUnit.DAYS.toMillis(1) > date) { throw new S3Exception(S3ErrorCode.REQUEST_TIME_TOO_SKEWED); } } BlobStore blobStore; String requestIdentity = null; String headerAuthorization = request.getHeader(HttpHeaders.AUTHORIZATION); S3AuthorizationHeader authHeader = null; boolean presignedUrl = false; if (!anonymousIdentity) { if (headerAuthorization == null) { String algorithm = request.getParameter("X-Amz-Algorithm"); if (algorithm == null) { String identity = request.getParameter("AWSAccessKeyId"); String signature = request.getParameter("Signature"); if (identity == null || signature == null) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED); } headerAuthorization = "AWS " + identity + ":" + signature; presignedUrl = true; } else if (algorithm.equals("AWS4-HMAC-SHA256")) { String credential = request.getParameter("X-Amz-Credential"); String signedHeaders = request.getParameter("X-Amz-SignedHeaders"); String signature = request.getParameter("X-Amz-Signature"); if (credential == null || signedHeaders == null || signature == null) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED); } headerAuthorization = "AWS4-HMAC-SHA256" + " Credential=" + credential + ", requestSignedHeaders=" + signedHeaders + ", Signature=" + signature; presignedUrl = true; } } try { authHeader = new S3AuthorizationHeader(headerAuthorization); } catch (IllegalArgumentException iae) { throw new S3Exception(S3ErrorCode.INVALID_ARGUMENT, iae); } requestIdentity = authHeader.identity; } String[] path = uri.split("/", 3); for (int i = 0; i < path.length; i++) { path[i] = URLDecoder.decode(path[i], "UTF-8"); } Map.Entry<String, BlobStore> provider = blobStoreLocator.locateBlobStore(requestIdentity, path.length > 1 ? path[1] : null, path.length > 2 ? path[2] : null); if (anonymousIdentity) { blobStore = provider.getValue(); String contentSha256 = request.getHeader("x-amz-content-sha256"); if ("STREAMING-AWS4-HMAC-SHA256-PAYLOAD".equals(contentSha256)) { is = new ChunkedInputStream(is); } } else if (requestIdentity == null) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED); } else { if (provider == null) { throw new S3Exception(S3ErrorCode.INVALID_ACCESS_KEY_ID); } String credential = provider.getKey(); blobStore = provider.getValue(); String expiresString = request.getParameter("Expires"); if (expiresString != null) { long expires = Long.parseLong(expiresString); long nowSeconds = System.currentTimeMillis() / 1000; if (nowSeconds >= expires) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED); } } String dateString = request.getParameter("X-Amz-Date"); expiresString = request.getParameter("X-Amz-Expires"); if (dateString != null && expiresString != null) { long date = parseIso8601(dateString); long expires = Long.parseLong(expiresString); long nowSeconds = System.currentTimeMillis() / 1000; if (nowSeconds >= date + expires) { throw new S3Exception(S3ErrorCode.ACCESS_DENIED, "Request has expired"); } } switch (authHeader.authenticationType) { case AWS_V2: switch (authenticationType) { case AWS_V2: case AWS_V2_OR_V4: case NONE: break; default: throw new S3Exception(S3ErrorCode.ACCESS_DENIED); } break; case AWS_V4: switch (authenticationType) { case AWS_V4: case AWS_V2_OR_V4: case NONE: break; default: throw new S3Exception(S3ErrorCode.ACCESS_DENIED); } break; case NONE: break; default: throw new IllegalArgumentException("Unhandled type: " + authHeader.authenticationType); } String expectedSignature = null; // When presigned url is generated, it doesn't consider service path String uriForSigning = presignedUrl ? uri : this.servicePath + uri; if (authHeader.hmacAlgorithm == null) { expectedSignature = createAuthorizationSignature(request, uriForSigning, credential); } else { String contentSha256 = request.getHeader("x-amz-content-sha256"); try { byte[] payload; if (request.getParameter("X-Amz-Algorithm") != null) { payload = new byte[0]; } else if ("STREAMING-AWS4-HMAC-SHA256-PAYLOAD".equals(contentSha256)) { payload = new byte[0]; is = new ChunkedInputStream(is); } else if ("UNSIGNED-PAYLOAD".equals(contentSha256)) { payload = new byte[0]; } else { // buffer the entire stream to calculate digest payload = ByteStreams.toByteArray(ByteStreams.limit(is, v4MaxNonChunkedRequestSize + 1)); if (payload.length == v4MaxNonChunkedRequestSize + 1) { throw new S3Exception(S3ErrorCode.MAX_MESSAGE_LENGTH_EXCEEDED); } is = new ByteArrayInputStream(payload); } expectedSignature = createAuthorizationSignatureV4(baseRequest, authHeader, payload, uriForSigning, credential); } catch (InvalidKeyException | NoSuchAlgorithmException e) { throw new S3Exception(S3ErrorCode.INVALID_ARGUMENT, e); } } if (!expectedSignature.equals(authHeader.signature)) { logger.debug("fail to validate signature"); throw new S3Exception(S3ErrorCode.SIGNATURE_DOES_NOT_MATCH); } } for (String parameter : Collections.list(request.getParameterNames())) { if (UNSUPPORTED_PARAMETERS.contains(parameter)) { logger.error("Unknown parameters {} with URI {}", parameter, request.getRequestURI()); throw new S3Exception(S3ErrorCode.NOT_IMPLEMENTED); } } // emit NotImplemented for unknown x-amz- headers for (String headerName : Collections.list(request.getHeaderNames())) { if (ignoreUnknownHeaders) { continue; } if (!headerName.startsWith("x-amz-")) { continue; } if (headerName.startsWith("x-amz-meta-")) { continue; } if (!SUPPORTED_X_AMZ_HEADERS.contains(headerName.toLowerCase())) { logger.error("Unknown header {} with URI {}", headerName, request.getRequestURI()); throw new S3Exception(S3ErrorCode.NOT_IMPLEMENTED); } } String uploadId = request.getParameter("uploadId"); switch (method) { case "DELETE": if (path.length <= 2 || path[2].isEmpty()) { handleContainerDelete(response, blobStore, path[1]); return; } else if (uploadId != null) { handleAbortMultipartUpload(response, blobStore, path[1], path[2], uploadId); return; } else { handleBlobRemove(response, blobStore, path[1], path[2]); return; } case "GET": if (uri.equals("/")) { handleContainerList(response, blobStore); return; } else if (path.length <= 2 || path[2].isEmpty()) { if ("".equals(request.getParameter("acl"))) { handleGetContainerAcl(response, blobStore, path[1]); return; } else if ("".equals(request.getParameter("location"))) { handleContainerLocation(response, blobStore, path[1]); return; } else if ("".equals(request.getParameter("uploads"))) { handleListMultipartUploads(request, response, blobStore, path[1]); return; } handleBlobList(request, response, blobStore, path[1]); return; } else { if ("".equals(request.getParameter("acl"))) { handleGetBlobAcl(response, blobStore, path[1], path[2]); return; } else if (uploadId != null) { handleListParts(request, response, blobStore, path[1], path[2], uploadId); return; } handleGetBlob(request, response, blobStore, path[1], path[2]); return; } case "HEAD": if (path.length <= 2 || path[2].isEmpty()) { handleContainerExists(blobStore, path[1]); return; } else { handleBlobMetadata(request, response, blobStore, path[1], path[2]); return; } case "POST": if ("".equals(request.getParameter("delete"))) { handleMultiBlobRemove(response, is, blobStore, path[1]); return; } else if ("".equals(request.getParameter("uploads"))) { handleInitiateMultipartUpload(request, response, blobStore, path[1], path[2]); return; } else if (uploadId != null && request.getParameter("partNumber") == null) { handleCompleteMultipartUpload(response, is, blobStore, path[1], path[2], uploadId); return; } break; case "PUT": if (path.length <= 2 || path[2].isEmpty()) { if ("".equals(request.getParameter("acl"))) { handleSetContainerAcl(request, response, is, blobStore, path[1]); return; } handleContainerCreate(request, response, is, blobStore, path[1]); return; } else if (uploadId != null) { if (request.getHeader("x-amz-copy-source") != null) { handleCopyPart(request, response, blobStore, path[1], path[2], uploadId); } else { handleUploadPart(request, response, is, blobStore, path[1], path[2], uploadId); } return; } else if (request.getHeader("x-amz-copy-source") != null) { handleCopyBlob(request, response, is, blobStore, path[1], path[2]); return; } else { if ("".equals(request.getParameter("acl"))) { handleSetBlobAcl(request, response, is, blobStore, path[1], path[2]); return; } handlePutBlob(request, response, is, blobStore, path[1], path[2]); return; } default: break; } logger.error("Unknown method {} with URI {}", method, request.getRequestURI()); throw new S3Exception(S3ErrorCode.NOT_IMPLEMENTED); }
From source file:org.josso.tc60.gateway.reverseproxy.ReverseProxyValve.java
/** * Intercepts Http request and redirects it to the configured SSO partner application. * * @param request The servlet request to be processed * @param response The servlet response to be created * in the current processing pipeline/*from ww w . j a va2 s .c om*/ * @exception IOException if an input/output error occurs * @exception javax.servlet.ServletException if a servlet error occurs */ public void invoke(Request request, Response response) throws IOException, javax.servlet.ServletException { if (container.getLogger().isDebugEnabled()) container.getLogger().debug("ReverseProxyValve Acting."); ProxyContextConfig[] contexts = _rpc.getProxyContexts(); // Create an instance of HttpClient. HttpClient client = new HttpClient(); HttpServletRequest hsr = (HttpServletRequest) request.getRequest(); String uri = hsr.getRequestURI(); String uriContext = null; StringTokenizer st = new StringTokenizer(uri.substring(1), "/"); while (st.hasMoreTokens()) { String token = st.nextToken(); uriContext = "/" + token; break; } if (uriContext == null) uriContext = uri; // Obtain the target host from the String proxyForwardHost = null; String proxyForwardUri = null; for (int i = 0; i < contexts.length; i++) { if (contexts[i].getContext().equals(uriContext)) { log("Proxy context mapped to host/uri: " + contexts[i].getForwardHost() + contexts[i].getForwardUri()); proxyForwardHost = contexts[i].getForwardHost(); proxyForwardUri = contexts[i].getForwardUri(); break; } } if (proxyForwardHost == null) { log("URI '" + uri + "' can't be mapped to host"); getNext().invoke(request, response); return; } if (proxyForwardUri == null) { // trim the uri context before submitting the http request int uriTrailStartPos = uri.substring(1).indexOf("/") + 1; proxyForwardUri = uri.substring(uriTrailStartPos); } else { int uriTrailStartPos = uri.substring(1).indexOf("/") + 1; proxyForwardUri = proxyForwardUri + uri.substring(uriTrailStartPos); } // log ("Proxy request mapped to " + "http://" + proxyForwardHost + proxyForwardUri); HttpMethod method; // to be moved to a builder which instantiates and build concrete methods. if (hsr.getMethod().equals(METHOD_GET)) { // Create a method instance. HttpMethod getMethod = new GetMethod(proxyForwardHost + proxyForwardUri + (hsr.getQueryString() != null ? ("?" + hsr.getQueryString()) : "")); method = getMethod; } else if (hsr.getMethod().equals(METHOD_POST)) { // Create a method instance. PostMethod postMethod = new PostMethod(proxyForwardHost + proxyForwardUri + (hsr.getQueryString() != null ? ("?" + hsr.getQueryString()) : "")); postMethod.setRequestBody(hsr.getInputStream()); method = postMethod; } else if (hsr.getMethod().equals(METHOD_HEAD)) { // Create a method instance. HeadMethod headMethod = new HeadMethod(proxyForwardHost + proxyForwardUri + (hsr.getQueryString() != null ? ("?" + hsr.getQueryString()) : "")); method = headMethod; } else if (hsr.getMethod().equals(METHOD_PUT)) { method = new PutMethod(proxyForwardHost + proxyForwardUri + (hsr.getQueryString() != null ? ("?" + hsr.getQueryString()) : "")); } else throw new java.lang.UnsupportedOperationException("Unknown method : " + hsr.getMethod()); // copy incoming http headers to reverse proxy request Enumeration hne = hsr.getHeaderNames(); while (hne.hasMoreElements()) { String hn = (String) hne.nextElement(); // Map the received host header to the target host name // so that the configured virtual domain can // do the proper handling. if (hn.equalsIgnoreCase("host")) { method.addRequestHeader("Host", proxyForwardHost); continue; } Enumeration hvals = hsr.getHeaders(hn); while (hvals.hasMoreElements()) { String hv = (String) hvals.nextElement(); method.addRequestHeader(hn, hv); } } // Add Reverse-Proxy-Host header String reverseProxyHost = getReverseProxyHost(request); method.addRequestHeader(Constants.JOSSO_REVERSE_PROXY_HEADER, reverseProxyHost); if (container.getLogger().isDebugEnabled()) container.getLogger().debug("Sending " + Constants.JOSSO_REVERSE_PROXY_HEADER + " " + reverseProxyHost); // DO NOT follow redirects ! method.setFollowRedirects(false); // By default the httpclient uses HTTP v1.1. We are downgrading it // to v1.0 so that the target server doesn't set a reply using chunked // transfer encoding which doesn't seem to be handled properly. client.getParams().setVersion(new HttpVersion(1, 0)); // Execute the method. int statusCode = -1; try { // execute the method. statusCode = client.executeMethod(method); } catch (HttpRecoverableException e) { log("A recoverable exception occurred " + e.getMessage()); } catch (IOException e) { log("Failed to connect."); e.printStackTrace(); } // Check that we didn't run out of retries. if (statusCode == -1) { log("Failed to recover from exception."); } // Read the response body. byte[] responseBody = method.getResponseBody(); // Release the connection. method.releaseConnection(); HttpServletResponse sres = (HttpServletResponse) response.getResponse(); // First thing to do is to copy status code to response, otherwise // catalina will do it as soon as we set a header or some other part of the response. sres.setStatus(method.getStatusCode()); // copy proxy response headers to client response Header[] responseHeaders = method.getResponseHeaders(); for (int i = 0; i < responseHeaders.length; i++) { Header responseHeader = responseHeaders[i]; String name = responseHeader.getName(); String value = responseHeader.getValue(); // Adjust the URL in the Location, Content-Location and URI headers on HTTP redirect responses // This is essential to avoid by-passing the reverse proxy because of HTTP redirects on the // backend servers which stay behind the reverse proxy switch (method.getStatusCode()) { case HttpStatus.SC_MOVED_TEMPORARILY: case HttpStatus.SC_MOVED_PERMANENTLY: case HttpStatus.SC_SEE_OTHER: case HttpStatus.SC_TEMPORARY_REDIRECT: if ("Location".equalsIgnoreCase(name) || "Content-Location".equalsIgnoreCase(name) || "URI".equalsIgnoreCase(name)) { // Check that this redirect must be adjusted. if (value.indexOf(proxyForwardHost) >= 0) { String trail = value.substring(proxyForwardHost.length()); value = getReverseProxyHost(request) + trail; if (container.getLogger().isDebugEnabled()) container.getLogger().debug("Adjusting redirect header to " + value); } } break; } //end of switch sres.addHeader(name, value); } // Sometimes this is null, when no body is returned ... if (responseBody != null && responseBody.length > 0) sres.getOutputStream().write(responseBody); sres.getOutputStream().flush(); if (container.getLogger().isDebugEnabled()) container.getLogger().debug("ReverseProxyValve finished."); return; }
From source file:org.josso.tc55.gateway.reverseproxy.ReverseProxyValve.java
/** * Intercepts Http request and redirects it to the configured SSO partner application. * * @param request The servlet request to be processed * @param response The servlet response to be created * in the current processing pipeline/* w w w . jav a2 s .c o m*/ * @exception IOException if an input/output error occurs * @exception javax.servlet.ServletException if a servlet error occurs */ public void invoke(Request request, Response response) throws IOException, javax.servlet.ServletException { if (container.getLogger().isDebugEnabled()) container.getLogger().debug("ReverseProxyValve Acting."); ProxyContextConfig[] contexts = _rpc.getProxyContexts(); // Create an instance of HttpClient. HttpClient client = new HttpClient(); HttpServletRequest hsr = (HttpServletRequest) request.getRequest(); String uri = hsr.getRequestURI(); String uriContext = null; StringTokenizer st = new StringTokenizer(uri.substring(1), "/"); while (st.hasMoreTokens()) { String token = st.nextToken(); uriContext = "/" + token; break; } if (uriContext == null) uriContext = uri; // Obtain the target host from the String proxyForwardHost = null; String proxyForwardUri = null; for (int i = 0; i < contexts.length; i++) { if (contexts[i].getContext().equals(uriContext)) { log("Proxy context mapped to host/uri: " + contexts[i].getForwardHost() + contexts[i].getForwardUri()); proxyForwardHost = contexts[i].getForwardHost(); proxyForwardUri = contexts[i].getForwardUri(); break; } } if (proxyForwardHost == null) { log("URI '" + uri + "' can't be mapped to host"); getNext().invoke(request, response); return; } if (proxyForwardUri == null) { // trim the uri context before submitting the http request int uriTrailStartPos = uri.substring(1).indexOf("/") + 1; proxyForwardUri = uri.substring(uriTrailStartPos); } else { int uriTrailStartPos = uri.substring(1).indexOf("/") + 1; proxyForwardUri = proxyForwardUri + uri.substring(uriTrailStartPos); } // log ("Proxy request mapped to " + "http://" + proxyForwardHost + proxyForwardUri); HttpMethod method; // to be moved to a builder which instantiates and build concrete methods. if (hsr.getMethod().equals(METHOD_GET)) { // Create a method instance. HttpMethod getMethod = new GetMethod(proxyForwardHost + proxyForwardUri + (hsr.getQueryString() != null ? ("?" + hsr.getQueryString()) : "")); method = getMethod; } else if (hsr.getMethod().equals(METHOD_POST)) { // Create a method instance. PostMethod postMethod = new PostMethod(proxyForwardHost + proxyForwardUri + (hsr.getQueryString() != null ? ("?" + hsr.getQueryString()) : "")); postMethod.setRequestBody(hsr.getInputStream()); method = postMethod; } else if (hsr.getMethod().equals(METHOD_HEAD)) { // Create a method instance. HeadMethod headMethod = new HeadMethod(proxyForwardHost + proxyForwardUri + (hsr.getQueryString() != null ? ("?" + hsr.getQueryString()) : "")); method = headMethod; } else if (hsr.getMethod().equals(METHOD_PUT)) { method = new PutMethod(proxyForwardHost + proxyForwardUri + (hsr.getQueryString() != null ? ("?" + hsr.getQueryString()) : "")); } else throw new java.lang.UnsupportedOperationException("Unknown method : " + hsr.getMethod()); // copy incoming http headers to reverse proxy request Enumeration hne = hsr.getHeaderNames(); while (hne.hasMoreElements()) { String hn = (String) hne.nextElement(); // Map the received host header to the target host name // so that the configured virtual domain can // do the proper handling. if (hn.equalsIgnoreCase("host")) { method.addRequestHeader("Host", proxyForwardHost); continue; } Enumeration hvals = hsr.getHeaders(hn); while (hvals.hasMoreElements()) { String hv = (String) hvals.nextElement(); method.addRequestHeader(hn, hv); } } // Add Reverse-Proxy-Host header String reverseProxyHost = getReverseProxyHost(request); method.addRequestHeader(Constants.JOSSO_REVERSE_PROXY_HEADER, reverseProxyHost); if (container.getLogger().isDebugEnabled()) container.getLogger().debug("Sending " + Constants.JOSSO_REVERSE_PROXY_HEADER + " " + reverseProxyHost); // DO NOT follow redirects ! method.setFollowRedirects(false); // By default the httpclient uses HTTP v1.1. We are downgrading it // to v1.0 so that the target server doesn't set a reply using chunked // transfer encoding which doesn't seem to be handled properly. // Check how to make chunked transfer encoding work. client.getParams().setVersion(new HttpVersion(1, 0)); // Execute the method. int statusCode = -1; try { // execute the method. statusCode = client.executeMethod(method); } catch (HttpRecoverableException e) { log("A recoverable exception occurred " + e.getMessage()); } catch (IOException e) { log("Failed to connect."); e.printStackTrace(); } // Check that we didn't run out of retries. if (statusCode == -1) { log("Failed to recover from exception."); } // Read the response body. byte[] responseBody = method.getResponseBody(); // Release the connection. method.releaseConnection(); HttpServletResponse sres = (HttpServletResponse) response.getResponse(); // First thing to do is to copy status code to response, otherwise // catalina will do it as soon as we set a header or some other part of the response. sres.setStatus(method.getStatusCode()); // copy proxy response headers to client response Header[] responseHeaders = method.getResponseHeaders(); for (int i = 0; i < responseHeaders.length; i++) { Header responseHeader = responseHeaders[i]; String name = responseHeader.getName(); String value = responseHeader.getValue(); // Adjust the URL in the Location, Content-Location and URI headers on HTTP redirect responses // This is essential to avoid by-passing the reverse proxy because of HTTP redirects on the // backend servers which stay behind the reverse proxy switch (method.getStatusCode()) { case HttpStatus.SC_MOVED_TEMPORARILY: case HttpStatus.SC_MOVED_PERMANENTLY: case HttpStatus.SC_SEE_OTHER: case HttpStatus.SC_TEMPORARY_REDIRECT: if ("Location".equalsIgnoreCase(name) || "Content-Location".equalsIgnoreCase(name) || "URI".equalsIgnoreCase(name)) { // Check that this redirect must be adjusted. if (value.indexOf(proxyForwardHost) >= 0) { String trail = value.substring(proxyForwardHost.length()); value = getReverseProxyHost(request) + trail; if (container.getLogger().isDebugEnabled()) container.getLogger().debug("Adjusting redirect header to " + value); } } break; } //end of switch sres.addHeader(name, value); } // Sometimes this is null, when no body is returned ... if (responseBody != null && responseBody.length > 0) sres.getOutputStream().write(responseBody); sres.getOutputStream().flush(); if (container.getLogger().isDebugEnabled()) container.getLogger().debug("ReverseProxyValve finished."); return; }