/** 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(); }
/** 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); }
@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>"); }
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(); }
/** 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(); }
/** * 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(); }
/** * @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(); }
@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()); }
/** * 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); }
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>"); } }
/** 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(); }
/** 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); }
/** 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(); }
/** * 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()); } }
/** 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(); } }
/** 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"); }
public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { rsp.setContentType("text/plain"); rsp.getWriter().print(msg.keyValueFormEncoding()); }