private void execute(HttpAction action, InputStream input) { // OPTIONS if (action.request.getMethod().equals(HttpNames.METHOD_OPTIONS)) { // Share with update via SPARQL_Protocol. doOptions(action); return; } UsingList usingList = processProtocol(action.request); // If the dsg is transactional, then we can parse and execute the update in a streaming fashion. // If it isn't, we need to read the entire update request before performing any updates, because // we have to attempt to make the request atomic in the face of malformed queries UpdateRequest req = null; if (!action.isTransactional()) { try { // TODO implement a spill-to-disk version of this req = UpdateFactory.read(usingList, input, UpdateParseBase, Syntax.syntaxARQ); } catch (UpdateException ex) { ServletOps.errorBadRequest(ex.getMessage()); return; } catch (QueryParseException ex) { ServletOps.errorBadRequest(messageForQueryException(ex)); return; } } action.beginWrite(); try { if (req == null) UpdateAction.parseExecute( usingList, action.getActiveDSG(), input, UpdateParseBase, Syntax.syntaxARQ); else UpdateAction.execute(req, action.getActiveDSG()); action.commit(); } catch (UpdateException ex) { action.abort(); incCounter(action.getEndpoint().getCounters(), UpdateExecErrors); ServletOps.errorOccurred(ex.getMessage()); } catch (QueryParseException | QueryBuildException ex) { action.abort(); // Counter inc'ed further out. ServletOps.errorBadRequest(messageForQueryException(ex)); } catch (Throwable ex) { if (!(ex instanceof ActionErrorException)) { try { action.abort(); } catch (Exception ex2) { } ServletOps.errorOccurred(ex.getMessage(), ex); } } finally { action.endWrite(); } }
private static Node createNode(String x) { try { IRI iri = resolver.resolve(x); return NodeFactory.createURI(iri.toString()); } catch (Exception ex) { ServletOps.errorBadRequest("SPARQL Update: bad IRI: " + x); return null; } }
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(); } }
@Override protected void validate(HttpAction action) { HttpServletRequest request = action.request; if (HttpNames.METHOD_OPTIONS.equals(request.getMethod())) return; if (!HttpNames.METHOD_POST.equalsIgnoreCase(request.getMethod())) ServletOps.errorMethodNotAllowed("SPARQL Update : use POST"); ContentType ct = FusekiLib.getContentType(action); if (ct == null) ct = ctSPARQLUpdate; if (matchContentType(ctSPARQLUpdate, ct)) { String charset = request.getCharacterEncoding(); if (charset != null && !charset.equalsIgnoreCase(charsetUTF8)) ServletOps.errorBadRequest("Bad charset: " + charset); validate(action, paramsPOST); return; } if (isHtmlForm(ct)) { int x = countParamOccurences(request, paramUpdate) + countParamOccurences(request, paramRequest); if (x == 0) ServletOps.errorBadRequest("SPARQL Update: No 'update=' parameter"); if (x != 1) ServletOps.errorBadRequest("SPARQL Update: Multiple 'update=' parameters"); String requestStr = request.getParameter(paramUpdate); if (requestStr == null) requestStr = request.getParameter(paramRequest); if (requestStr == null) ServletOps.errorBadRequest("SPARQL Update: No update= in HTML form"); validate(action, paramsForm); return; } ServletOps.error( HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Must be " + contentTypeSPARQLUpdate + " or " + contentTypeHTMLForm + " (got " + ct.getContentType() + ")"); }
@Override protected void doGet(HttpAction action) { // Assume success - do the set up before grabbing the lock. // Sets content type. MediaType mediaType = ActionLib.contentNegotationRDF(action); ServletOutputStream output; try { output = action.response.getOutputStream(); } catch (IOException ex) { ServletOps.errorOccurred(ex); output = null; } TypedOutputStream out = new TypedOutputStream(output, mediaType); Lang lang = RDFLanguages.contentTypeToLang(mediaType.getContentType()); if (action.verbose) action.log.info( format( "[%d] Get: Content-Type=%s, Charset=%s => %s", action.id, mediaType.getContentType(), mediaType.getCharset(), lang.getName())); action.beginRead(); setCommonHeaders(action.response); try { Target target = determineTarget(action); if (action.log.isDebugEnabled()) action.log.debug("GET->" + target); boolean exists = target.exists(); if (!exists) ServletOps.errorNotFound("No such graph: <" + target.name + ">"); // If we want to set the Content-Length, we need to buffer. // response.setContentLength(??) ; String ct = lang.getContentType().toHeaderString(); action.response.setContentType(ct); Graph g = target.graph(); // Special case RDF/XML to be the plain (faster, less readable) form RDFFormat fmt = (lang == Lang.RDFXML) ? RDFFormat.RDFXML_PLAIN : RDFWriterRegistry.defaultSerialization(lang); try { RDFDataMgr.write(out, g, fmt); } catch (JenaException ex) { // Some RDF/XML data is unwritable. All we can do is pretend it's a bad // request (inappropriate content type). // Good news - this happens before any output for RDF/XML-ABBREV. if (fmt.getLang().equals(Lang.RDFXML)) ServletOps.errorBadRequest("Failed to write output in RDF/XML: " + ex.getMessage()); else ServletOps.errorOccurred("Failed to write output: " + ex.getMessage(), ex); } ServletOps.success(action); } finally { action.endRead(); } }
/** * 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); } } }
/** * 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; }