You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2020/07/08 11:49:39 UTC

[jena] branch master updated: JENA-1934: Better error handling for bad HTML forms

This is an automated email from the ASF dual-hosted git repository.

andy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jena.git


The following commit(s) were added to refs/heads/master by this push:
     new f0f92f6  JENA-1934: Better error handling for bad HTML forms
     new 34e3485  Merge pull request #772 from afs/jena1934-fuseki-robust
f0f92f6 is described below

commit f0f92f630561d4365fd3b25d6f06b8b4c0746ca2
Author: Andy Seaborne <an...@apache.org>
AuthorDate: Thu Jul 2 16:00:06 2020 +0100

    JENA-1934: Better error handling for bad HTML forms
---
 .../org/apache/jena/fuseki/server/Dispatcher.java  | 57 +++++++++++++++-------
 .../org/apache/jena/fuseki/server/EndpointSet.java |  2 +-
 .../org/apache/jena/fuseki/main/FusekiServer.java  |  4 +-
 3 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Dispatcher.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Dispatcher.java
index a261689..285d9bf 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Dispatcher.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/Dispatcher.java
@@ -20,7 +20,7 @@ package org.apache.jena.fuseki.server;
 
 import static java.lang.String.format;
 import static org.apache.commons.lang3.StringUtils.isEmpty;
-import static org.apache.jena.fuseki.server.Operation.*;
+import static org.apache.jena.fuseki.server.Operation.GSP_R;
 import static org.apache.jena.fuseki.server.Operation.GSP_RW;
 import static org.apache.jena.fuseki.server.Operation.Query;
 import static org.apache.jena.fuseki.server.Operation.Update;
@@ -37,6 +37,7 @@ import org.apache.jena.fuseki.Fuseki;
 import org.apache.jena.fuseki.auth.Auth;
 import org.apache.jena.fuseki.servlets.*;
 import org.apache.jena.fuseki.system.ActionCategory;
+import org.apache.jena.riot.WebContent;
 import org.apache.jena.riot.web.HttpNames;
 import org.apache.jena.web.HttpSC;
 import org.slf4j.Logger;
@@ -228,23 +229,31 @@ public class Dispatcher {
      * look for a named endpoint that supplies the operation.
      */
     private static Endpoint chooseEndpoint(HttpAction action, DataService dataService, String endpointName) {
-        Endpoint ep = chooseEndpointNoLegacy(action, dataService, endpointName);
-        if ( ep != null )
-            return ep;
-        // No dispatch so far.
+        try {
+            Endpoint ep = chooseEndpointNoLegacy(action, dataService, endpointName);
+            if ( ep != null )
+                return ep;
+            // No dispatch so far.
+
+            if ( ! isEmpty(endpointName) )
+                return ep;
+            // [DISPATCH LEGACY]
 
-        if ( ! isEmpty(endpointName) )
+            // When it is a unnamed service request (operation on the dataset) and there
+            // is no match, search the named services.
+            Operation operation = chooseOperation(action);
+            // Search for an endpoint that provides the operation.
+            // No guarantee it has the access controls for the operation
+            // but in this case, access control will validate against all possible endpoints.
+            ep = findEndpointForOperation(action, dataService, operation, true);
             return ep;
-        // [DISPATCH LEGACY]
-
-        // When it is a unnamed service request (operation on the dataset) and there
-        // is no match, search the named services.
-        Operation operation = chooseOperation(action);
-        // Search for an endpoint that provides the operation.
-        // No guarantee it has the access controls for the operation
-        // but in this case, access control will validate against all possible endpoints.
-        ep = findEndpointForOperation(action, dataService, operation, true);
-        return ep;
+        } catch (ActionErrorException ex) {
+            throw ex;
+        } catch (RuntimeException ex) {
+            // Example: Jetty throws BadMessageException when it is an HTML form and it is too big.
+            ServletOps.errorBadRequest(ex.getMessage());
+            return null;
+        }
     }
 
     /**
@@ -267,7 +276,7 @@ public class Dispatcher {
             return null;
 
         // If there is one endpoint, dispatch there directly.
-        Endpoint ep = epSet.getOnly();
+        Endpoint ep = epSet.getExactlyOne();
         if ( ep != null )
             return ep;
         // No single direct dispatch. Multiple choices (different operation, same endpoint name)
@@ -373,11 +382,23 @@ public class Dispatcher {
 
         // -- Any other queryString
         // Query string now unexpected.
+
         // Place for an extension point.
         boolean hasParams = request.getParameterMap().size() > 0;
         if ( hasParams ) {
+            // One nasty case:
+            // Bad HTML form (content-type  application/x-www-form-urlencoded), but body is not an HTML form.
+            //  map is one entry, and the key is all of the body,
+            if ( WebContent.contentTypeHTMLForm.equals(request.getContentType()) ) {
+                ServletOps.errorBadRequest("Malformed request: unrecognized HTML form request");
+                return null;
+            }
             // Unrecognized ?key=value
-            ServletOps.errorBadRequest("Malformed request: unrecognized query string parameters: " + request.getQueryString());
+            String qs = request.getQueryString();
+            if ( qs != null )
+                ServletOps.errorBadRequest("Malformed request: unrecognized parameters: " + qs);
+            else
+                ServletOps.errorBadRequest(HttpSC.getMessage(HttpSC.BAD_REQUEST_400));
         }
 
 
diff --git a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/EndpointSet.java b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/EndpointSet.java
index 8aa9c98..c4f2b5a 100644
--- a/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/EndpointSet.java
+++ b/jena-fuseki2/jena-fuseki-core/src/main/java/org/apache/jena/fuseki/server/EndpointSet.java
@@ -104,7 +104,7 @@ public class EndpointSet {
     public Collection<Operation> operations() { return endpoints.keySet(); }
     
     /** Get the Endpoint for a singleton EndpointSet */
-    public Endpoint getOnly() {
+    public Endpoint getExactlyOne() {
         return single;
     }
     
diff --git a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiServer.java b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiServer.java
index 8f6e75f..2b09b94 100644
--- a/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiServer.java
+++ b/jena-fuseki2/jena-fuseki-main/src/main/java/org/apache/jena/fuseki/main/FusekiServer.java
@@ -273,7 +273,7 @@ public class FusekiServer {
         static {
             // This is the CrossOriginFilter default.
             corsInitParamsDft.put(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*");
-            // Variatiosn from CrossOriginFilter defaults.
+            // Variations from CrossOriginFilter defaults.
             corsInitParamsDft.put(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,POST,DELETE,PUT,HEAD,OPTIONS,PATCH");
             corsInitParamsDft.put(CrossOriginFilter.ALLOWED_HEADERS_PARAM,
                 "X-Requested-With, Content-Type, Accept, Origin, Last-Modified, Authorization");
@@ -974,6 +974,8 @@ public class FusekiServer {
             context.setDisplayName(Fuseki.servletRequestLogName);
             context.setErrorHandler(new FusekiErrorHandler1());
             context.setContextPath(contextPath);
+            // SPARQL Update by HTML - not the best way but.
+            context.setMaxFormContentSize(1024*1024);
             // securityHandler done in buildAccessControl
             return context;
         }