Пример #1
0
 /** Sends out the raw polling log output. */
 public void doPollingLog(StaplerRequest req, StaplerResponse rsp) throws IOException {
   rsp.setContentType("text/plain;charset=UTF-8");
   // Prevent jelly from flushing stream so Content-Length header can be added afterwards
   FlushProofOutputStream out = new FlushProofOutputStream(rsp.getCompressedOutputStream(req));
   getPollingLogText().writeLogTo(0, out);
   out.close();
 }
Пример #2
0
  /** Serves <tt>help.html</tt> from the resource of {@link #clazz}. */
  public void doHelp(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
    String path = req.getRestOfPath();
    if (path.contains("..")) throw new ServletException("Illegal path: " + path);

    path = path.replace('/', '-');

    for (Class c = clazz; c != null; c = c.getSuperclass()) {
      RequestDispatcher rd = Stapler.getCurrentRequest().getView(c, "help" + path);
      if (rd != null) { // Jelly-generated help page
        rd.forward(req, rsp);
        return;
      }

      InputStream in = getHelpStream(c, path);
      if (in != null) {
        // TODO: generalize macro expansion and perhaps even support JEXL
        rsp.setContentType("text/html;charset=UTF-8");
        String literal = IOUtils.toString(in, "UTF-8");
        rsp.getWriter()
            .println(
                Util.replaceMacro(
                    literal, Collections.singletonMap("rootURL", req.getContextPath())));
        in.close();
        return;
      }
    }
    rsp.sendError(SC_NOT_FOUND);
  }
Пример #3
0
 @Restricted(DoNotUse.class)
 public void doStatic(StaplerRequest req, StaplerResponse rsp) throws Exception {
   rsp.setContentType("text/html;charset=UTF-8");
   PrintWriter pw = rsp.getWriter();
   pw.println("<html><head><title>Jenkins Workflow Reference</title></head><body>");
   pw.println("<h1>Steps</h1>");
   for (StepDescriptor d : getStepDescriptors(false)) {
     generateStepHelp(d, pw);
   }
   pw.println("<h1>Advanced/Deprecated Steps</h1>");
   for (StepDescriptor d : getStepDescriptors(true)) {
     generateStepHelp(d, pw);
   }
   pw.println("<h1>Variables</h1>");
   for (GlobalVariable v : getGlobalVariables()) {
     pw.println("<h2><code>" + v.getName() + "</code></h2>");
     RequestDispatcher rd = req.getView(v, "help");
     if (rd != null) {
       pw.println("(help for variables not currently supported here)");
       /* TODO RequestDispatcher.include sends that content, but then closes the stream and prevents further output from appearing.
               Also ${rootURL} etc. are not set, but no idea what JellyContext to pass to Functions.initPageVariables
               Not clear how to fix these issues except by rewriting all of this to be driven from a static.jelly page.
               Also need to use new PrintWriter(new OutputStreamWriter(rsp.getOutputStream(), "UTF-8")) and pw.flush() at the end
               (cannot use getWriter since RequestDispatcher.include will call getOutputStream).
       rd.include(req, rsp);
       */
     } else {
       pw.println("(no help)");
     }
   }
   pw.println("</body></html>");
 }
Пример #4
0
 private void writeBody(StaplerResponse response, JSONObject body) throws IOException {
   response.setContentType("application/json");
   PrintWriter writer = response.getWriter();
   writer.write(body.toString());
   writer.flush();
   writer.close();
 }
Пример #5
0
 /** Generate schema. */
 public void doSchema(StaplerRequest req, StaplerResponse rsp)
     throws IOException, ServletException {
   setHeaders(rsp);
   rsp.setContentType("application/xml");
   StreamResult r = new StreamResult(rsp.getOutputStream());
   new SchemaGenerator(new ModelBuilder().get(bean.getClass())).generateSchema(r);
   r.getOutputStream().close();
 }
Пример #6
0
  /**
   * Used by OpenSearch auto-completion. Returns JSON array of the form:
   *
   * <pre>
   * ["queryString",["comp1","comp2",...]]
   * </pre>
   *
   * See http://developer.mozilla.org/en/docs/Supporting_search_suggestions_in_search_plugins
   */
  public void doSuggestOpenSearch(StaplerRequest req, StaplerResponse rsp, @QueryParameter String q)
      throws IOException, ServletException {
    rsp.setContentType(Flavor.JSON.contentType);
    DataWriter w = Flavor.JSON.createDataWriter(null, rsp);
    w.startArray();
    w.value(q);

    w.startArray();
    for (SuggestedItem item : getSuggestions(req, q)) w.value(item.getPath());
    w.endArray();
    w.endArray();
  }
Пример #7
0
  /**
   * @param rsp The stapler response to write the output to.
   * @throws IOException
   */
  private void writeJSON(StaplerResponse rsp, JSONObject jsonObject) throws IOException {
    rsp.setContentType("application/json");
    PrintWriter w = rsp.getWriter();

    if (jsonObject == null) {
      w.write("null");
    } else {
      w.write(jsonObject.toString());
    }

    w.flush();
    w.close();
  }
Пример #8
0
    @WebMethod(name = "heapdump.hprof")
    public void doHeapDump(StaplerRequest req, StaplerResponse rsp)
        throws IOException, InterruptedException {
      owner.checkPermission(Jenkins.RUN_SCRIPTS);
      rsp.setContentType("application/octet-stream");

      FilePath dump = obtain();
      try {
        dump.copyTo(rsp.getCompressedOutputStream(req));
      } finally {
        dump.delete();
      }
    }
 /**
  * Check whether the "incorrect version" msg should be displayed, and returns what the currently
  * configured version is, in a json.
  */
 public void doVersionCheck(StaplerRequest req, StaplerResponse rsp, @QueryParameter String url)
     throws IOException {
   rsp.setContentType("text/plain;charset=UTF-8");
   JSONObject versionJSON = new JSONObject();
   String error_display_style = "none";
   if (!isGoodCNVersion(url)) {
     error_display_style = "inline";
   }
   versionJSON.element("error_display_style", error_display_style);
   VersionNumber version = getVersion(url);
   if (version != null) {
     versionJSON.element("version", version.toString());
   } else {
     versionJSON.element("version", "unknown");
   }
   rsp.getWriter().print(versionJSON.toString());
 }
Пример #10
0
    /**
     * Accepts <tt>config.xml</tt> submission, as well as serve it.
     */
    @WebMethod(name = "config.xml")
    public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp)
            throws IOException {
        if (req.getMethod().equals("GET")) {
            // read
            checkPermission(EXTENDED_READ);
            rsp.setContentType("application/xml");
            IOUtils.copy(getConfigFile().getFile(),rsp.getOutputStream());
            return;
        }
        if (req.getMethod().equals("POST")) {
            // submission
            updateByXml((Source)new StreamSource(req.getReader()));
            return;
        }

        // huh?
        rsp.sendError(SC_BAD_REQUEST);
    }
Пример #11
0
 private void _errorWithMarkup(String message, String cssClass)
     throws IOException, ServletException {
   if (message == null) {
     ok();
   } else {
     response.setContentType("text/html;charset=UTF-8");
     // 1x16 spacer needed for IE since it doesn't support min-height
     response
         .getWriter()
         .print(
             "<div class="
                 + cssClass
                 + "><img src='"
                 + request.getContextPath()
                 + Hudson.RESOURCE_PATH
                 + "/images/none.gif' height=16 width=1>"
                 + message
                 + "</div>");
   }
 }
Пример #12
0
  /** Dumps the contents of the export table. */
  public void doDumpExportTable(StaplerRequest req, StaplerResponse rsp)
      throws IOException, ServletException, InterruptedException {
    // this is a debug probe and may expose sensitive information
    checkPermission(Jenkins.ADMINISTER);

    rsp.setContentType("text/plain");
    PrintWriter w = new PrintWriter(rsp.getCompressedWriter(req));
    VirtualChannel vc = getChannel();
    if (vc instanceof Channel) {
      w.println("Master to slave");
      ((Channel) vc).dumpExportTable(w);
      w.flush(); // flush here once so that even if the dump from the slave fails, the client
      // gets some useful info

      w.println("\n\n\nSlave to master");
      w.print(vc.call(new DumpExportTableTask()));
    } else {
      w.println(Messages.Computer_BadChannel());
    }
    w.close();
  }
Пример #13
0
  /** Accepts <tt>config.xml</tt> submission, as well as serve it. */
  @WebMethod(name = "config.xml")
  public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp)
      throws IOException, ServletException {
    checkPermission(Jenkins.ADMINISTER);
    if (req.getMethod().equals("GET")) {
      // read
      rsp.setContentType("application/xml");
      Jenkins.XSTREAM2.toXML(getNode(), rsp.getOutputStream());
      return;
    }
    if (req.getMethod().equals("POST")) {
      // submission
      Node result = (Node) Jenkins.XSTREAM2.fromXML(req.getReader());

      replaceBy(result);
      return;
    }

    // huh?
    rsp.sendError(SC_BAD_REQUEST);
  }
Пример #14
0
  /** Accepts and serves the job description */
  public void doDescription(StaplerRequest req, StaplerResponse rsp) throws IOException {
    if (req.getMethod().equals("GET")) {
      // read
      rsp.setContentType("text/plain;charset=UTF-8");
      rsp.getWriter().write(Util.fixNull(this.getDescription()));
      return;
    }
    if (req.getMethod().equals("POST")) {
      checkPermission(CONFIGURE);

      // submission
      if (req.getParameter("description") != null) {
        this.setDescription(req.getParameter("description"));
        rsp.sendError(SC_NO_CONTENT);
        return;
      }
    }

    // huh?
    rsp.sendError(SC_BAD_REQUEST);
  }
  public void buildWithParameters(StaplerRequest req, StaplerResponse rsp)
      throws IOException, ServletException {
    List<ParameterValue> values = new ArrayList<ParameterValue>();
    for (ParameterDefinition d : this.getParameterDefinitions()) {
      ParameterValue value = d.createValue(req);
      if (value != null) {
        values.add(value);
      }
    }

    CauseAction buildCause = null;
    if (owner instanceof InheritanceProject) {
      buildCause = ((InheritanceProject) owner).getBuildCauseOverride(req);
    } else {
      buildCause = new CauseAction(new Cause.UserIdCause());
    }

    TimeDuration delay =
        (req.hasParameter("delay"))
            ? TimeDuration.fromString(req.getParameter("delay"))
            : new TimeDuration(0);

    Jenkins.getInstance()
        .getQueue()
        .schedule(
            owner,
            (int) delay.as(TimeUnit.SECONDS),
            new ParametersAction(values),
            buildCause,
            new VersioningAction(this.getVersioningMap()));

    if (requestWantsJson(req)) {
      rsp.setContentType("application/json");
      rsp.serveExposedBean(req, owner, Flavor.JSON);
    } else {
      // send the user back to the job top page.
      rsp.sendRedirect(".");
    }
  }
  /**
   * Serve a page at this URL.
   *
   * @param request
   * @param response
   * @throws IOException
   */
  public void doIndex(StaplerRequest request, StaplerResponse response) throws IOException {
    int precision = getPrecision(request);
    response.setContentType("text/plain;charset=UTF-8");
    PrintWriter writer = response.getWriter();

    TimestampsReader reader = new TimestampsReader(build);
    boolean timestampsFound = false;
    while (true) {
      List<Timestamp> timestamps = reader.read(1000);
      if (timestamps.isEmpty()) {
        break;
      }
      timestampsFound = true;
      for (Timestamp timestamp : timestamps) {
        writer.write(formatTimestamp(timestamp, precision));
      }
    }

    if (!timestampsFound) {
      writeConsoleNotes(writer, precision);
    }

    writer.flush();
  }
Пример #17
0
  /**
   * 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());
    }
  }
Пример #18
0
  /** Exposes the bean as XML. */
  public void doXml(
      StaplerRequest req,
      StaplerResponse rsp,
      @QueryParameter String xpath,
      @QueryParameter String wrapper,
      @QueryParameter String tree,
      @QueryParameter int depth)
      throws IOException, ServletException {
    setHeaders(rsp);

    String[] excludes = req.getParameterValues("exclude");

    if (xpath == null && excludes == null) {
      // serve the whole thing
      rsp.serveExposedBean(req, bean, Flavor.XML);
      return;
    }

    StringWriter sw = new StringWriter();

    // first write to String
    Model p = MODEL_BUILDER.get(bean.getClass());
    TreePruner pruner = (tree != null) ? new NamedPathPruner(tree) : new ByDepth(1 - depth);
    p.writeTo(bean, pruner, Flavor.XML.createDataWriter(bean, sw));

    // apply XPath
    Object result;
    try {
      Document dom = new SAXReader().read(new StringReader(sw.toString()));

      // apply exclusions
      if (excludes != null) {
        for (String exclude : excludes) {
          List<org.dom4j.Node> list = (List<org.dom4j.Node>) dom.selectNodes(exclude);
          for (org.dom4j.Node n : list) {
            Element parent = n.getParent();
            if (parent != null) parent.remove(n);
          }
        }
      }

      if (xpath == null) {
        result = dom;
      } else {
        List list = dom.selectNodes(xpath);
        if (wrapper != null) {
          Element root = DocumentFactory.getInstance().createElement(wrapper);
          for (Object o : list) {
            if (o instanceof String) {
              root.addText(o.toString());
            } else {
              root.add(((org.dom4j.Node) o).detach());
            }
          }
          result = root;
        } else if (list.isEmpty()) {
          rsp.setStatus(HttpServletResponse.SC_NOT_FOUND);
          rsp.getWriter().print(Messages.Api_NoXPathMatch(xpath));
          return;
        } else if (list.size() > 1) {
          rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
          rsp.getWriter().print(Messages.Api_MultipleMatch(xpath, list.size()));
          return;
        } else {
          result = list.get(0);
        }
      }

    } catch (DocumentException e) {
      LOGGER.log(Level.FINER, "Failed to do XPath/wrapper handling. XML is as follows:" + sw, e);
      throw new IOException2(
          "Failed to do XPath/wrapper handling. Turn on FINER logging to view XML.", e);
    }

    OutputStream o = rsp.getCompressedOutputStream(req);
    try {
      if (result instanceof CharacterData
          || result instanceof String
          || result instanceof Number
          || result instanceof Boolean) {
        if (INSECURE) {
          rsp.setContentType("text/plain;charset=UTF-8");
          String text =
              result instanceof CharacterData
                  ? ((CharacterData) result).getText()
                  : result.toString();
          o.write(text.getBytes("UTF-8"));
        } else {
          rsp.sendError(
              HttpURLConnection.HTTP_FORBIDDEN,
              "primitive XPath result sets forbidden; can use -Dhudson.model.Api.INSECURE=true if you run without security");
        }
        return;
      }

      // otherwise XML
      rsp.setContentType("application/xml;charset=UTF-8");
      new XMLWriter(o).write(result);
    } finally {
      o.close();
    }
  }
Пример #19
0
 /** Sends out an arbitrary HTML fragment. */
 public void respond(String html) throws IOException, ServletException {
   response.setContentType("text/html");
   response.getWriter().print(html);
 }
 protected void setContentType(StaplerResponse rsp) {
   rsp.setContentType("text/plain;charset=UTF-8");
 }
Пример #21
0
 public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node)
     throws IOException, ServletException {
   rsp.setContentType("text/plain");
   rsp.getWriter().print(msg.keyValueFormEncoding());
 }