public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { List<Ancestor> l = req.getAncestors(); for (int i = l.size() - 1; i >= 0; i--) { Ancestor a = l.get(i); if (a.getObject() instanceof SearchableModelObject) { SearchableModelObject smo = (SearchableModelObject) a.getObject(); SearchIndex index = smo.getSearchIndex(); String query = req.getParameter("q"); if (query != null) { SuggestedItem target = find(index, query); if (target != null) { // found rsp.sendRedirect2(a.getUrl() + target.getUrl()); return; } } } } // no exact match. show the suggestions rsp.setStatus(SC_NOT_FOUND); req.getView(this, "search-failed.jelly").forward(req, rsp); }
public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup owner) throws FormException, IOException, ServletException { String requestContentType = req.getContentType(); if (requestContentType == null) throw new Failure("No Content-Type header set"); boolean isXmlSubmission = requestContentType.startsWith("application/xml") || requestContentType.startsWith("text/xml"); String name = req.getParameter("name"); checkGoodName(name); if (owner.getView(name) != null) throw new FormException(Messages.Hudson_ViewAlreadyExists(name), "name"); String mode = req.getParameter("mode"); if (mode == null || mode.length() == 0) { if (isXmlSubmission) { View v; v = createViewFromXML(name, req.getInputStream()); v.owner = owner; rsp.setStatus(HttpServletResponse.SC_OK); return v; } else throw new FormException(Messages.View_MissingMode(), "mode"); } // create a view View v = all().findByName(mode).newInstance(req, req.getSubmittedForm()); v.owner = owner; // redirect to the config screen rsp.sendRedirect2(req.getContextPath() + '/' + v.getUrl() + v.getPostConstructLandingPage()); return v; }
/** * Implements the progressive text handling. This method is used as a "web method" with * progressiveText.jelly. */ public void doProgressText(StaplerRequest req, StaplerResponse rsp) throws IOException { setContentType(rsp); rsp.setStatus(HttpServletResponse.SC_OK); if (!source.exists()) { // file doesn't exist yet rsp.addHeader("X-Text-Size", "0"); rsp.addHeader("X-More-Data", "true"); return; } long start = 0; String s = req.getParameter("start"); if (s != null) start = Long.parseLong(s); if (source.length() < start) start = 0; // text rolled over CharSpool spool = new CharSpool(); long r = writeLogTo(start, spool); rsp.addHeader("X-Text-Size", String.valueOf(r)); if (!completed) rsp.addHeader("X-More-Data", "true"); Writer w = createWriter(req, rsp, r - start); spool.writeTo(new LineEndNormalizingWriter(w)); w.close(); }
/** Accepts submission from the configuration page. */ @RequirePOST public synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); description = req.getParameter("description"); keepDependencies = req.getParameter("keepDependencies") != null; try { JSONObject json = req.getSubmittedForm(); setDisplayName(json.optString("displayNameOrNull")); if (req.getParameter("logrotate") != null) logRotator = LogRotator.DESCRIPTOR.newInstance(req, json.getJSONObject("logrotate")); else logRotator = null; DescribableList<JobProperty<?>, JobPropertyDescriptor> t = new DescribableList<JobProperty<?>, JobPropertyDescriptor>(NOOP, getAllProperties()); t.rebuild( req, json.optJSONObject("properties"), JobPropertyDescriptor.getPropertyDescriptors(Job.this.getClass())); properties.clear(); for (JobProperty p : t) { p.setOwner(this); properties.add(p); } submit(req, rsp); save(); ItemListener.fireOnUpdated(this); String newName = req.getParameter("name"); final ProjectNamingStrategy namingStrategy = Jenkins.getInstance().getProjectNamingStrategy(); if (newName != null && !newName.equals(name)) { // check this error early to avoid HTTP response splitting. Jenkins.checkGoodName(newName); namingStrategy.checkName(newName); rsp.sendRedirect("rename?newName=" + URLEncoder.encode(newName, "UTF-8")); } else { if (namingStrategy.isForceExistingJobs()) { namingStrategy.checkName(name); } FormApply.success(".").generateResponse(req, rsp, null); } } catch (JSONException e) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); pw.println("Failed to parse form data. Please report this problem as a bug"); pw.println("JSON=" + req.getSubmittedForm()); pw.println(); e.printStackTrace(pw); rsp.setStatus(SC_BAD_REQUEST); sendError(sw.toString(), req, rsp, true); } }
/** Handles incremental log output. */ public void doProgressiveHtml(StaplerRequest req, StaplerResponse rsp) throws IOException { AnnotatedLargeText text = obtainLog(); if (text != null) { text.doProgressiveHtml(req, rsp); return; } rsp.setStatus(HttpServletResponse.SC_OK); }
/** * Creates a {@link TopLevelItem} from the submission of the '/lib/hudson/newFromList/formList' or * throws an exception if it fails. */ public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { acl.checkPermission(Job.CREATE); TopLevelItem result; String requestContentType = req.getContentType(); if (requestContentType == null) throw new Failure("No Content-Type header set"); boolean isXmlSubmission = requestContentType.startsWith("application/xml") || requestContentType.startsWith("text/xml"); String name = req.getParameter("name"); if (name == null) throw new Failure("Query parameter 'name' is required"); { // check if the name looks good Jenkins.checkGoodName(name); name = name.trim(); if (parent.getItem(name) != null) throw new Failure(Messages.Hudson_JobAlreadyExists(name)); } String mode = req.getParameter("mode"); if (mode != null && mode.equals("copy")) { String from = req.getParameter("from"); // resolve a name to Item Item src = null; if (!from.startsWith("/")) src = parent.getItem(from); if (src == null) src = Jenkins.getInstance().getItemByFullName(from); if (src == null) { if (Util.fixEmpty(from) == null) throw new Failure("Specify which job to copy"); else throw new Failure("No such job: " + from); } if (!(src instanceof TopLevelItem)) throw new Failure(from + " cannot be copied"); result = copy((TopLevelItem) src, name); } else { if (isXmlSubmission) { result = createProjectFromXML(name, req.getInputStream()); rsp.setStatus(HttpServletResponse.SC_OK); return result; } else { if (mode == null) throw new Failure("No mode given"); // create empty job and redirect to the project config screen result = createProject(Items.all().findByName(mode), name, true); } } rsp.sendRedirect2(redirectAfterCreateItem(req, result)); return result; }
public static void adminCheck( StaplerRequest req, StaplerResponse rsp, Object required, Permission permission) throws IOException, ServletException { // this is legacy --- all views should be eventually converted to // the permission based model. if (required != null && !Hudson.adminCheck(req, rsp)) { // check failed. commit the FORBIDDEN response, then abort. rsp.setStatus(HttpServletResponse.SC_FORBIDDEN); rsp.getOutputStream().close(); throw new ServletException("Unauthorized access"); } // make sure the user owns the necessary permission to access this page. if (permission != null) checkPermission(permission); }
public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, InterruptedException { rsp.setStatus(SC_SERVICE_UNAVAILABLE); req.getView(this, "index.jelly").forward(req, rsp); }
@Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { rsp.setStatus(200); rsp.addHeader(X_BLUEOCEAN_JWT, sign()); }
/** * Notify the commit to this repository. * * <p>Because this URL is not guarded, we can't really trust the data that's sent to us. But we * intentionally don't protect this URL to simplify <tt>post-commit</tt> script set up. */ public void doNotifyCommit(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { requirePOST(); // compute the affected paths Set<String> affectedPath = new HashSet<String>(); String line; BufferedReader r = new BufferedReader(req.getReader()); try { while ((line = r.readLine()) != null) { if (LOGGER.isLoggable(FINER)) { LOGGER.finer("Reading line: " + line); } affectedPath.add(line.substring(4)); if (line.startsWith("svnlook changed --revision ")) { String msg = "Expecting the output from the svnlook command but instead you just sent me the svnlook invocation command line: " + line; LOGGER.warning(msg); throw new IllegalArgumentException(msg); } } } finally { IOUtils.closeQuietly(r); } if (LOGGER.isLoggable(FINE)) LOGGER.fine("Change reported to Subversion repository " + uuid + " on " + affectedPath); boolean scmFound = false, triggerFound = false, uuidFound = false, pathFound = false; // we can't reliably use req.getParameter() as it can try to parse the payload, which we've // already consumed above. // servlet container relies on Content-type to decide if it wants to parse the payload or not, // and at least // in case of Jetty, it doesn't check if the payload is QueryParameterMap query = new QueryParameterMap(req); String revParam = query.get("rev"); long rev = -1; if (revParam != null) { rev = Long.parseLong(revParam); } else { revParam = req.getHeader("X-Hudson-Subversion-Revision"); if (revParam != null) { rev = Long.parseLong(revParam); } } OUTER: for (AbstractProject<?, ?> p : Hudson.getInstance().getItems(AbstractProject.class)) { try { SCM scm = p.getScm(); if (scm instanceof SubversionSCM) scmFound = true; else continue; SCMTrigger trigger = p.getTrigger(SCMTrigger.class); if (trigger != null) triggerFound = true; else continue; SubversionSCM sscm = (SubversionSCM) scm; for (ModuleLocation loc : sscm.getLocations()) { if (loc.getUUID(p).equals(uuid)) uuidFound = true; else continue; String m = loc.getSVNURL().getPath(); String n = loc.getRepositoryRoot(p).getPath(); if (!m.startsWith(n)) continue; // repository root should be a subpath of the module path, but be defensive String remaining = m.substring(n.length()); if (remaining.startsWith("/")) remaining = remaining.substring(1); String remainingSlash = remaining + '/'; final RevisionParameterAction[] actions; if (rev != -1) { SvnInfo info[] = {new SvnInfo(loc.getURL(), rev)}; RevisionParameterAction action = new RevisionParameterAction(info); actions = new RevisionParameterAction[] {action}; } else { actions = new RevisionParameterAction[0]; } for (String path : affectedPath) { if (path.equals(remaining) /*for files*/ || path.startsWith(remainingSlash) /*for dirs*/) { // this project is possibly changed. poll now. // if any of the data we used was bogus, the trigger will not detect a change LOGGER.fine("Scheduling the immediate polling of " + p); trigger.run(actions); pathFound = true; continue OUTER; } } } } catch (SVNException e) { LOGGER.log(WARNING, "Failed to handle Subversion commit notification", e); } } if (!scmFound) LOGGER.warning("No subversion jobs found"); else if (!triggerFound) LOGGER.warning("No subversion jobs using SCM polling"); else if (!uuidFound) LOGGER.warning("No subversion jobs using repository: " + uuid); else if (!pathFound) LOGGER.fine("No jobs found matching the modified files"); rsp.setStatus(SC_OK); }
/* * 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()); }
/** 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(); } }