/** * @param req The request. * @return The query string of the request in its raw (not URI-encoded) form. This is suitable for * passing as the 'query' parameter to one of the multi-argument {@link URI} constructors. */ private static String getQueryString(HttpServletRequest req) throws UnsupportedEncodingException { StringBuilder buf = new StringBuilder(); Map<String, String[]> params = req.getParameterMap(); if (params.size() == 0) return null; for (Entry<String, String[]> entry : params.entrySet()) { String name = entry.getKey(); String[] values = entry.getValue(); if (values.length == 0) { buf.append("&").append(name); } else { for (String value : values) { buf.append("&").append(name).append("=").append(value); } } } return buf.substring(1); }
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { traceRequest(req); String pathInfoString = req.getPathInfo(); String queryString = getQueryString(req); IPath pathInfo = new Path( null /*don't parse host:port as device*/, pathInfoString == null ? "" : pathInfoString); // $NON-NLS-1$ if (pathInfo.segmentCount() > 0) { String hostedHost = pathInfo.segment(0); IHostedSite site = HostingActivator.getDefault().getHostingService().get(hostedHost); if (site != null) { IPath path = pathInfo.removeFirstSegments(1); IPath contextPath = new Path(req.getContextPath()); IPath contextlessPath = path.makeRelativeTo(contextPath).makeAbsolute(); URI[] mappedPaths; try { mappedPaths = getMapped(site, contextlessPath, queryString); } catch (URISyntaxException e) { handleException( resp, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Could not create target URI ", e)); return; } if (mappedPaths != null) { serve(req, resp, site, mappedPaths); } else { handleException( resp, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, NLS.bind("No mappings matched {0}", path), null)); } } else { String msg = NLS.bind("Hosted site {0} is stopped", hostedHost); handleException( resp, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND, msg, null)); } } else { super.doGet(req, resp); } }
private void serve( HttpServletRequest req, HttpServletResponse resp, IHostedSite site, URI[] mappedURIs) throws ServletException, IOException { for (int i = 0; i < mappedURIs.length; i++) { URI uri = mappedURIs[i]; // Bypass a 404 if any workspace or remote paths remain to be checked. boolean failEarlyOn404 = i + 1 < mappedURIs.length; if (uri.getScheme() == null) { if ("GET".equals(req.getMethod())) { // $NON-NLS-1$ if (serveOrionFile(req, resp, site, new Path(uri.getPath()), failEarlyOn404)) return; } else { String message = "Only GET method is supported for workspace paths"; handleException( resp, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_METHOD_NOT_ALLOWED, NLS.bind(message, mappedURIs), null)); } } else { if (proxyRemotePath( req, new LocationHeaderServletResponseWrapper(req, resp, site), uri, failEarlyOn404)) return; } } }
private String mapLocation(String location) { Map<String, List<String>> mappings = site.getMappings(); String bestMatch = ""; String prefix = null; for (Iterator<Entry<String, List<String>>> iterator = mappings.entrySet().iterator(); iterator.hasNext(); ) { Entry<String, List<String>> entry = iterator.next(); List<String> candidates = entry.getValue(); for (Iterator<String> candidateIt = candidates.iterator(); candidateIt.hasNext(); ) { String candidate = candidateIt.next(); if (location.startsWith(candidate) && candidate.length() > bestMatch.length()) { bestMatch = candidate; prefix = entry.getKey(); } } } if (prefix != null) { String reverseMappedPath = prefix + location.substring(bestMatch.length()); try { URI pathlessRequestURI = new URI( request.getScheme(), null, request.getServerName(), request.getServerPort(), null, null, null); return pathlessRequestURI.toString() + reverseMappedPath; } catch (URISyntaxException t) { // best effort System.err.println(t); } } return location; }