/** * Handles POST requests for / * * @param apiEntry the object with form data about entry point. * @param result BindingResult with data about validation of input data. * @return JSP page which will be shown. */ @RequestMapping(value = "/", method = RequestMethod.POST) public String doCheckAPI(ApiEntry apiEntry, BindingResult result) { if (result.hasErrors()) { return JSP; } if (!apiEntry.getUrl().startsWith("http://") && !apiEntry.getUrl().startsWith("https://")) { apiEntry.setUrl("http://" + apiEntry.getUrl()); } if (apiEntry.getUrl().length() < 10) { apiEntry.setMessage("Invalid URL"); return JSP; } createTree(apiEntry); if (HttpValidator.responseOk(apiEntry) && apiEntry.getResourceNodes().getDescendants().size() > 0) { validateTree(apiEntry); generateViewOfQuestionnaires(apiEntry); generateViewOfResources(apiEntry); generateViewOfTree(apiEntry); return JSPOkResponse; } else { return JSPBadResponse; } }
/** * Handles POST requests for /repeatedtesting * * @param apiEntry the object with form data about entry point. * @return ResponseEntity with resource body. */ @RequestMapping(value = "/repeatedtesting", method = RequestMethod.POST) public ResponseEntity<String> doCheckAPIRepeatedTesting(ApiEntry apiEntry, BindingResult result) { if (result.hasErrors()) { apiEntry.setMessage("Invalid input: max siblings"); return new ResponseEntity<String>(apiEntry.getMessage(), HttpStatus.BAD_REQUEST); } if (!apiEntry.getUrl().startsWith("http://") && !apiEntry.getUrl().startsWith("https://")) { apiEntry.setUrl("http://" + apiEntry.getUrl()); } if (apiEntry.getUrl().length() < 10) { apiEntry.setMessage("Invalid input: URL"); return new ResponseEntity<String>(apiEntry.getMessage(), HttpStatus.BAD_REQUEST); } createTree(apiEntry); apiEntry.setMessage("<RESTfulChecker_report>"); generateViewOfEntryPointXML(apiEntry); validateTreeXML(apiEntry); generateViewOfTreeXML(apiEntry); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentType(MediaType.TEXT_XML); apiEntry.setMessage(apiEntry.getMessage() + "</RESTfulChecker_report>"); return new ResponseEntity<String>(apiEntry.getMessage(), responseHeaders, HttpStatus.OK); }
/** * Appends XML information about entrypoint into entrypoints message. * * @param apiEntry data about entrypoint. */ private void generateViewOfEntryPointXML(ApiEntry apiEntry) { StringBuilder sb = new StringBuilder(apiEntry.getMessage()); sb.append("<test_definition>"); sb.append("<request>"); sb.append("<API_entry_URL>"); sb.append(apiEntry.getUrl()); sb.append("</API_entry_URL>"); if (apiEntry.getRequestHeaders().size() > 0) { sb.append("<headers>"); for (Header header : apiEntry.getRequestHeaders()) { sb.append("<header>"); sb.append("<key>"); sb.append(header.getHeaderKey()); sb.append("</key>"); sb.append("<value>"); sb.append(header.getHeaderValue()); sb.append("</value>"); sb.append("</header>"); } sb.append("</headers>"); } sb.append("</request>"); sb.append("<limits>"); sb.append("<max_siblings>"); sb.append(apiEntry.getMaxSiblings()); sb.append("</max_siblings>"); sb.append("<base_url>"); sb.append(apiEntry.getBaseUrl()); sb.append("</base_url>"); sb.append("</limits>"); sb.append("</test_definition>"); apiEntry.setMessage(sb.toString()); }
/** * Discovers and crawls in currentResourceNode for aditional resources. * * @param currentResourceNode resource which will be crawled. * @param apiEntry Informations about api entrypoint. * @param discoveredResources Map which holds informations about already crawled resources. * @param toVisit queue used to store discovered resources for aditional crawling. */ private void doCrawle( ResourceNode currentResourceNode, ApiEntry apiEntry, Map<String, ResourceNode> discoveredResources, Queue<ResourceNode> toVisit) { if (discoveredResources.containsKey(currentResourceNode.getCurrentResource().getUrl())) { currentResourceNode.setCurrentResource( (RemoteResource) discoveredResources .get(currentResourceNode.getCurrentResource().getUrl()) .getCurrentResource()); currentResourceNode.setCurrentResourceOptions( (RemoteResource) discoveredResources .get(currentResourceNode.getCurrentResource().getUrl()) .getCurrentResourceOptions()); return; } currentResourceNode.sendOptions(); currentResourceNode.sendRequest(); LinkExtrator links = new LinkExtrator(); if (currentResourceNode.getCurrentResource().getResponseBody() == null) { return; } List<String> urls = UrlWorker.getUrls( currentResourceNode.getCurrentResource().getUrl(), links.grabHTMLLinks(currentResourceNode.getCurrentResource().getResponseBody())); List<String> validUrls = new ArrayList<String>(); for (String url : urls) { if (url.startsWith(apiEntry.getBaseUrl())) { validUrls.add(url); } } if (validUrls.size() > 0) { RemoteResource nextResource; int maxResourcesToLoad = apiEntry.getMaxSiblings(); for (String url : validUrls) { try { nextResource = (RemoteResource) currentResourceNode.getCurrentResource().clone(); nextResource.deletePreviousResponse(); if (apiEntry.getUrl().contains("?") && !url.contains("?")) { String append = currentResourceNode.getCurrentResource().getUrl(); append = currentResourceNode .getCurrentResource() .getUrl() .substring(currentResourceNode.getCurrentResource().getUrl().lastIndexOf('?')); nextResource.setUrl(url + append); } else { nextResource.setUrl(url); } ResourceNode nextResourceNode = new ResourceNode(nextResource); currentResourceNode.getDescendants().add(nextResourceNode); if (--maxResourcesToLoad < 0) { // No more crawling for this resource's childs. } else { toVisit.add(nextResourceNode); } } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } discoveredResources.put(currentResourceNode.getCurrentResource().getUrl(), currentResourceNode); }