]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/http/server/HttpServerUtils.java
Prepare next development cycle
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / http / server / HttpServerUtils.java
1 package org.argeo.cms.http.server;
2
3 import java.io.BufferedReader;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.io.UncheckedIOException;
7 import java.net.URI;
8 import java.net.URLDecoder;
9 import java.nio.charset.Charset;
10 import java.nio.charset.StandardCharsets;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Objects;
16
17 import org.argeo.api.acr.ContentRepository;
18 import org.argeo.api.acr.ContentSession;
19 import org.argeo.cms.auth.RemoteAuthUtils;
20 import org.argeo.cms.http.HttpMethod;
21 import org.argeo.cms.http.RemoteAuthHttpExchange;
22
23 import com.sun.net.httpserver.HttpContext;
24 import com.sun.net.httpserver.HttpExchange;
25
26 /** HTTP utilities on the server-side. */
27 public class HttpServerUtils {
28 private final static String SLASH = "/";
29
30 private static String extractPathWithingContext(HttpContext httpContext, String fullPath, boolean startWithSlash) {
31 Objects.requireNonNull(fullPath);
32 String contextPath = httpContext.getPath();
33 if (!fullPath.startsWith(contextPath))
34 throw new IllegalArgumentException(fullPath + " does not belong to context" + contextPath);
35 String path = fullPath.substring(contextPath.length());
36 // TODO optimise?
37 if (!startWithSlash && path.startsWith(SLASH)) {
38 path = path.substring(1);
39 } else if (startWithSlash && !path.startsWith(SLASH)) {
40 path = SLASH + path;
41 }
42 return path;
43 }
44
45 /** Path within the context, NOT starting with a slash. */
46 public static String relativize(HttpExchange exchange) {
47 URI uri = exchange.getRequestURI();
48 HttpContext httpContext = exchange.getHttpContext();
49 return extractPathWithingContext(httpContext, uri.getPath(), false);
50 }
51
52 /** Path within the context, starting with a slash. */
53 public static String subPath(HttpExchange exchange) {
54 URI uri = exchange.getRequestURI();
55 HttpContext httpContext = exchange.getHttpContext();
56 return extractPathWithingContext(httpContext, uri.getPath(), true);
57 }
58
59 /** Returns content session consistent with this HTTP context. */
60 public static ContentSession getContentSession(ContentRepository contentRepository, HttpExchange exchange) {
61 ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(),
62 new RemoteAuthHttpExchange(exchange));
63 return session;
64 }
65
66 /*
67 * QUERY PARAMETERS
68 */
69 /** Returns the HTTP parameters form an {@link HttpExchange}. */
70 public static Map<String, List<String>> parseParameters(HttpExchange exchange) {
71 // TODO check encoding?
72 Charset encoding = StandardCharsets.UTF_8;
73
74 Map<String, List<String>> parameters = new HashMap<>();
75 URI requestedUri = exchange.getRequestURI();
76 String query = requestedUri.getRawQuery();
77 parseQuery(query, parameters, encoding);
78
79 // TODO do we really want to support POST?
80 if (HttpMethod.POST.name().equalsIgnoreCase(exchange.getRequestMethod())) {
81 String postQuery;
82 try {
83 // We do not close the stream on purpose, since the body still needs to be read
84 BufferedReader br = new BufferedReader(new InputStreamReader(exchange.getRequestBody(), encoding));
85 postQuery = br.readLine();
86 } catch (IOException e) {
87 throw new UncheckedIOException("Cannot read exchange body", e);
88 }
89 parseQuery(postQuery, parameters, encoding);
90 }
91 return parameters;
92 }
93
94 private static void parseQuery(String query, Map<String, List<String>> parameters, Charset encoding) {
95 if (query == null)
96 return;
97 String pairs[] = query.split("[&]");
98 for (String pair : pairs) {
99 String param[] = pair.split("[=]");
100
101 String key = null;
102 String value = null;
103 if (param.length > 0) {
104 key = URLDecoder.decode(param[0], encoding);
105 }
106
107 if (param.length > 1) {
108 value = URLDecoder.decode(param[1], encoding);
109 }
110
111 if (!parameters.containsKey(key))
112 parameters.put(key, new ArrayList<>());
113 parameters.get(key).add(value);
114 }
115 }
116
117 /** singleton */
118 private HttpServerUtils() {
119
120 }
121 }