HTTP parameters support
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 31 Aug 2023 12:18:42 +0000 (14:18 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 31 Aug 2023 12:18:42 +0000 (14:18 +0200)
org.argeo.cms.ee/src/org/argeo/cms/servlet/httpserver/ServletHttpExchange.java
org.argeo.cms/src/org/argeo/cms/http/HttpHeader.java
org.argeo.cms/src/org/argeo/cms/http/server/HttpServerUtils.java

index f5e9c03945f4877c62f36369d264d75ed5bd1aea..85553f01cd9f1fd1be76a348d1d0a90c6434c15f 100644 (file)
@@ -5,9 +5,14 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.InetSocketAddress;
 import java.net.URI;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
 
 import javax.net.ssl.SSLSession;
 import javax.servlet.http.HttpServletRequest;
@@ -72,7 +77,17 @@ class ServletHttpExchange extends HttpsExchange {
 
        @Override
        public URI getRequestURI() {
-               return URI.create(httpServletRequest.getRequestURI());
+               // TODO properly deal with charset?
+               Charset encoding = StandardCharsets.UTF_8;
+               Map<String, String[]> parameters = httpServletRequest.getParameterMap();
+               StringJoiner sb = new StringJoiner("&");
+               for (String key : parameters.keySet()) {
+                       for (String value : parameters.get(key)) {
+                               String pair = URLEncoder.encode(key, encoding) + '=' + URLEncoder.encode(value, encoding);
+                               sb.add(pair);
+                       }
+               }
+               return URI.create(httpServletRequest.getRequestURI() + (sb.length() != 0 ? '?' + sb.toString() : ""));
        }
 
        @Override
index ef7385d1d5516899100c4c30648582bf593c3ff7..91ca1f2af50eb389ff9fe44d248d7a8caaa3e1a1 100644 (file)
@@ -6,6 +6,7 @@ public enum HttpHeader {
        WWW_AUTHENTICATE("WWW-Authenticate"), //
        ALLOW("Allow"), //
        VIA("Via"), //
+       CONTENT_TYPE("Content-Type"), //
 
        // WebDav
        DAV("DAV"), //
index ab033f0ce068fa36a383769b84f56367e4e5fc37..a170507e5078d70c2fd5621a6ae638a33197a105 100644 (file)
@@ -1,8 +1,25 @@
 package org.argeo.cms.http.server;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UncheckedIOException;
 import java.net.URI;
+import java.net.URLDecoder;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
+import org.argeo.api.acr.ContentRepository;
+import org.argeo.api.acr.ContentSession;
+import org.argeo.cms.auth.RemoteAuthUtils;
+import org.argeo.cms.http.HttpMethod;
+import org.argeo.cms.internal.http.RemoteAuthHttpExchange;
+
 import com.sun.net.httpserver.HttpContext;
 import com.sun.net.httpserver.HttpExchange;
 
@@ -39,6 +56,64 @@ public class HttpServerUtils {
                return extractPathWithingContext(httpContext, uri.getPath(), true);
        }
 
+       /** Returns content session consistent with this HTTP context. */
+       public static ContentSession getContentSession(ContentRepository contentRepository, HttpExchange exchange) {
+               ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(),
+                               new RemoteAuthHttpExchange(exchange));
+               return session;
+       }
+
+       /*
+        * QUERY PARAMETERS
+        */
+       /** Returns the HTTP parameters form an {@link HttpExchange}. */
+       public static Map<String, List<String>> parseParameters(HttpExchange exchange) {
+               // TODO check encoding?
+               Charset encoding = StandardCharsets.UTF_8;
+
+               Map<String, List<String>> parameters = new HashMap<>();
+               URI requestedUri = exchange.getRequestURI();
+               String query = requestedUri.getRawQuery();
+               parseQuery(query, parameters, encoding);
+
+               // TODO do we really want to support POST?
+               if (HttpMethod.POST.name().equalsIgnoreCase(exchange.getRequestMethod())) {
+                       String postQuery;
+                       try {
+                               // We do not close the stream on purpose, since the body still needs to be read
+                               BufferedReader br = new BufferedReader(new InputStreamReader(exchange.getRequestBody(), encoding));
+                               postQuery = br.readLine();
+                       } catch (IOException e) {
+                               throw new UncheckedIOException("Cannot read exchange body", e);
+                       }
+                       parseQuery(postQuery, parameters, encoding);
+               }
+               return parameters;
+       }
+
+       private static void parseQuery(String query, Map<String, List<String>> parameters, Charset encoding) {
+               if (query == null)
+                       return;
+               String pairs[] = query.split("[&]");
+               for (String pair : pairs) {
+                       String param[] = pair.split("[=]");
+
+                       String key = null;
+                       String value = null;
+                       if (param.length > 0) {
+                               key = URLDecoder.decode(param[0], encoding);
+                       }
+
+                       if (param.length > 1) {
+                               value = URLDecoder.decode(param[1], encoding);
+                       }
+
+                       if (!parameters.containsKey(key))
+                               parameters.put(key, new ArrayList<>());
+                       parameters.get(key).add(value);
+               }
+       }
+
        /** singleton */
        private HttpServerUtils() {