@Override public ProjectResultReport postProject( ProjectExecutionRequest executionRequest, boolean async, HttpBasicAuth auth) throws ApiException { File projectFile = executionRequest.getProjectFile(); if (!projectFile.exists()) { throw new ApiException(404, "File [" + projectFile.toString() + "] not found"); } setAuthentication(auth); List<Pair> queryParams = buildQueryParameters( async, executionRequest.getTestCaseName(), executionRequest.getTestSuiteName(), executionRequest.getEnvironment()); String path = ServerDefaults.SERVICE_BASE_PATH + "/executions"; String type = "application/xml"; try { // composite project? if (projectFile.isDirectory()) { projectFile = zipCompositeProject(projectFile); path += "/composite"; type = "application/zip"; } else { path += "/xml"; } if (executionRequest.getCustomPropertiesMap().isEmpty()) { byte[] data = Files.readAllBytes(projectFile.toPath()); return invokeAPI(path, POST.name(), data, type, queryParams, null); } else { File propertiesFile = writeCustomPropertiesToFile(executionRequest.getCustomPropertiesMap().values()); Map<String, File> formParams = new HashMap<>(); formParams.put(projectFile.getName(), projectFile); formParams.put(propertiesFile.getName(), propertiesFile); return invokeAPI(path, POST.name(), null, "multipart/form-data", queryParams, formParams); } } catch (IOException e) { throw new ApiException(500, "Failed to read project; " + e.toString()); } }
@Override public Object getPayloadInstance(Method method) { if (POST.equals(method)) { return new String(); } return null; }
/** * Execute submitted test recipe * * @param testCase test case to run * @param async if true server will return executionID immediately without waiting for execution * to complete. If false, it will wait for the execution to finish before it returns * executionId and execution results. Default is true; * @param auth authentication object * @return ProjectResultReport execution result */ @Override public ProjectResultReport postTestRecipe(TestCase testCase, boolean async, HttpBasicAuth auth) throws ApiException { // verify the required parameter 'testCase' is set if (testCase == null) { throw new ApiException( 400, "Missing the required parameter 'testCase' when calling postTestRecipe"); } verifyDataSourceFilesExist(testCase); setAuthentication(auth); // create path and map variables String path = (ServerDefaults.SERVICE_BASE_PATH + "/executions").replaceAll("\\{format\\}", "json"); // query params List<Pair> queryParams = new ArrayList<>(); queryParams.add(new Pair("async", String.valueOf(async))); Map<String, File> formParams = new HashMap<>(); ProjectResultReport projectResultReport = invokeAPI(path, POST.name(), testCase, APPLICATION_JSON, queryParams, formParams); return sendPendingFiles(testCase, projectResultReport, queryParams); }
@Override public ProjectResultReport postSwagger( File swaggerFile, SwaggerApiValidator.SwaggerFormat swaggerFormat, String endpoint, String callBackUrl, boolean async, HttpBasicAuth auth) throws ApiException { if (!swaggerFile.exists()) { throw new ApiException(404, "File [" + swaggerFile.toString() + "] not found"); } setAuthentication(auth); List<Pair> queryParams = new ArrayList<>(); queryParams.add(new Pair("async", String.valueOf(false))); if (StringUtils.isNotEmpty(endpoint)) { queryParams.add(new Pair("endpoint", endpoint)); } if (StringUtils.isNotEmpty(callBackUrl)) { queryParams.add(new Pair("callback", callBackUrl)); } try { byte[] data = Files.readAllBytes(swaggerFile.toPath()); return invokeAPI( SWAGGER_RESOURCE_PATH, POST.name(), data, swaggerFormat.getMimeType(), queryParams, null); } catch (IOException e) { throw new ApiException(500, "Failed to read Swagger file; " + e.toString()); } }
static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(TestTaskContentProvider.AUTHORITY, POST.getTableName(), POST.getOrdinal()); sUriMatcher.addURI( TestTaskContentProvider.AUTHORITY, POST.getTableName() + "/#", POST.getItemOrdinal()); sContentType = new HashMap<>(); sContentType.put(POST.getOrdinal(), POST.getType()); sContentType.put(POST.getItemOrdinal(), POST.getItemType()); }
@Override public Response serve(final Request req) { if (log.isDebugEnabled()) { log.debug("uri=" + req.uri); log.debug("method=" + req.method); log.debug("headers=" + req.headers); log.debug("params=" + req.params); } else if (log.isInfoEnabled()) log.info(req.method + " '" + req.uri + "' "); try { if (GET.equalsIgnoreCase(req.method)) { return doGet(req); } else if (POST.equalsIgnoreCase(req.method)) { return doPost(req); } else if (PUT.equalsIgnoreCase(req.method)) { return doPut(req); } else if (DELETE.equalsIgnoreCase(req.method)) { return doDelete(req); } else { return new Response(HTTP_METHOD_NOT_ALLOWED, MIME_TEXT_PLAIN, "" + req.method); } } catch (Throwable e) { log.error(e.getMessage(), e); final StringWriter w = new StringWriter(); e.printStackTrace(new PrintWriter(w)); /* * Note: if you send an HTTP_INTERNALERROR (500) the browser won't * display the response body so you have to send an Ok with the text * of the error message.... */ return new Response(HTTP_OK, MIME_TEXT_PLAIN, w.toString()); } }
HttpServerHandler( LayoutService layoutService, Map<Pattern, HttpService> httpServices, HttpSessionManager httpSessionManager, List<Object> jsonServices) { this.layoutService = layoutService; this.httpServices = ImmutableMap.copyOf(httpServices); this.httpSessionManager = httpSessionManager; List<JsonServiceMapping> jsonServiceMappings = Lists.newArrayList(); for (Object jsonService : jsonServices) { for (Method method : jsonService.getClass().getDeclaredMethods()) { GET annotationGET = method.getAnnotation(GET.class); if (annotationGET != null) { jsonServiceMappings.add( ImmutableJsonServiceMapping.builder() .httpMethod(HttpMethod.GET) .path(annotationGET.value()) .service(jsonService) .methodName(method.getName()) .build()); } POST annotationPOST = method.getAnnotation(POST.class); if (annotationPOST != null) { jsonServiceMappings.add( ImmutableJsonServiceMapping.builder() .httpMethod(HttpMethod.POST) .path(annotationPOST.value()) .service(jsonService) .methodName(method.getName()) .build()); } } } this.jsonServiceMappings = ImmutableList.copyOf(jsonServiceMappings); allChannels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); }
private ProjectResultReport sendPendingFiles( TestCase body, ProjectResultReport projectResultReport, List<Pair> queryParams) { String path = ServerDefaults.SERVICE_BASE_PATH + "/executions/" + projectResultReport.getExecutionID() + "/files"; Map<String, File> formParams = buildFormParametersForDataSourceFiles(body); addClientCertificateFile(formParams, body.getClientCertFileName()); addTestStepClientCertificateFile(body, formParams); if (formParams.isEmpty()) { return projectResultReport; } return invokeAPI(path, POST.name(), body, "multipart/form-data", queryParams, formParams); }
/** * Handles a operation request via HTTP. * * @param http The HttpExchange object that allows access to the request and response. * @throws IOException if an error occurs while attempting to process the request. */ private void processRequest(final HttpExchange http) throws IOException { final URI request = http.getRequestURI(); final String requestMethod = http.getRequestMethod(); boolean isGet = GET.equals(requestMethod); if (!isGet && !POST.equals(requestMethod)) { http.sendResponseHeaders(METHOD_NOT_ALLOWED, -1); return; } ModelNode dmr; ModelNode response; int status = OK; Headers requestHeaders = http.getRequestHeaders(); boolean encode = APPLICATION_DMR_ENCODED.equals(requestHeaders.getFirst(ACCEPT)) || APPLICATION_DMR_ENCODED.equals(requestHeaders.getFirst(CONTENT_TYPE)); try { dmr = isGet ? convertGetRequest(request) : convertPostRequest(http.getRequestBody(), encode); } catch (IllegalArgumentException iae) { ROOT_LOGGER.debugf("Unable to construct ModelNode '%s'", iae.getMessage()); http.sendResponseHeaders(INTERNAL_SERVER_ERROR, -1); return; } try { response = modelController.execute(new OperationBuilder(dmr).build()); } catch (Throwable t) { ROOT_LOGGER.modelRequestError(t); http.sendResponseHeaders(INTERNAL_SERVER_ERROR, -1); return; } if (response.hasDefined(OUTCOME) && FAILED.equals(response.get(OUTCOME).asString())) { status = INTERNAL_SERVER_ERROR; } boolean pretty = dmr.hasDefined("json.pretty") && dmr.get("json.pretty").asBoolean(); writeResponse(http, isGet, pretty, response, status, encode); }
@Override public ProjectResultReport postSwagger( URL swaggerApiURL, String endpoint, String callBackUrl, boolean async, HttpBasicAuth auth) throws ApiException { if (swaggerApiURL == null) { throw new ApiException(404, "Swagger API URL is null."); } setAuthentication(auth); List<Pair> queryParams = new ArrayList<>(); queryParams.add(new Pair("async", String.valueOf(async))); if (StringUtils.isNotEmpty(endpoint)) { queryParams.add(new Pair("endpoint", endpoint)); } if (StringUtils.isNotEmpty(callBackUrl)) { queryParams.add(new Pair("callback", callBackUrl)); } queryParams.add(new Pair("swaggerEndpoint", swaggerApiURL.toString())); return invokeAPI(SWAGGER_RESOURCE_PATH, POST.name(), null, APPLICATION_JSON, queryParams, null); }
@Override public ProjectResultReport postRepositoryProject( RepositoryProjectExecutionRequest request, boolean async, HttpBasicAuth auth) throws ApiException { setAuthentication(auth); List<Pair> queryParams = buildQueryParameters( async, request.getTestCaseName(), request.getTestSuiteName(), request.getEnvironment()); queryParams.add(new Pair("projectFileName", request.getProjectFileName())); if (request.getRepositoryName() != null) { queryParams.add(new Pair("repositoryName", request.getRepositoryName())); } return invokeAPI( ServerDefaults.SERVICE_BASE_PATH + "/executions/project", POST.name(), request.getCustomPropertiesMap().values(), "application/json", queryParams, null); }
public void handle(HttpExchange http) throws IOException { /** * Request Verification - before the request is handled a set of checks are performed for CSRF * and XSS */ /* * Completely disallow OPTIONS - if the browser suspects this is a cross site request just reject it. */ final String requestMethod = http.getRequestMethod(); if (OPTIONS.equals(requestMethod)) { drain(http); http.sendResponseHeaders(METHOD_NOT_ALLOWED, -1); return; } /* * Origin check, if it is set the Origin header should match the Host otherwise reject the request. * * This check is for cross site scripted GET and POST requests. */ final Headers headers = http.getRequestHeaders(); final URI request = http.getRequestURI(); if (headers.containsKey(ORIGIN)) { String origin = headers.getFirst(ORIGIN); String host = headers.getFirst(HOST); String protocol = http.getHttpContext().getServer() instanceof HttpServer ? HTTP : HTTPS; String allowedOrigin = protocol + "://" + host; // This will reject multi-origin Origin headers due to the exact match. if (origin.equals(allowedOrigin) == false) { drain(http); http.sendResponseHeaders(FORBIDDEN, -1); return; } } /* * Cross Site Request Forgery makes use of a specially constructed form to pass in what appears to be * a valid operation request - except for upload requests any inbound requests where the Content-Type * is not application/json or application/dmr-encoded will be rejected. */ final boolean uploadRequest = UPLOAD_REQUEST.equals(request.getPath()); if (POST.equals(requestMethod)) { if (uploadRequest) { // This type of request doesn't need the content type check. processUploadRequest(http); return; } String contentType = extractContentType(headers.getFirst(CONTENT_TYPE)); if (!(APPLICATION_JSON.equals(contentType) || APPLICATION_DMR_ENCODED.equals(contentType))) { drain(http); http.sendResponseHeaders(FORBIDDEN, -1); return; } } processRequest(http); }