/*
   * Set the correct media based on the request Accept header and marshal the
   * response. Set any common headers for all responses.
   */
  private void marshal(Object objects[]) throws IOException {
    OSLC4JMarshaller marshaller = OSLC4JContext.newInstance().createMarshaller();

    MediaType type = AcceptUtil.matchMediaType(Stapler.getCurrentRequest());
    if (type == null) {
      throw HttpResponses.status(HttpServletResponse.SC_NOT_ACCEPTABLE);
    }

    marshaller.setMediaType(type);

    StaplerResponse response = Stapler.getCurrentResponse();
    response.setCharacterEncoding("UTF-8");
    response.setHeader("OSLC-Core-Version", "2.0");
    response.setHeader("Content-Type", type.toString());
    response.setHeader("Vary", "Accept, Accept-Encoding");

    // Use WriterOutputStream since Stapler has already called response.getWriter().
    WriterOutputStream out = new WriterOutputStream(response.getWriter());
    marshaller.marshal(objects, out);
  }
Example #2
0
 public void doIndex(StaplerRequest req, StaplerResponse rsp)
     throws IOException, ServletException {
   URLConnection con = connect();
   // since we end up redirecting users to jnlpJars/foo.jar/, set the content disposition
   // so that browsers can download them in the right file name.
   // see http://support.microsoft.com/kb/260519 and
   // http://www.boutell.com/newfaq/creating/forcedownload.html
   rsp.setHeader("Content-Disposition", "attachment; filename=" + fileName);
   InputStream in = con.getInputStream();
   rsp.serveFile(req, in, con.getLastModified(), con.getContentLength(), "*.jar");
   in.close();
 }
Example #3
0
  private void generateStatusPNG(
      String branch,
      String commitSHA1,
      Job project,
      final StaplerRequest req,
      final StaplerResponse rsp)
      throws ServletException, IOException {
    SCMTriggerItem item = SCMTriggerItems.asSCMTriggerItem(project);
    GitSCM gitSCM = getGitSCM(item);

    if (gitSCM == null) {
      throw new IllegalArgumentException("This repo does not use git.");
    }

    Run mainBuild = null;

    if (branch != null) {
      mainBuild = this.getBuildByBranch(project, branch);
    } else if (commitSHA1 != null) {
      mainBuild = this.getBuildBySHA1(project, commitSHA1, false);
    }

    String baseUrl = Jenkins.getInstance().getRootUrl();
    // Remove trailing slash
    if (baseUrl.endsWith("/")) {
      baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
    }
    String imageUrl = "images/unknown.png";
    if (null != mainBuild) {
      Result res = mainBuild.getResult();
      if (mainBuild.isBuilding()) {
        imageUrl = "images/running.png";
      } else if (res == Result.SUCCESS) {
        imageUrl = "images/success.png";
      } else if (res == Result.FAILURE) {
        imageUrl = "images/failed.png";
      } else if (res == Result.UNSTABLE) {
        imageUrl = "images/unstable.png";
      } else {
        imageUrl = "images/unknown.png";
      }
    }
    Authentication old = SecurityContextHolder.getContext().getAuthentication();
    SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
    try {
      URL resourceUrl =
          new URL(
              Jenkins.getInstance().getPlugin("gitlab-plugin").getWrapper().baseResourceURL
                  + imageUrl);
      LOGGER.info("serving image " + resourceUrl.toExternalForm());
      rsp.setHeader("Expires", "Fri, 01 Jan 1984 00:00:00 GMT");
      rsp.setHeader("Cache-Control", "no-cache, private");
      rsp.setHeader("Content-Type", "image/png");
      hudson.util.IOUtils.copy(new File(resourceUrl.toURI()), rsp.getOutputStream());
      rsp.flushBuffer();
    } catch (Exception e) {
      throw HttpResponses.error(500, "Could not generate response.");
    } finally {
      SecurityContextHolder.getContext().setAuthentication(old);
    }
  }
  /*
   * Path: /auto/scheduleBuild
   *
   * POST to create automation requests to schedule builds.
   */
  public void doScheduleBuild(StaplerRequest request, StaplerResponse response) throws Exception {
    requirePOST();

    OSLC4JUnmarshaller unmarshaller = OSLC4JContext.newInstance().createUnmarshaller();

    String contentType = request.getContentType();
    if (contentType == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }
    unmarshaller.setMediaType(MediaType.valueOf(contentType));

    final AutomationRequest autoRequest =
        unmarshaller.unmarshal(request.getInputStream(), AutomationRequest.class);
    if (autoRequest == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    Link planLink = autoRequest.getExecutesAutomationPlan();
    if (planLink == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    URI planURI = planLink.getValue();
    String jobName = getJobNameFromURI(planURI);
    if (jobName == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    Job<?, ?> job = getJob(jobName);
    if (job == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    if (!job.isBuildable()) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    if (!(job instanceof AbstractProject)) {
      LOG.log(
          Level.WARNING,
          "Cannot schedule builds for jobs that don't extend AbstractProject: " + jobName);
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;
    int nextBuildNumber = project.getNextBuildNumber();
    Cause cause =
        new Cause() {
          @Override
          public String getShortDescription() {
            String description = autoRequest.getDescription();
            return description != null ? description : "OSLC Automation Request";
          }
        };

    ParameterInstance[] parameters = autoRequest.getInputParameters();
    boolean suceeded;
    if (parameters.length == 0) {
      suceeded = project.scheduleBuild(cause);
    } else {
      List<ParameterValue> values = getParameterValues(project, parameters);
      suceeded =
          project.scheduleBuild2(project.getQuietPeriod(), cause, new ParametersAction(values))
              != null;
    }

    if (!suceeded) {
      // Build already queued.
      LOG.log(
          Level.WARNING,
          "Automation request rejected (409 conflict) since build is already queued: " + jobName);
      throw HttpResponses.status(HttpServletResponse.SC_CONFLICT);
    }

    URI requestURI = getAutoRequestURI(job, nextBuildNumber);
    response.setStatus(HttpServletResponse.SC_CREATED);
    response.setHeader("Location", requestURI.toString());
  }
Example #5
0
 private void setHeaders(StaplerResponse rsp) {
   rsp.setHeader("X-Jenkins", Jenkins.VERSION);
   rsp.setHeader("X-Jenkins-Session", Jenkins.SESSION_HASH);
 }
  /**
   * Serves a file from the file system (Maps the URL to a directory in a file system.)
   *
   * @param icon The icon file name, like "folder-open.gif"
   * @param serveDirIndex True to generate the directory index. False to serve "index.html"
   * @deprecated as of 1.297 Instead of calling this method explicitly, just return the {@link
   *     DirectoryBrowserSupport} object from the {@code doXYZ} method and let Stapler generate a
   *     response for you.
   */
  public void serveFile(
      StaplerRequest req, StaplerResponse rsp, FilePath root, String icon, boolean serveDirIndex)
      throws IOException, ServletException, InterruptedException {
    // handle form submission
    String pattern = req.getParameter("pattern");
    if (pattern == null) pattern = req.getParameter("path"); // compatibility with Hudson<1.129
    if (pattern != null) {
      rsp.sendRedirect2(pattern);
      return;
    }

    String path = getPath(req);
    if (path.replace('\\', '/').indexOf("/../") != -1) {
      // don't serve anything other than files in the artifacts dir
      rsp.sendError(HttpServletResponse.SC_BAD_REQUEST);
      return;
    }

    // split the path to the base directory portion "abc/def/ghi" which doesn't include any
    // wildcard,
    // and the GLOB portion "**/*.xml" (the rest)
    StringBuilder _base = new StringBuilder();
    StringBuilder _rest = new StringBuilder();
    int restSize = -1; // number of ".." needed to go back to the 'base' level.
    boolean zip = false; // if we are asked to serve a zip file bundle
    boolean plain = false; // if asked to serve a plain text directory listing
    {
      boolean inBase = true;
      StringTokenizer pathTokens = new StringTokenizer(path, "/");
      while (pathTokens.hasMoreTokens()) {
        String pathElement = pathTokens.nextToken();
        // Treat * and ? as wildcard unless they match a literal filename
        if ((pathElement.contains("?") || pathElement.contains("*"))
            && inBase
            && !(new FilePath(root, (_base.length() > 0 ? _base + "/" : "") + pathElement)
                .exists())) inBase = false;
        if (pathElement.equals("*zip*")) {
          // the expected syntax is foo/bar/*zip*/bar.zip
          // the last 'bar.zip' portion is to causes browses to set a good default file name.
          // so the 'rest' portion ends here.
          zip = true;
          break;
        }
        if (pathElement.equals("*plain*")) {
          plain = true;
          break;
        }

        StringBuilder sb = inBase ? _base : _rest;
        if (sb.length() > 0) sb.append('/');
        sb.append(pathElement);
        if (!inBase) restSize++;
      }
    }
    restSize = Math.max(restSize, 0);
    String base = _base.toString();
    String rest = _rest.toString();

    // this is the base file/directory
    FilePath baseFile = new FilePath(root, base);

    if (baseFile.isDirectory()) {
      if (zip) {
        rsp.setContentType("application/zip");
        baseFile.zip(rsp.getOutputStream(), rest);
        return;
      }
      if (plain) {
        rsp.setContentType("text/plain;charset=UTF-8");
        OutputStream os = rsp.getOutputStream();
        try {
          for (String kid : baseFile.act(new SimpleChildList())) {
            os.write(kid.getBytes("UTF-8"));
            os.write('\n');
          }
          os.flush();
        } finally {
          os.close();
        }
        return;
      }

      if (rest.length() == 0) {
        // if the target page to be displayed is a directory and the path doesn't end with '/',
        // redirect
        StringBuffer reqUrl = req.getRequestURL();
        if (reqUrl.charAt(reqUrl.length() - 1) != '/') {
          rsp.sendRedirect2(reqUrl.append('/').toString());
          return;
        }
      }

      FileCallable<List<List<Path>>> glob = null;

      if (rest.length() > 0) {
        // the rest is Ant glob pattern
        glob = new PatternScanner(rest, createBackRef(restSize));
      } else if (serveDirIndex) {
        // serve directory index
        glob = new ChildPathBuilder();
      }

      if (glob != null) {
        // serve glob
        req.setAttribute("it", this);
        List<Path> parentPaths = buildParentPath(base, restSize);
        req.setAttribute("parentPath", parentPaths);
        req.setAttribute("backPath", createBackRef(restSize));
        req.setAttribute("topPath", createBackRef(parentPaths.size() + restSize));
        req.setAttribute("files", baseFile.act(glob));
        req.setAttribute("icon", icon);
        req.setAttribute("path", path);
        req.setAttribute("pattern", rest);
        req.setAttribute("dir", baseFile);
        req.getView(this, "dir.jelly").forward(req, rsp);
        return;
      }

      // convert a directory service request to a single file service request by serving
      // 'index.html'
      baseFile = baseFile.child(indexFileName);
    }

    // serve a single file
    if (!baseFile.exists()) {
      rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    boolean view = rest.equals("*view*");

    if (rest.equals("*fingerprint*")) {
      rsp.forward(Hudson.getInstance().getFingerprint(baseFile.digest()), "/", req);
      return;
    }

    ContentInfo ci = baseFile.act(new ContentInfo());

    if (LOGGER.isLoggable(Level.FINE))
      LOGGER.fine(
          "Serving "
              + baseFile
              + " with lastModified="
              + ci.lastModified
              + ", contentLength="
              + ci.contentLength);

    InputStream in = baseFile.read();
    if (view) {
      // for binary files, provide the file name for download
      rsp.setHeader("Content-Disposition", "inline; filename=" + baseFile.getName());

      // pseudo file name to let the Stapler set text/plain
      rsp.serveFile(req, in, ci.lastModified, -1, ci.contentLength, "plain.txt");
    } else {
      rsp.serveFile(req, in, ci.lastModified, -1, ci.contentLength, baseFile.getName());
    }
  }