Ejemplo n.º 1
0
  private void executeBody(HttpAction action) {
    InputStream input = null;
    try {
      input = action.request.getInputStream();
    } catch (IOException ex) {
      ServletOps.errorOccurred(ex);
    }

    if (action.verbose) {
      // Verbose mode only .... capture request for logging (does not scale).
      String requestStr = null;
      try {
        requestStr = IO.readWholeFileAsUTF8(input);
      } catch (IOException ex) {
        IO.exception(ex);
      }
      action.log.info(format("[%d] Update = %s", action.id, ServletOps.formatForLog(requestStr)));

      input = new ByteArrayInputStream(requestStr.getBytes());
      requestStr = null;
    }

    execute(action, input);
    ServletOps.successNoContent(action);
  }
Ejemplo n.º 2
0
  @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();
    }
  }
Ejemplo n.º 3
0
  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();
    }
  }
Ejemplo n.º 4
0
  @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());
  }
Ejemplo n.º 5
0
 @Override
 protected void doOptions(HttpAction action) {
   setCommonHeadersForOptions(action.response);
   action.response.setHeader(HttpNames.hAllow, "GET,HEAD,OPTIONS");
   action.response.setHeader(HttpNames.hContentLengh, "0");
   ServletOps.success(action);
 }
Ejemplo n.º 6
0
 @Override
 protected void doHead(HttpAction action) {
   action.beginRead();
   setCommonHeaders(action.response);
   try {
     Target target = determineTarget(action);
     if (action.log.isDebugEnabled()) action.log.debug("HEAD->" + target);
     if (!target.exists()) {
       ServletOps.successNotFound(action);
       return;
     }
     MediaType mediaType = ActionLib.contentNegotationRDF(action);
     ServletOps.success(action);
   } finally {
     action.endRead();
   }
 }
Ejemplo n.º 7
0
 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;
   }
 }
Ejemplo n.º 8
0
 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);
 }
Ejemplo n.º 9
0
  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();
    }
  }
Ejemplo n.º 10
0
 protected void validate(HttpAction action, Collection<String> params) {
   if (params != null) {
     Enumeration<String> en = action.request.getParameterNames();
     for (; en.hasMoreElements(); ) {
       String name = en.nextElement();
       if (!params.contains(name))
         ServletOps.warning(
             action, "SPARQL Update: Unrecognized request parameter (ignored): " + name);
     }
   }
 }
Ejemplo n.º 11
0
 /**
  * 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");
 }
Ejemplo n.º 12
0
  /**
   * 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.
  }
Ejemplo n.º 13
0
  private void executeForm(HttpAction action) {
    String requestStr = action.request.getParameter(paramUpdate);
    if (requestStr == null) requestStr = action.request.getParameter(paramRequest);

    if (action.verbose) action.log.info(format("[%d] Form update = \n%s", action.id, requestStr));
    // A little ugly because we are taking a copy of the string, but hopefully shouldn't be too big
    // if we are in this code-path
    // If we didn't want this additional copy, we could make the parser take a Reader in addition to
    // an InputStream
    byte[] b = StrUtils.asUTF8bytes(requestStr);
    ByteArrayInputStream input = new ByteArrayInputStream(b);
    requestStr = null; // free it early at least
    execute(action, input);
    ServletOps.successPage(action, "Update succeeded");
  }
Ejemplo n.º 14
0
  @Override
  protected void perform(HttpAction action) {
    ContentType ct = FusekiLib.getContentType(action);
    if (ct == null) ct = ctSPARQLUpdate;

    if (matchContentType(ctSPARQLUpdate, ct)) {
      executeBody(action);
      return;
    }
    if (isHtmlForm(ct)) {
      executeForm(action);
      return;
    }
    ServletOps.error(
        HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Bad content type: " + action.request.getContentType());
  }
Ejemplo n.º 15
0
  /**
   * 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;
  }
Ejemplo n.º 16
0
  @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()
            + ")");
  }
Ejemplo n.º 17
0
  /**
   * 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);
      }
    }
  }
Ejemplo n.º 18
0
 @Override
 protected void doPost(HttpAction action) {
   ServletOps.errorMethodNotAllowed("POST : Read-only");
 }
Ejemplo n.º 19
0
 @Override
 protected void doDelete(HttpAction action) {
   ServletOps.errorMethodNotAllowed("DELETE : Read-only");
 }
Ejemplo n.º 20
0
 @Override
 protected void doPatch(HttpAction action) {
   ServletOps.errorMethodNotAllowed("PATCH : Read-only");
 }