extensions/servlet/src/com/google/inject/servlet/ServletDefinition.java
void doService(final ServletRequest servletRequest, ServletResponse servletResponse)
      throws ServletException, IOException {

    HttpServletRequest request =
        new HttpServletRequestWrapper((HttpServletRequest) servletRequest) {
          private boolean pathComputed;
          private String path;

          private boolean pathInfoComputed;
          private String pathInfo;

          @Override
          public String getPathInfo() {
            if (!isPathInfoComputed()) {
              String servletPath = getServletPath();
              int servletPathLength = servletPath.length();
              String requestUri = getRequestURI();
              pathInfo = requestUri.substring(getContextPath().length()).replaceAll("[/]{2,}", "/");
              // See: https://github.com/google/guice/issues/372
              if (pathInfo.startsWith(servletPath)) {
                pathInfo = pathInfo.substring(servletPathLength);
                // Corner case: when servlet path & request path match exactly (without trailing '/'),
                // then pathinfo is null.
                if (pathInfo.isEmpty() && servletPathLength > 0) {
                  pathInfo = null;
                } else {
                  try {
                    pathInfo = new URI(pathInfo).getPath();
                  } catch (URISyntaxException e) {
                    // ugh, just leave it alone then
                  }
                }
              } else {
                pathInfo = null; // we know nothing additional about the URI.
              }
              pathInfoComputed = true;
            }

            return pathInfo;
          }

          // NOTE(dhanji): These two are a bit of a hack to help ensure that request dispatcher-sent
          // requests don't use the same path info that was memoized for the original request.
          // NOTE(iqshum): I don't think this is possible, since the dispatcher-sent request would
          // perform its own wrapping.
          private boolean isPathInfoComputed() {
            return pathInfoComputed
                && servletRequest.getAttribute(REQUEST_DISPATCHER_REQUEST) == null;
          }

          private boolean isPathComputed() {
            return pathComputed && servletRequest.getAttribute(REQUEST_DISPATCHER_REQUEST) == null;
          }

          @Override
          public String getServletPath() {
            return computePath();
          }

          @Override
          public String getPathTranslated() {
            final String info = getPathInfo();

            return (null == info) ? null : getRealPath(info);
          }

          // Memoizer pattern.
          private String computePath() {
            if (!isPathComputed()) {
              String servletPath = super.getServletPath();
              path = patternMatcher.extractPath(servletPath);
              pathComputed = true;

              if (null == path) {
                path = servletPath;
              }
            }

            return path;
          }
        };

    doServiceImpl(request, (HttpServletResponse) servletResponse);
  }
void doService(final ServletRequest servletRequest, ServletResponse servletResponse)
      throws ServletException, IOException {

    HttpServletRequest request =
        new HttpServletRequestWrapper((HttpServletRequest) servletRequest) {
          private boolean pathComputed;
          private String path;

          private boolean pathInfoComputed;
          private String pathInfo;

          @Override
          public String getPathInfo() {
            if (!isPathInfoComputed()) {
              String servletPath = getServletPath();
              int servletPathLength = servletPath.length();
              String requestUri = getRequestURI();
              pathInfo = requestUri.substring(getContextPath().length()).replaceAll("[/]{2,}", "/");
              // See: https://github.com/google/guice/issues/372
              if (pathInfo.startsWith(servletPath)) {
                pathInfo = pathInfo.substring(servletPathLength);
                // Corner case: when servlet path & request path match exactly (without trailing '/'),
                // then pathinfo is null.
                if (pathInfo.isEmpty() && servletPathLength > 0) {
                  pathInfo = null;
                } else {
                  try {
                    pathInfo = new URI(pathInfo).getPath();
                  } catch (URISyntaxException e) {
                    // ugh, just leave it alone then
                  }
                }
              } else {
                pathInfo = null; // we know nothing additional about the URI.
              }
              pathInfoComputed = true;
            }

            return pathInfo;
          }

          // NOTE(dhanji): These two are a bit of a hack to help ensure that request dispatcher-sent
          // requests don't use the same path info that was memoized for the original request.
          // NOTE(iqshum): I don't think this is possible, since the dispatcher-sent request would
          // perform its own wrapping.
          private boolean isPathInfoComputed() {
            return pathInfoComputed
                && servletRequest.getAttribute(REQUEST_DISPATCHER_REQUEST) == null;
          }

          private boolean isPathComputed() {
            return pathComputed && servletRequest.getAttribute(REQUEST_DISPATCHER_REQUEST) == null;
          }

          @Override
          public String getServletPath() {
            return computePath();
          }

          @Override
          public String getPathTranslated() {
            final String info = getPathInfo();

            return (null == info) ? null : getRealPath(info);
          }

          // Memoizer pattern.
          private String computePath() {
            if (!isPathComputed()) {
              String servletPath = super.getServletPath();
              path = patternMatcher.extractPath(servletPath);
              pathComputed = true;

              if (null == path) {
                path = servletPath;
              }
            }

            return path;
          }
        };

    doServiceImpl(request, (HttpServletResponse) servletResponse);
  }
void doService ( final ServletRequest servletRequest , ServletResponse servletResponse ) throws ServletException , IOException { HttpServletRequest request = new HttpServletRequestWrapper ( ( HttpServletRequest ) servletRequest ) { private boolean pathComputed ; private String path ; private boolean pathInfoComputed ; private String pathInfo ; @ Override public String getPathInfo ( ) { if ( ! isPathInfoComputed ( ) ) { String servletPath = getServletPath ( ) ; int servletPathLength = servletPath . length ( ) ; String requestUri = getRequestURI ( ) ; pathInfo = requestUri . substring ( getContextPath ( ) . length ( ) ) . replaceAll ( "[/]{2,}" , "/" ) ; // See: https://github.com/google/guice/issues/372 if ( pathInfo . startsWith ( servletPath ) ) { pathInfo = pathInfo . substring ( servletPathLength ) ; // Corner case: when servlet path & request path match exactly (without trailing '/'), // then pathinfo is null. if ( pathInfo . isEmpty ( ) && servletPathLength > 0 ) { pathInfo = null ; } else { try { pathInfo = new URI ( pathInfo ) . getPath ( ) ; } catch ( URISyntaxException e ) { // ugh, just leave it alone then } } } else { pathInfo = null ; // we know nothing additional about the URI. } pathInfoComputed = true ; } return pathInfo ; } // NOTE(dhanji): These two are a bit of a hack to help ensure that request dispatcher-sent // requests don't use the same path info that was memoized for the original request. // NOTE(iqshum): I don't think this is possible, since the dispatcher-sent request would // perform its own wrapping. private boolean isPathInfoComputed ( ) { return pathInfoComputed && servletRequest . getAttribute ( REQUEST_DISPATCHER_REQUEST ) == null ; } private boolean isPathComputed ( ) { return pathComputed && servletRequest . getAttribute ( REQUEST_DISPATCHER_REQUEST ) == null ; } @ Override public String getServletPath ( ) { return computePath ( ) ; } @ Override public String getPathTranslated ( ) { final String info = getPathInfo ( ) ; return ( null == info ) ? null : getRealPath ( info ) ; } // Memoizer pattern. private String computePath ( ) { if ( ! isPathComputed ( ) ) { String servletPath = super . getServletPath ( ) ; path = patternMatcher . extractPath ( servletPath ) ; pathComputed = true ; if ( null == path ) { path = servletPath ; } } return path ; } } ; doServiceImpl ( request , ( HttpServletResponse ) servletResponse ) ; }
Utility that delegates to the actual service method of the servlet wrapped with a contextual
request (i.e. with correctly computed path info).

<p>We need to suppress deprecation coz we use HttpServletRequestWrapper, which implements
deprecated API for backwards compatibility.
Utility that delegates to the actual service method of the servlet wrapped with a contextual request ( i . e . with correctly computed path info ) .