@Override public void handle(Request wsRequest, Response wsResponse) throws Exception { userSession.checkIsSystemAdministrator(); String processKey = wsRequest.mandatoryParam(PROCESS_PROPERTY); ProcessId processId = ProcessId.fromKey(processKey); File logsDir = serverLogging.getLogsDir(); File file = new File(logsDir, processId.getLogFilenamePrefix() + ".log"); // filenames are defined in the enum LogProcess. Still to prevent any vulnerability, // path is double-checked to prevent returning any file present on the file system. if (file.exists() && file.getParentFile().equals(logsDir)) { wsResponse.stream().setMediaType(MediaTypes.TXT); FileUtils.copyFile(file, wsResponse.stream().output()); } else { wsResponse.stream().setStatus(HttpURLConnection.HTTP_NOT_FOUND); } } }
@Override public void handle(Request request, Response response) throws Exception { response.setHeader("Cache-Control", "no-cache"); response.stream().setMediaType(SVG); try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto project = support.getComponent(dbSession, request); Level qualityGateStatus = getQualityGate(dbSession, project); String result = svgGenerator.generateQualityGate(qualityGateStatus); String eTag = getETag(result); Optional<String> requestedETag = request.header("If-None-Match"); if (requestedETag.filter(eTag::equals).isPresent()) { response.stream().setStatus(304); return; } response.setHeader("ETag", eTag); write(result, response.stream().output(), UTF_8); } catch (ProjectBadgesException | ForbiddenException | NotFoundException e) { // There is an issue, so do not return any ETag but make this response expire now SimpleDateFormat sdf = new SimpleDateFormat(RFC1123_DATE, Locale.US); response.setHeader("Expires", sdf.format(new Date())); write(svgGenerator.generateError(e.getMessage()), response.stream().output(), UTF_8); } }
@Override public void handle(Request request, Response response) throws Exception { Date timestamp = request.paramAsDateTime(TS_PARAM); if (timestamp != null && timestamp.after(server.getStartedAt())) { response.stream().setStatus(HTTP_NOT_MODIFIED).output().close(); return; } String localeParam = request.mandatoryParam(LOCALE_PARAM); Locale locale = Locale.forLanguageTag(localeParam); checkArgument(!locale.getISO3Language().isEmpty(), "'%s' cannot be parsed as a BCP47 language tag", localeParam); try (JsonWriter json = response.newJsonWriter()) { json.beginObject(); json.prop("effectiveLocale", i18n.getEffectiveLocale(locale).toLanguageTag()); json.name("messages"); json.beginObject(); i18n.getPropertyKeys().forEach(messageKey -> json.prop(messageKey, i18n.message(locale, messageKey, messageKey))); json.endObject(); json.endObject(); } } }
@Override public void handle(Request request, Response response) throws Exception { ruleWsSupport.checkQProfileAdminPermissionOnDefaultOrganization(); String customKey = request.mandatoryParam(PARAM_CUSTOM_KEY); try (DbSession dbSession = dbClient.openSession(false)) { try { NewCustomRule newRule = NewCustomRule.createForCustomRule(customKey, RuleKey.parse(request.mandatoryParam(PARAM_TEMPLATE_KEY))) .setName(request.mandatoryParam(PARAM_NAME)) .setMarkdownDescription(request.mandatoryParam(PARAM_DESCRIPTION)) .setSeverity(request.mandatoryParam(PARAM_SEVERITY)) .setStatus(RuleStatus.valueOf(request.mandatoryParam(PARAM_STATUS))) .setPreventReactivation(request.mandatoryParamAsBoolean(PARAM_PREVENT_REACTIVATION)); String params = request.param(PARAMS); if (!isNullOrEmpty(params)) { newRule.setParameters(KeyValueFormat.parse(params)); } setNullable(request.param(PARAM_TYPE), t -> newRule.setType(RuleType.valueOf(t))); writeResponse(dbSession, request, response, ruleCreator.create(dbSession, newRule)); } catch (ReactivationException e) { response.stream().setStatus(HTTP_CONFLICT); writeResponse(dbSession, request, response, e.ruleKey()); } } }
@Override public void handle(Request request, Response response) throws Exception { response.setHeader("Cache-Control", "no-cache"); response.stream().setMediaType(SVG); String metricKey = request.mandatoryParam(PARAM_METRIC); try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto project = support.getComponent(dbSession, request); MetricDto metric = dbClient.metricDao().selectByKey(dbSession, metricKey); checkState(metric != null && metric.isEnabled(), "Metric '%s' hasn't been found", metricKey); LiveMeasureDto measure = getMeasure(dbSession, project, metricKey); String result = generateSvg(metric, measure); String eTag = getETag(result); Optional<String> requestedETag = request.header("If-None-Match"); if (requestedETag.filter(eTag::equals).isPresent()) { response.stream().setStatus(304); return; } response.setHeader("ETag", eTag); write(result, response.stream().output(), UTF_8); } catch (ProjectBadgesException | ForbiddenException | NotFoundException e) { // There is an issue, so do not return any ETag but make this response expire now SimpleDateFormat sdf = new SimpleDateFormat(RFC1123_DATE, Locale.US); response.setHeader("Expires", sdf.format(new Date())); write(svgGenerator.generateError(e.getMessage()), response.stream().output(), UTF_8); } }
@Override public void handle(Request request, Response response) throws Exception { response.setHeader("Cache-Control", "no-cache"); response.stream().setMediaType(SVG); try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto project = support.getComponent(dbSession, request); Level qualityGateStatus = getQualityGate(dbSession, project); String result = svgGenerator.generateQualityGate(qualityGateStatus); String eTag = getETag(result); Optional<String> requestedETag = request.header("If-None-Match"); if (requestedETag.filter(eTag::equals).isPresent()) { response.stream().setStatus(304); return; } response.setHeader("ETag", eTag); write(result, response.stream().output(), UTF_8); } catch (ProjectBadgesException | ForbiddenException | NotFoundException e) { // There is an issue, so do not return any ETag but make this response expire now SimpleDateFormat sdf = new SimpleDateFormat(RFC1123_DATE, Locale.US); response.setHeader("Expires", sdf.format(new Date())); write(svgGenerator.generateError(e.getMessage()), response.stream().output(), UTF_8); } }
@Override public void handle(Request request, Response response) throws Exception { Date timestamp = request.paramAsDateTime(TS_PARAM); if (timestamp != null && timestamp.after(server.getStartedAt())) { response.stream().setStatus(HTTP_NOT_MODIFIED).output().close(); return; } String localeParam = request.mandatoryParam(LOCALE_PARAM); Locale locale = Locale.forLanguageTag(localeParam); checkArgument(!locale.getISO3Language().isEmpty(), "'%s' cannot be parsed as a BCP47 language tag", localeParam); try (JsonWriter json = response.newJsonWriter()) { json.beginObject(); json.prop("effectiveLocale", i18n.getEffectiveLocale(locale).toLanguageTag()); json.name("messages"); json.beginObject(); i18n.getPropertyKeys().forEach(messageKey -> json.prop(messageKey, i18n.message(locale, messageKey, messageKey))); json.endObject(); json.endObject(); } } }
@Override public void handle(Request wsRequest, Response wsResponse) throws Exception { userSession.checkIsSystemAdministrator(); String processKey = wsRequest.mandatoryParam(PROCESS_PROPERTY); ProcessId processId = ProcessId.fromKey(processKey); File logsDir = serverLogging.getLogsDir(); File file = new File(logsDir, processId.getLogFilenamePrefix() + ".log"); // filenames are defined in the enum LogProcess. Still to prevent any vulnerability, // path is double-checked to prevent returning any file present on the file system. if (file.exists() && file.getParentFile().equals(logsDir)) { wsResponse.stream().setMediaType(MediaTypes.TXT); FileUtils.copyFile(file, wsResponse.stream().output()); } else { wsResponse.stream().setStatus(HttpURLConnection.HTTP_NOT_FOUND); } } }
@Override public void handle(Request request, Response response) throws Exception { response.setHeader("Cache-Control", "no-cache"); response.stream().setMediaType(SVG); String metricKey = request.mandatoryParam(PARAM_METRIC); try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto project = support.getComponent(dbSession, request); MetricDto metric = dbClient.metricDao().selectByKey(dbSession, metricKey); checkState(metric != null && metric.isEnabled(), "Metric '%s' hasn't been found", metricKey); LiveMeasureDto measure = getMeasure(dbSession, project, metricKey); String result = generateSvg(metric, measure); String eTag = getETag(result); Optional<String> requestedETag = request.header("If-None-Match"); if (requestedETag.filter(eTag::equals).isPresent()) { response.stream().setStatus(304); return; } response.setHeader("ETag", eTag); write(result, response.stream().output(), UTF_8); } catch (ProjectBadgesException | ForbiddenException | NotFoundException e) { // There is an issue, so do not return any ETag but make this response expire now SimpleDateFormat sdf = new SimpleDateFormat(RFC1123_DATE, Locale.US); response.setHeader("Expires", sdf.format(new Date())); write(svgGenerator.generateError(e.getMessage()), response.stream().output(), UTF_8); } }
@Override public void handle(Request request, Response response) throws Exception { ruleWsSupport.checkQProfileAdminPermissionOnDefaultOrganization(); String customKey = request.mandatoryParam(PARAM_CUSTOM_KEY); try (DbSession dbSession = dbClient.openSession(false)) { try { NewCustomRule newRule = NewCustomRule.createForCustomRule(customKey, RuleKey.parse(request.mandatoryParam(PARAM_TEMPLATE_KEY))) .setName(request.mandatoryParam(PARAM_NAME)) .setMarkdownDescription(request.mandatoryParam(PARAM_DESCRIPTION)) .setSeverity(request.mandatoryParam(PARAM_SEVERITY)) .setStatus(RuleStatus.valueOf(request.mandatoryParam(PARAM_STATUS))) .setPreventReactivation(request.mandatoryParamAsBoolean(PARAM_PREVENT_REACTIVATION)); String params = request.param(PARAMS); if (!isNullOrEmpty(params)) { newRule.setParameters(KeyValueFormat.parse(params)); } ofNullable(request.param(PARAM_TYPE)).ifPresent(t -> newRule.setType(RuleType.valueOf(t))); writeResponse(dbSession, request, response, ruleCreator.create(dbSession, newRule)); } catch (ReactivationException e) { response.stream().setStatus(HTTP_CONFLICT); writeResponse(dbSession, request, response, e.ruleKey()); } } }
@Test public void support_aborted_request_when_response_is_not_committed() { Request request = new TestRequest().setPath("api/foo"); Response response = mockServletResponse(false); run(request, response, newClientAbortWs()); verify(response.stream()).setStatus(299); assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Request api/foo has been aborted by client"); }
@Test public void internal_error_when_response_is_not_committed() { Request request = new TestRequest().setPath("api/foo"); Response response = mockServletResponse(false); run(request, response, newFailWs()); verify(response.stream()).setStatus(500); assertThat(logTester.logs(LoggerLevel.ERROR)).contains("Fail to process request api/foo"); }
@Test public void internal_error_when_response_is_already_committed() { Request request = new TestRequest().setPath("api/foo"); Response response = mockServletResponse(true); run(request, response, newFailWs()); // response is committed (status is already sent), so status can't be changed verify(response.stream(), never()).setStatus(anyInt()); assertThat(logTester.logs(LoggerLevel.ERROR)).contains("Fail to process request api/foo"); }
@Test public void support_aborted_request_when_response_is_already_committed() { Request request = new TestRequest().setPath("api/foo"); Response response = mockServletResponse(true); run(request, response, newClientAbortWs()); // response is committed (status is already sent), so status can't be changed verify(response.stream(), never()).setStatus(anyInt()); assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Request api/foo has been aborted by client"); }
@Override public Response noContent() { stream().setStatus(HttpURLConnection.HTTP_NO_CONTENT); IOUtils.closeQuietly(output); return this; }