/**
  * @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;
 }