hudson.model.DirectoryBrowserSupport#org.kohsuke.stapler.HttpResponse源码实例Demo

下面列出了hudson.model.DirectoryBrowserSupport#org.kohsuke.stapler.HttpResponse 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

/**
 * Validates this server endpoint. Checks availability and version requirement.
 * @return If valid HttpStatus 200, if unsupported version then 428 and if unreachable then 400 error code is returned.
 */
@GET
@WebMethod(name="validate")
public HttpResponse validate(){
    String version = BitbucketServerApi.getVersion(apiUrl);
    if(!BitbucketServerApi.isSupportedVersion(version)){
        throw new ServiceException.PreconditionRequired(
                Messages.bbserver_version_validation_error(
                        version, BitbucketServerApi.MINIMUM_SUPPORTED_VERSION));
    }
    return new HttpResponse(){
        @Override
        public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException {
            rsp.setStatus(200);
        }
    };
}
 
源代码2 项目: gitlab-oauth-plugin   文件: GitLabSecurityRealm.java
public HttpResponse doCommenceLogin(StaplerRequest request, @QueryParameter String from, @Header("Referer") final String referer) throws IOException {
    // 2. Requesting authorization :
    // http://doc.gitlab.com/ce/api/oauth2.html

    String redirectOnFinish;
    if (from != null && Util.isSafeToRedirectTo(from)) {
        redirectOnFinish = from;
    } else if (referer != null && (referer.startsWith(Jenkins.getInstance().getRootUrl()) || Util.isSafeToRedirectTo(referer))) {
        redirectOnFinish = referer;
    } else {
        redirectOnFinish = Jenkins.getInstance().getRootUrl();
    }

    List<NameValuePair> parameters = new ArrayList<>();
    parameters.add(new BasicNameValuePair("redirect_uri", buildRedirectUrl(request, redirectOnFinish)));
    parameters.add(new BasicNameValuePair("response_type", "code"));
    parameters.add(new BasicNameValuePair("client_id", clientID));

    return new HttpRedirect(gitlabWebUri + "/oauth/authorize?" + URLEncodedUtils.format(parameters, StandardCharsets.UTF_8));
}
 
源代码3 项目: oic-auth-plugin   文件: OicSession.java
/**
 * When the identity provider is done with its thing, the user comes back here.
 * @return an {@link HttpResponse}
 */
public HttpResponse doFinishLogin(StaplerRequest request)  {
    StringBuffer buf = request.getRequestURL();
    if (request.getQueryString() != null) {
        buf.append('?').append(request.getQueryString());
    }
    AuthorizationCodeResponseUrl responseUrl = new AuthorizationCodeResponseUrl(buf.toString());
    if (!state.equals(responseUrl.getState())) {
        return new Failure("State is invalid");
    }
    String code = responseUrl.getCode();
    if (responseUrl.getError() != null) {
        return new Failure(
                "Error from provider: " + responseUrl.getError() + ". Details: " + responseUrl.getErrorDescription()
        );
    } else if (code == null) {
        return new Failure("Missing authorization code");
    } else {
        return onSuccess(code);
    }
}
 
源代码4 项目: jira-ext-plugin   文件: AddLabelToField.java
public HttpResponse doQueryJiraFields(@QueryParameter String issueKey)
{
    try
    {
        if (!Config.getGlobalConfig().isJiraConfigComplete())
        {
            return FormValidation.error("JIRA settings are not set in global config");
        }
        final Map<String, String> jiraFields = getJiraClientSvc().getJiraFields(issueKey);
        return new ForwardToView(this, "/org/jenkinsci/plugins/jiraext/view/AddLabelToField/jiraFields.jelly")
                .with("jiraFieldMap", jiraFields);
    }
    catch (Throwable t)
    {
        String message =  "Error finding FieldIds for issueKey: " + issueKey;
        logger.log(Level.WARNING, message, t);
        return FormValidation.error(t, message);
    }
}
 
源代码5 项目: jira-ext-plugin   文件: UpdateField.java
public HttpResponse doQueryJiraFields(@QueryParameter String issueKey)
{
    try
    {
        if (!Config.getGlobalConfig().isJiraConfigComplete())
        {
            return FormValidation.error("JIRA settings are not set in global config");
        }
        final Map<String, String> jiraFields = getJiraClientSvc().getJiraFields(issueKey);
        return new ForwardToView(this, "/org/jenkinsci/plugins/jiraext/view/UpdateField/jiraFields.jelly")
                .with("jiraFieldMap", jiraFields);
    }
    catch (Throwable t)
    {
        String message =  "Error finding FieldIds for issueKey: " + issueKey;
        logger.log(Level.WARNING, message, t);
        return FormValidation.error(t, message);
    }
}
 
/**
 * Retrieves the latest container status via API.
 * The output will be retrieved in JSON. Supports filers. Missing 
 * &quot;since&quot; and &quot;until&quot; 
 * @param id ID of the container, for which the info should be retrieved.
 *    Short container IDs are not supported.
 * @throws IOException Processing error
 * @throws ServletException Servlet error
 * @return Raw JSON output compatible with docker inspect
 */
public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String id) 
        throws IOException, ServletException {     
    checkPermission(DockerTraceabilityPlugin.READ_DETAILS);
    
    //TODO: check containerID format
    final DockerTraceabilityReport report = DockerTraceabilityHelper.getLastReport(id);
    if (report == null) {
        return HttpResponses.error(404, "No info available for the containerId=" + id);
    }
    final InspectContainerResponse inspectInfo = report.getContainer();
    if (inspectInfo == null) {
        assert false : "Input logic should reject such cases";
        return HttpResponses.error(500, "Cannot retrieve the container's status"); 
    }
    
    // Return raw JSON in the response
    InspectContainerResponse[] out = {inspectInfo};
    return toJSONResponse(out);
}
 
源代码7 项目: DotCi   文件: GithubOauthLoginAction.java
public HttpResponse doFinishLogin(StaplerRequest request, StaplerResponse rsp) throws IOException {

        String code = request.getParameter("code");

        if (code == null || code.trim().length() == 0) {
            Log.info("doFinishLogin: missing code.");
            return HttpResponses.redirectToContextRoot();
        }

        String content = postForAccessToken(code);

        String accessToken = extractToken(content);
        updateOfflineAccessTokenForUser(accessToken);
        request.getSession().setAttribute("access_token", accessToken);

        String newProjectSetupUrl = getJenkinsRootUrl() + "/" + GithubReposController.URL;
        return HttpResponses.redirectTo(newProjectSetupUrl);
    }
 
public HttpResponse doPost(StaplerRequest request) throws IOException, GitLabApiException {
    if (!request.getMethod().equals("POST")) {
        return HttpResponses
            .error(HttpServletResponse.SC_BAD_REQUEST,
                "Only POST requests are supported, this was a " + request.getMethod()
                    + " request");
    }
    if (!"application/json".equals(request.getContentType())) {
        return HttpResponses
            .error(HttpServletResponse.SC_BAD_REQUEST,
                "Only application/json content is supported, this was " + request
                    .getContentType());
    }
    String type = request.getHeader("X-Gitlab-Event");
    if (StringUtils.isBlank(type)) {
        return HttpResponses.error(HttpServletResponse.SC_BAD_REQUEST,
            "Expecting a GitLab event, missing expected X-Gitlab-Event header");
    }
    String secretToken = request.getHeader("X-Gitlab-Token");
    if(!isValidToken(secretToken)) {
        return HttpResponses.error(HttpServletResponse.SC_UNAUTHORIZED,
            "Expecting a valid secret token");
    }
    String origin = SCMEvent.originOf(request);
    WebHookManager webHookManager = new WebHookManager();
    webHookManager.addListener(new GitLabWebHookListener(origin));
    webHookManager.handleEvent(request);
    return HttpResponses.ok(); // TODO find a better response
}
 
public HttpResponse doPost(StaplerRequest request) throws GitLabApiException {
    if (!request.getMethod().equals("POST")) {
        return HttpResponses
            .error(HttpServletResponse.SC_BAD_REQUEST,
                "Only POST requests are supported, this was a " + request.getMethod()
                    + " request");
    }
    if (!"application/json".equals(request.getContentType())) {
        return HttpResponses
            .error(HttpServletResponse.SC_BAD_REQUEST,
                "Only application/json content is supported, this was " + request
                    .getContentType());
    }
    String type = request.getHeader("X-Gitlab-Event");
    if (StringUtils.isBlank(type)) {
        return HttpResponses.error(HttpServletResponse.SC_BAD_REQUEST,
            "Expecting a GitLab event, missing expected X-Gitlab-Event header");
    }
    String secretToken = request.getHeader("X-Gitlab-Token");
    if(!isValidToken(secretToken)) {
        return HttpResponses.error(HttpServletResponse.SC_UNAUTHORIZED,
            "Expecting a valid secret token");
    }
    String origin = SCMEvent.originOf(request);
    SystemHookManager systemHookManager = new SystemHookManager();
    systemHookManager.addListener(new GitLabSystemHookListener(origin));
    systemHookManager.handleEvent(request);
    return HttpResponses.ok(); // TODO find a better response
}
 
源代码10 项目: blueocean-plugin   文件: AbstractBitbucketScm.java
/**
 * Request payload:
 * {
 *     "userName": "joe",
 *     "password":"****",
 *     "apiUrl":"mybitbucketserver.com"
 * }
 * @param request userName and password of bitbucket server
 *
 * @return credential id
 */
@Override
public HttpResponse validateAndCreate(@JsonBody JSONObject request) {
    User authenticatedUser = User.current();
    if(authenticatedUser == null){
        throw new ServiceException.UnauthorizedException("No logged in user found");
    }

    String userName = (String) request.get("userName");
    String password = (String) request.get("password");
    String apiUrl = (String) request.get("apiUrl");

    validate(userName, password, apiUrl);

    final StandardUsernamePasswordCredentials credential = new UsernamePasswordCredentialsImpl(CredentialsScope.USER,
            createCredentialId(apiUrl), "Bitbucket server credentials", userName, password);

    //if credentials are wrong, this call will fail with 401 error
    validateCredential(apiUrl, credential);

    StandardUsernamePasswordCredentials bbCredentials = CredentialsUtils.findCredential(createCredentialId(apiUrl),
            StandardUsernamePasswordCredentials.class, new BlueOceanDomainRequirement());

    try {
        if (bbCredentials == null) {
            CredentialsUtils.createCredentialsInUserStore(
                    credential, authenticatedUser, getDomainId(),
                    ImmutableList.<DomainSpecification>of(new BlueOceanDomainSpecification()));
        } else {
            CredentialsUtils.updateCredentialsInUserStore(
                    bbCredentials, credential, authenticatedUser, getDomainId(),
                    ImmutableList.<DomainSpecification>of(new BlueOceanDomainSpecification()));
        }

        return createResponse(credential.getId());
    }catch (IOException e){
        throw new ServiceException.UnexpectedErrorException(e.getMessage());
    }
}
 
@GET
@WebMethod(name="")
public HttpResponse getProgress(StaplerRequest req) {
    String repositoryUrl = req.getOriginalRestOfPath();
    CloneProgressMonitor progress = CloneProgressMonitor.get(repositoryUrl);
    if (progress == null) {
        return null;
    }
    return HttpResponses.okJSON(ImmutableMap.of("progress", progress.getPercentComplete()));
}
 
@DELETE
@WebMethod(name="")
public HttpResponse cancelClone(StaplerRequest req) {
    String repositoryUrl = req.getOriginalRestOfPath();
    CloneProgressMonitor progress = CloneProgressMonitor.get(repositoryUrl);
    if (progress != null) {
        progress.cancel();
    }
    return HttpResponses.ok();
}
 
源代码13 项目: blueocean-plugin   文件: AbstractScm.java
protected HttpResponse createResponse(final String credentialId) {
    return new HttpResponse() {
        @Override
        public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException {
            rsp.setStatus(200);
            rsp.getWriter().print(JsonConverter.toJson(ImmutableMap.of("credentialId", credentialId)));
        }
    };
}
 
源代码14 项目: oic-auth-plugin   文件: OicSession.java
/**
 * Starts the login session.
 * @return an {@link HttpResponse}
 */
@SuppressFBWarnings("J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION")
public HttpResponse doCommenceLogin() {
    // remember this in the session
    Stapler.getCurrentRequest().getSession().setAttribute(SESSION_NAME, this);
    AuthorizationCodeRequestUrl authorizationCodeRequestUrl = flow.newAuthorizationUrl().setState(state).setRedirectUri(redirectUrl);
    return new HttpRedirect(authorizationCodeRequestUrl.toString());
}
 
源代码15 项目: oic-auth-plugin   文件: OicSecurityRealm.java
public HttpResponse doEscapeHatch(@QueryParameter("j_username") String username, @QueryParameter("j_password") String password) {
    randomWait(); // to slowdown brute forcing
    if(!isEscapeHatchEnabled()) {
        return HttpResponses.redirectViaContextPath("loginError");
    }
    if(this.escapeHatchUsername == null || this.escapeHatchSecret == null) {
        return HttpResponses.redirectViaContextPath("loginError");
    }
    if(escapeHatchUsername.equalsIgnoreCase(username) && escapeHatchSecret.getPlainText().equals(password)) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(SecurityRealm.AUTHENTICATED_AUTHORITY);
        if(isNotBlank(escapeHatchGroup)) {
            authorities.add(new GrantedAuthorityImpl(escapeHatchGroup));
        }
        String userName = "escape-hatch-admin";
        GrantedAuthority[] grantedAuthorities = authorities.toArray(new GrantedAuthority[authorities.size()]);
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
        		userName,
                "",
                grantedAuthorities
        );
        SecurityContextHolder.getContext().setAuthentication(token);
        OicUserDetails userDetails = new OicUserDetails(userName, grantedAuthorities);
        SecurityListener.fireAuthenticated(userDetails);
        return HttpRedirect.CONTEXT_ROOT;
    }
    return HttpResponses.redirectViaContextPath("loginError");
}
 
源代码16 项目: oic-auth-plugin   文件: OicSecurityRealm.java
/**
 * This is where the user comes back to at the end of the OpenID redirect ping-pong.
 * @param request The user's request
 * @return an HttpResponse
*/
public HttpResponse doFinishLogin(StaplerRequest request) {
	OicSession currentSession = OicSession.getCurrent();
	if(currentSession==null) {
		LOGGER.fine("No session to resume (perhaps jenkins was restarted?)");
		return HttpResponses.errorWithoutStack(401, "Unauthorized");
	}
    return currentSession.doFinishLogin(request);
}
 
源代码17 项目: oic-auth-plugin   文件: TestRealm.java
@Override
public HttpResponse doFinishLogin(StaplerRequest request) {
    try {
        Field field = OicSession.class.getDeclaredField("state");
        field.setAccessible(true);
        field.set(OicSession.getCurrent(), "state");
    } catch (Exception e) {
        throw new RuntimeException("can't fudge state",e);
    }
    return super.doFinishLogin(request);
}
 
/**
 * Submits a new event through Jenkins API.
 * @param inspectData JSON output of docker inspect container (array of container infos)
 * @param hostName Optional name of the host, which submitted the event
 *      &quot;unknown&quot; by default
 * @param hostId Optional host ID. 
 *      &quot;unknown&quot; by default
 * @param status Optional status of the container. 
 *      By default, an artificial {@link DockerEventType#NONE} will be used.    
 * @param time Optional time when the event happened. 
 *      The time is specified in seconds since January 1, 1970, 00:00:00 GMT
 *      Default value - current time
 * @param environment Optional field, which describes the environment
 * @param imageName Optional field, which provides the name of the image
 * @return {@link HttpResponse}
 * @throws IOException Request processing error
 * @throws ServletException Servlet error
 */
//TODO: parameters check
@RequirePOST
public HttpResponse doSubmitContainerStatus(
        @QueryParameter(required = true) String inspectData,
        @QueryParameter(required = false) String hostId,
        @QueryParameter(required = false) String hostName,
        @QueryParameter(required = false) String status,
        @QueryParameter(required = false) long time,
        @QueryParameter(required = false) @CheckForNull String environment,
        @QueryParameter(required = false) @CheckForNull String imageName
) throws IOException, ServletException { 
    checkPermission(DockerTraceabilityPlugin.SUBMIT);
    final ObjectMapper mapper = new ObjectMapper();
    final InspectContainerResponse[] inspectContainerResponses = mapper.readValue(inspectData, InspectContainerResponse[].class);
    final long eventTime = time != 0 ? time : System.currentTimeMillis()/1000;
    final String effectiveHostName = StringUtils.isNotBlank(hostName) ? hostName : "unknown";
    final String effectiveHostId = StringUtils.isNotBlank(hostId) ? hostId : "unknown";
    final String effectiveStatus = StringUtils.isNotBlank(status) 
            ? status.toUpperCase(Locale.ENGLISH) : DockerEventType.NONE.toString();
    final String effectiveImageName = hudson.Util.fixEmpty(imageName);
    final String effectiveEnvironment = hudson.Util.fixEmpty(environment);
    
    
    for (InspectContainerResponse inspectContainerResponse : inspectContainerResponses) {
        final Event event = new DockerEvent(effectiveStatus, inspectContainerResponse.getImageId(), 
                effectiveHostId, eventTime).toDockerEvent();
        final Info hostInfo = new DockerInfo(effectiveHostId, effectiveHostName).toInfo();

        DockerTraceabilityReport res = new DockerTraceabilityReport(event, hostInfo,
                inspectContainerResponse, 
                inspectContainerResponse.getImageId(), effectiveImageName,
                /* InspectImageResponse */ null, new LinkedList<String>(), effectiveEnvironment);
        DockerTraceabilityReportListener.fire(res);
    }
    return HttpResponses.ok();
}
 
/**
 * Submits a new {@link DockerTraceabilityReport} via API.
 * @param json String representation of {@link DockerTraceabilityReport}
 * @return {@link HttpResponse}
 * @throws ServletException Servlet error
 * @throws IOException Processing error
 */
@RequirePOST
public HttpResponse doSubmitReport(@QueryParameter(required = true) String json) 
        throws IOException, ServletException { 
    checkPermission(DockerTraceabilityPlugin.SUBMIT);
    ObjectMapper mapper = new ObjectMapper();
    final DockerTraceabilityReport report = mapper.readValue(json, DockerTraceabilityReport.class);
    DockerTraceabilityReportListener.fire(report);
    return HttpResponses.ok();
}
 
/**
 * Removes the container reference from the registry.
 * @param id Container ID. Method supports full 64-char IDs only.
 * @throws IOException Cannot save the updated {@link DockerTraceabilityRootAction}
 * @throws ServletException Servlet exception
 * @return response
 */
@RequirePOST
public HttpResponse doDeleteContainer(@QueryParameter(required = true) String id) 
        throws IOException, ServletException {  
    checkPermission(DockerTraceabilityPlugin.DELETE);
    removeContainerID(id);
    return HttpResponses.ok();
}
 
/**
 * Retrieves the latest raw status via API.
 * The output will be retrieved in JSON.
 * @param id ID of the image, for which the info should be retrieved.
 *    Short container IDs are not supported.
 * @throws IOException Processing error
 * @throws ServletException Servlet error
 * @return {@link HttpResponse}
 */
public HttpResponse doRawImageInfo(@QueryParameter(required = true) String id) 
        throws IOException, ServletException {     
    checkPermission(DockerTraceabilityPlugin.READ_DETAILS);
    
    final InspectImageResponse report = DockerTraceabilityHelper.getLastInspectImageResponse(id);
    if (report == null) {   
        return HttpResponses.error(404, "No info available for the imageId=" + id);
    }
    
    // Return raw JSON in the response
    InspectImageResponse[] out = {report};
    return toJSONResponse(out);
}
 
/**
 * Serves the JSON response.
 * @param item Data to be serialized to JSON
 * @return HTTP response with application/json MIME type
 */
private static HttpResponse toJSONResponse(final Object item) {
    return new HttpResponse() {
        @Override
        public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException {
            ObjectMapper mapper = new ObjectMapper(); 
            rsp.setContentType("application/json;charset=UTF-8");
            mapper.writeValue(rsp.getWriter(), item);
        }
    };
}
 
@Test
@Bug(28656)
public void createFingerPrintsOnDemand() throws Exception {
    // Read data from resources
    String inspectData = JSONSamples.inspectContainerData.readString();
    InspectContainerResponse inspectResponse = JSONSamples.inspectContainerData.
            readObject(InspectContainerResponse[].class)[0];
    final String containerId = inspectResponse.getId();
    final String imageId = inspectResponse.getImageId();
    
    // Retrieve instances
    final DockerTraceabilityRootAction action = DockerTraceabilityRootAction.getInstance();
    assertNotNull(action);
    
    // Enable automatic fingerprints creation
    DockerTraceabilityPluginConfiguration config = new DockerTraceabilityPluginConfiguration(true, false);
    DockerTraceabilityPluginTest.configure(config);
    DockerTraceabilityPlugin plugin = DockerTraceabilityPlugin.getInstance();
    assertTrue(plugin.getConfiguration().isCreateImageFingerprints());
    
    // Submit JSON
    HttpResponse res = action.doSubmitContainerStatus(inspectData, null, null, null, 0, null, null);
    
    // Ensure that both container and images have been created with proper facets
    Fingerprint imageFP = DockerFingerprints.of(imageId);
    Fingerprint containerFP = DockerFingerprints.of(containerId);
    assertNotNull(imageFP);
    assertNotNull(DockerFingerprints.getFacet(imageFP, DockerDeploymentRefFacet.class));
    assertNotNull(containerFP);
    assertNotNull(DockerFingerprints.getFacet(containerFP, DockerDeploymentFacet.class));
    
    // TODO: JENKINS-28655 (Fingerprints cleanup)
    // Check original references - Docker Traceability Manager should create runs
    // assertNotNull(imageFP.getOriginal().getJob());
    // assertNotNull(containerFP.getOriginal().getJob());
}
 
@SuppressWarnings(UNUSED)
@CLIMethod(name = "disable-job")
@RequirePOST
public HttpResponse doDisable() throws IOException, ServletException { // NOSONAR
    checkPermission(CONFIGURE);
    makeDisabled(true);
    return new HttpRedirect(".");
}
 
@SuppressWarnings(UNUSED)
@CLIMethod(name = "enable-job")
@RequirePOST
public HttpResponse doEnable() throws IOException, ServletException { // NOSONAR
    checkPermission(CONFIGURE);
    makeDisabled(false);
    return new HttpRedirect(".");
}
 
public HttpResponse doIcon( StaplerRequest req, StaplerResponse rsp, @QueryParameter String job,
                            @QueryParameter String style )
    throws IOException, FontFormatException
{
    Job<?, ?> project = coverageStatus.getProject( job, req, rsp );
    int coverage = coverageStatus.getCoverage( project );
    return iconResolver.getCoverageImage( coverage, style );
}
 
public HttpResponse doIcon( StaplerRequest req, StaplerResponse rsp, @QueryParameter String job,
                            @QueryParameter String style )
    throws IOException, FontFormatException
{
    Job<?, ?> project = gradeStatus.getProject( job, req, rsp );
    double grade = gradeStatus.getGrade( project );
    return iconResolver.getGradeImage( grade, style );
}
 
public HttpResponse doIcon( StaplerRequest req, StaplerResponse rsp, @QueryParameter String job,
                            @QueryParameter String style )
    throws IOException, FontFormatException
{
    Job<?, ?> project = buildStatus.getProject( job, req, rsp );
    return iconResolver.getBuildImage( project.getIconColor(), style );
}
 
源代码29 项目: DotCi   文件: GithubOauthLoginActionTest.java
@Test
public void should_set_access_token_in_the_session() throws IOException {
    final StaplerRequest request = mock(StaplerRequest.class);
    final HttpSession httpSession = mock(HttpSession.class);
    when(request.getSession()).thenReturn(httpSession);
    when(request.getParameter("code")).thenReturn("code");
    when(this.httpPoster.post(anyString(), anyMap())).thenReturn("access_token=meow_token");
    final HttpResponse response = this.githubOauthLoginAction.doFinishLogin(request, null);

    verify(httpSession).setAttribute("access_token", "meow_token");
    assertNotNull(response);

}
 
源代码30 项目: gitea-plugin   文件: GiteaWebhookAction.java
public HttpResponse doPost(StaplerRequest request) throws IOException {
    String origin = SCMEvent.originOf(request);
    if (!request.getMethod().equals("POST")) {
        LOGGER.log(Level.FINE, "Received {0} request (expecting POST) from {1}",
                new Object[]{request.getMethod(), origin});
        return HttpResponses
                .error(HttpServletResponse.SC_BAD_REQUEST,
                        "Only POST requests are supported, this was a " + request.getMethod() + " request");
    }
    if (!"application/json".equals(request.getContentType())) {
        LOGGER.log(Level.FINE, "Received {0} body (expecting application/json) from {1}",
                new Object[]{request.getContentType(), origin});
        return HttpResponses
                .error(HttpServletResponse.SC_BAD_REQUEST,
                        "Only application/json content is supported, this was " + request.getContentType());
    }
    String type = request.getHeader("X-Gitea-Event");
    if (StringUtils.isBlank(type)) {
        LOGGER.log(Level.FINE, "Received request without X-Gitea-Event header from {1}",
                new Object[]{request.getContentType(), origin});
        return HttpResponses.error(HttpServletResponse.SC_BAD_REQUEST,
                "Expecting a Gitea event, missing expected X-Gitea-Event header");
    }
    LOGGER.log(Level.FINER, "Received {0} event from {1}", new Object[]{
            request.getContentType(), origin
    });
    boolean processed = false;
    for (GiteaWebhookHandler<?, ?> h : ExtensionList.lookup(GiteaWebhookHandler.class)) {
        if (h.matches(type)) {
            LOGGER.log(Level.FINER, "Processing {0} event from {1} with {2}",
                    new Object[]{type, origin, h});
            h.process(request.getInputStream(), origin);
            processed = true;
        }
    }
    if (!processed) {
        LOGGER.log(Level.INFO, "Received hook payload with unknown type: {0} from {1}",
                new Object[]{type, origin});
    }
    return HttpResponses.text(processed ? "Processed" : "Ignored");
}