@Override protected final void perform(HttpAction action) { // OPTIONS if (action.request.getMethod().equals(HttpNames.METHOD_OPTIONS)) { // Share with update via SPARQL_Protocol. doOptions(action); return; } // GET if (action.request.getMethod().equals(HttpNames.METHOD_GET)) { executeWithParameter(action); return; } ContentType ct = FusekiLib.getContentType(action); // POST application/x-www-form-url // POST ?query= and no Content-Type if (ct == null || isHtmlForm(ct)) { // validation checked that if no Content-type, then its a POST with ?query= executeWithParameter(action); return; } // POST application/sparql-query if (matchContentType(ct, ctSPARQLQuery)) { executeBody(action); return; } ServletOps.error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Bad content type: " + ct.getContentType()); }
protected void execute(String queryString, HttpAction action) { String queryStringLog = ServletOps.formatForLog(queryString); if (action.verbose) action.log.info(format("[%d] Query = \n%s", action.id, queryString)); else action.log.info(format("[%d] Query = %s", action.id, queryStringLog)); Query query = null; try { // NB syntax is ARQ (a superset of SPARQL) query = QueryFactory.create(queryString, QueryParseBase, Syntax.syntaxARQ); queryStringLog = formatForLog(query); validateQuery(action, query); } catch (ActionErrorException ex) { throw ex; } catch (QueryParseException ex) { ServletOps.errorBadRequest( "Parse error: \n" + queryString + "\n\r" + messageForQueryException(ex)); } // Should not happen. catch (QueryException ex) { ServletOps.errorBadRequest("Error: \n" + queryString + "\n\r" + ex.getMessage()); } // Assumes finished whole thing by end of sendResult. try { action.beginRead(); Dataset dataset = decideDataset(action, query, queryStringLog); try (QueryExecution qExec = createQueryExecution(query, dataset); ) { SPARQLResult result = executeQuery(action, qExec, query, queryStringLog); // Deals with exceptions itself. sendResults(action, result, query.getPrologue()); } } catch (QueryParseException ex) { // Late stage static error (e.g. bad fixed Lucene query string). ServletOps.errorBadRequest( "Query parse error: \n" + queryString + "\n\r" + messageForQueryException(ex)); } catch (QueryCancelledException ex) { // Additional counter information. incCounter(action.getEndpoint().getCounters(), QueryTimeouts); throw ex; } finally { action.endRead(); } }
protected void executeBody(HttpAction action) { String queryString = null; try { InputStream input = action.request.getInputStream(); queryString = IO.readWholeFileAsUTF8(input); } catch (IOException ex) { ServletOps.errorOccurred(ex); } execute(queryString, action); }
/** * Ship the results to the remote caller. * * @param action * @param result * @param qPrologue */ protected void sendResults(HttpAction action, SPARQLResult result, Prologue qPrologue) { if (result.isResultSet()) ResponseResultSet.doResponseResultSet(action, result.getResultSet(), qPrologue); else if (result.isDataset()) // CONSTRUCT is processed as a extended CONSTRUCT - result is a dataset. ResponseDataset.doResponseDataset(action, result.getDataset()); else if (result.isModel()) // DESCRIBE results are models ResponseDataset.doResponseModel(action, result.getModel()); else if (result.isBoolean()) ResponseResultSet.doResponseResultSet(action, result.getBooleanResult()); else ServletOps.errorOccurred("Unknown or invalid result type"); }
/** * Validate the request, checking HTTP method and HTTP Parameters. * * @param action HTTP Action */ @Override protected void validate(HttpAction action) { String method = action.request.getMethod().toUpperCase(Locale.ROOT); if (HttpNames.METHOD_OPTIONS.equals(method)) return; if (!HttpNames.METHOD_POST.equals(method) && !HttpNames.METHOD_GET.equals(method)) ServletOps.errorMethodNotAllowed("Not a GET or POST request"); if (HttpNames.METHOD_GET.equals(method) && action.request.getQueryString() == null) { ServletOps.warning( action, "Service Description / SPARQL Query / " + action.request.getRequestURI()); ServletOps.errorNotFound("Service Description: " + action.request.getRequestURI()); } // Use of the dataset describing parameters is check later. try { validateParams(action, allParams); validateRequest(action); } catch (ActionErrorException ex) { throw ex; } // Query not yet parsed. }
/** * Perform the {@link QueryExecution} once. * * @param action * @param queryExecution * @param query * @param queryStringLog Informational string created from the initial query. * @return */ protected SPARQLResult executeQuery( HttpAction action, QueryExecution queryExecution, Query query, String queryStringLog) { setAnyTimeouts(queryExecution, action); if (query.isSelectType()) { ResultSet rs = queryExecution.execSelect(); // Force some query execution now. // If the timeout-first-row goes off, the output stream has not // been started so the HTTP error code is sent. rs.hasNext(); // If we wanted perfect query time cancellation, we could consume // the result now to see if the timeout-end-of-query goes off. // rs = ResultSetFactory.copyResults(rs) ; // action.log.info(format("[%d] exec/select", action.id)) ; return new SPARQLResult(rs); } if (query.isConstructType()) { Dataset dataset = queryExecution.execConstructDataset(); // action.log.info(format("[%d] exec/construct", action.id)); return new SPARQLResult(dataset); } if (query.isDescribeType()) { Model model = queryExecution.execDescribe(); // action.log.info(format("[%d] exec/describe", action.id)) ; return new SPARQLResult(model); } if (query.isAskType()) { boolean b = queryExecution.execAsk(); // action.log.info(format("[%d] exec/ask", action.id)) ; return new SPARQLResult(b); } ServletOps.errorBadRequest("Unknown query type - " + queryStringLog); return null; }
/** * Helper method for validating request. * * @param request HTTP request * @param params parameters in a collection of Strings */ protected void validateParams(HttpAction action, Collection<String> params) { HttpServletRequest request = action.request; ContentType ct = FusekiLib.getContentType(request); boolean mustHaveQueryParam = true; if (ct != null) { String incoming = ct.getContentType(); if (matchContentType(ctSPARQLQuery, ct)) { mustHaveQueryParam = false; // Drop through. } else if (matchContentType(ctHTMLForm, ct)) { // Nothing specific to do } else ServletOps.error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Unsupported: " + incoming); } // GET/POST of a form at this point. if (mustHaveQueryParam) { int N = countParamOccurences(request, paramQuery); if (N == 0) ServletOps.errorBadRequest("SPARQL Query: No 'query=' parameter"); if (N > 1) ServletOps.errorBadRequest("SPARQL Query: Multiple 'query=' parameters"); // application/sparql-query does not use a query param. String queryStr = request.getParameter(HttpNames.paramQuery); if (queryStr == null) ServletOps.errorBadRequest("SPARQL Query: No query specified (no 'query=' found)"); if (queryStr.isEmpty()) ServletOps.errorBadRequest("SPARQL Query: Empty query string"); } if (params != null) { Enumeration<String> en = request.getParameterNames(); for (; en.hasMoreElements(); ) { String name = en.nextElement(); if (!params.contains(name)) ServletOps.warning( action, "SPARQL Query: Unrecognize request parameter (ignored): " + name); } } }