protected ModelAndView doHandle()

in teamcity-symbol-server/src/main/java/jetbrains/buildServer/symbols/DownloadSymbolsController.java [78:159]


  protected ModelAndView doHandle(final @NotNull HttpServletRequest request, final @NotNull HttpServletResponse response) throws Exception {
    final String requestURI = StringUtil.removeTailingSlash(request.getRequestURI());

    if (requestURI.endsWith(SymbolsConstants.APP_SYMBOLS)) {
      return simpleView("TeamCity symbol server is running");
    }

    if (requestURI.endsWith(COMPRESSED_FILE_EXTENSION)) {
      WebUtil.notFound(request, response, "File not found", null);
      return null;
    }
    if (requestURI.endsWith(FILE_POINTER_FILE_EXTENSION)) {
      WebUtil.notFound(request, response, "File not found", null);
      return null;
    }

    final Matcher urlMatcher = DOWNLOAD_URL_PATTERN.matcher(requestURI);
    if (!urlMatcher.find()) {
      WebUtil.notFound(request, response, "File not found", null);
      if (!requestURI.endsWith("index2.txt")) {
        LOG.warn("Invalid request to symbol server: " + requestURI);
      }
      return null;
    }

    final String encodedFileName = urlMatcher.group(1).replaceAll("\\+", "%2b");
    final String fileName = URLDecoder.decode(encodedFileName, "UTF-8");
    final String signature = urlMatcher.group(2).toLowerCase();

    String guid = PdbSignatureIndexUtil.extractGuid(signature, true);
    LOG.debug(String.format("Symbol file requested. File name: %s. Guid: %s.", fileName, guid));

    try {
      final BuildMetadataEntry metadataEntry = getMetadataEntry(guid, fileName);
      if (metadataEntry == null) {
        LOG.debug(String.format("There is no information about symbol file %s with id %s in the index.", fileName, guid));

        WebUtil.notFound(request, response, "File not found", null);
        return null;
      }
      final String projectId = findRelatedProjectId(metadataEntry);
      if (projectId == null) {
        WebUtil.notFound(request, response, "File not found", null);
        return null;
      }

      final SUser user = myAuthHelper.getAuthenticatedUser(request, response, authority -> authority.isPermissionGrantedForProject(projectId, Permission.VIEW_BUILD_RUNTIME_DATA));
      if (user == null) return null;

      mySecurityContext.runAs(user, () -> {
        final BuildArtifact buildArtifact = findArtifact(metadataEntry);
        if (buildArtifact == null) {
          WebUtil.notFound(request, response, "Symbol file not found", null);
          LOG.debug(String.format("Symbol file not found. File name: %s. Guid: %s.", fileName, guid));
          return;
        }

        LOG.debug(String.format("Start sending symbols file. File name: %s. Guid: %s.", fileName, guid));
        BufferedOutputStream output = new BufferedOutputStream(response.getOutputStream());
        try {
          LOG.debug(String.format("Getting artifact stream for symbols file. File name: %s. Guid: %s.", fileName, guid));
          InputStream input = buildArtifact.getInputStream();
          try {
            LOG.debug(String.format("Sending symbols file. File name: %s. Guid: %s.", fileName, guid));
            FileUtil.copyStreams(input, output);
          } finally {
            FileUtil.close(input);
          }
        } finally {
          FileUtil.close(output);
        }
        LOG.debug(String.format("Symbols file successfully transferred. File name: %s. Guid: %s.", fileName, guid));
      });
    } catch (Throwable throwable) {
      LOG.debug(String.format("Failed to send symbols for file %s: %s", fileName, throwable.getMessage()), throwable);
      if (!response.isCommitted()) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, throwable.getMessage());
      }
    }

    return null;
  }