|
1 package com.oracle.jmx.remote.rest.http; |
|
2 |
|
3 import com.oracle.jmx.remote.rest.json.JSONObject; |
|
4 import com.sun.net.httpserver.Headers; |
|
5 import com.sun.net.httpserver.HttpExchange; |
|
6 |
|
7 import javax.management.remote.rest.PlatformRestAdapter; |
|
8 import java.io.*; |
|
9 import java.net.URI; |
|
10 import java.net.URL; |
|
11 import java.net.URLDecoder; |
|
12 import java.net.URLEncoder; |
|
13 import java.util.Base64; |
|
14 import java.util.LinkedHashMap; |
|
15 import java.util.List; |
|
16 import java.util.Map; |
|
17 import java.util.stream.Collectors; |
|
18 |
|
19 public class HttpUtil { |
|
20 |
|
21 public static String getRequestCharset(HttpExchange ex) { |
|
22 String charset = null; |
|
23 List<String> contentType = ex.getRequestHeaders().get("Content-type"); |
|
24 if (contentType != null) { |
|
25 for (String kv : contentType) { |
|
26 for (String value : kv.split(";")) { |
|
27 value = value.trim(); |
|
28 if (value.toLowerCase().startsWith("charset=")) { |
|
29 charset = value.substring("charset=".length()); |
|
30 } |
|
31 } |
|
32 } |
|
33 } |
|
34 return charset; |
|
35 } |
|
36 |
|
37 public static String getAcceptCharset(HttpExchange ex) { |
|
38 List<String> acceptCharset = ex.getRequestHeaders().get("Accept-Charset"); |
|
39 if (acceptCharset != null && acceptCharset.size() > 0) { |
|
40 return acceptCharset.get(0); |
|
41 } |
|
42 return null; |
|
43 } |
|
44 |
|
45 public static String getGetRequestResource(HttpExchange ex) throws UnsupportedEncodingException { |
|
46 String charset = getRequestCharset(ex); |
|
47 String httpHandlerPath = ex.getHttpContext().getPath(); |
|
48 String requestURIpath = ex.getRequestURI().getPath(); |
|
49 String getRequestPath = requestURIpath.substring(httpHandlerPath.length()); |
|
50 if (charset != null) { |
|
51 return URLDecoder.decode(getRequestPath, charset); |
|
52 } else { |
|
53 return getRequestPath; |
|
54 } |
|
55 } |
|
56 |
|
57 public static String getGetRequestQuery(HttpExchange ex) throws UnsupportedEncodingException { |
|
58 String charset = getRequestCharset(ex); |
|
59 String query = ex.getRequestURI().getQuery(); |
|
60 if (charset != null && query != null) { |
|
61 return URLDecoder.decode(query, charset); |
|
62 } else { |
|
63 return query; |
|
64 } |
|
65 } |
|
66 |
|
67 public static Map<String, String> getGetRequestQueryMap(HttpExchange ex) |
|
68 throws UnsupportedEncodingException { |
|
69 String charset = getRequestCharset(ex); |
|
70 String query = ex.getRequestURI().getQuery(); |
|
71 if (charset != null && query != null) { |
|
72 query = URLDecoder.decode(query, charset); |
|
73 } |
|
74 Map<String, String> queryParams = new LinkedHashMap<>(); |
|
75 |
|
76 if (query == null || query.isEmpty()) { |
|
77 return queryParams; |
|
78 } |
|
79 String[] params = query.trim().split("&"); |
|
80 for (String param : params) { |
|
81 int idx = param.indexOf('='); |
|
82 queryParams.put(param.substring(0, idx), param.substring(idx + 1)); |
|
83 } |
|
84 return queryParams; |
|
85 } |
|
86 |
|
87 public static String getCredentials(HttpExchange exchange) { |
|
88 Headers rmap = exchange.getRequestHeaders(); |
|
89 String auth = rmap.getFirst("Authorization"); |
|
90 if (auth != null && !auth.isEmpty()) { |
|
91 int sp = auth.indexOf(' '); |
|
92 byte[] b = Base64.getDecoder().decode(auth.substring(sp + 1)); |
|
93 String authCredentials = new String(b); |
|
94 return authCredentials; |
|
95 } |
|
96 return ""; |
|
97 } |
|
98 |
|
99 public static String readRequestBody(HttpExchange he) throws IOException { |
|
100 String charset = getRequestCharset(he); |
|
101 StringBuilder stringBuilder = new StringBuilder(); |
|
102 InputStreamReader in = charset != null ? new InputStreamReader(he.getRequestBody(), charset) : new InputStreamReader(he.getRequestBody()); |
|
103 BufferedReader br = new BufferedReader(in); |
|
104 String line; |
|
105 while ((line = br.readLine()) != null) { |
|
106 String decode = charset != null ? URLDecoder.decode(line, charset) : line; |
|
107 stringBuilder.append(decode); |
|
108 } |
|
109 return stringBuilder.toString(); |
|
110 } |
|
111 |
|
112 public static void sendResponse(HttpExchange exchange, HttpResponse response) throws IOException { |
|
113 String charset = getRequestCharset(exchange); |
|
114 String acceptCharset = HttpUtil.getAcceptCharset(exchange); |
|
115 if (acceptCharset != null) { |
|
116 charset = acceptCharset; |
|
117 } |
|
118 |
|
119 // Set response headers explicitly |
|
120 String msg = charset == null ? response.getResponse() : URLEncoder.encode(response.getResponse(), charset); |
|
121 byte[] bytes = msg.getBytes(); |
|
122 Headers resHeaders = exchange.getResponseHeaders(); |
|
123 resHeaders.add("Content-Type", "application/json; charset=" + charset); |
|
124 |
|
125 exchange.sendResponseHeaders(response.getCode(), bytes.length); |
|
126 try (OutputStream os = exchange.getResponseBody()) { |
|
127 os.write(bytes); |
|
128 } |
|
129 } |
|
130 |
|
131 public static <T> List<T> filterByPage(HttpExchange exchange, List<T> input, int pageSize) throws UnsupportedEncodingException { |
|
132 if (input.size() <= pageSize) { |
|
133 return input; |
|
134 } |
|
135 Map<String, String> queryParams = HttpUtil.getGetRequestQueryMap(exchange); |
|
136 int currPage = 1; |
|
137 if (queryParams != null && !queryParams.isEmpty()) { |
|
138 String pageStr = queryParams.get("page"); |
|
139 if (pageStr != null && !pageStr.isEmpty()) { |
|
140 currPage = Integer.parseInt(pageStr); |
|
141 currPage = currPage > 1 ? currPage : 1; |
|
142 } |
|
143 } |
|
144 int start = (currPage - 1) * pageSize; |
|
145 int end = Math.min(input.size(), start + pageSize); |
|
146 if (start < end) { |
|
147 return input.subList(start, end); |
|
148 } else { |
|
149 return null; |
|
150 } |
|
151 } |
|
152 |
|
153 public static <T> JSONObject getPaginationLinks(HttpExchange exchange, List<T> input, int pageSize) throws UnsupportedEncodingException { |
|
154 |
|
155 if (pageSize >= input.size()) { |
|
156 return null; |
|
157 } |
|
158 |
|
159 Map<String, String> queryParams = HttpUtil.getGetRequestQueryMap(exchange); |
|
160 int currPage = 1; |
|
161 if (queryParams != null && !queryParams.isEmpty()) { |
|
162 String pageStr = queryParams.get("page"); |
|
163 if (pageStr != null && !pageStr.isEmpty()) { |
|
164 currPage = Integer.parseInt(pageStr); |
|
165 } |
|
166 } |
|
167 String path = PlatformRestAdapter.getAuthority() + exchange.getRequestURI().getPath() + "?"; |
|
168 Map<String, String> queryMap = getGetRequestQueryMap(exchange); |
|
169 if (queryMap != null) { |
|
170 queryMap.remove("page"); |
|
171 if (!queryMap.isEmpty()) { |
|
172 String query = queryMap.keySet().stream() |
|
173 .map(k -> k + "=" + queryMap.get(k)) |
|
174 .collect(Collectors.joining("&")); |
|
175 path = path + query + "&"; |
|
176 } |
|
177 } |
|
178 int totalPages = (input.size() % pageSize == 0) ? input.size() / pageSize : input.size() / pageSize + 1; |
|
179 |
|
180 JSONObject jobj = new JSONObject(); |
|
181 jobj.put("first", path.replaceAll(".$", "")); |
|
182 if (currPage == 2) { |
|
183 jobj.put("prev", path.replaceAll(".$", "")); |
|
184 } else if (currPage > 2) { |
|
185 jobj.put("prev", path + "page=" + (currPage - 1)); |
|
186 } |
|
187 if (currPage < totalPages) { |
|
188 jobj.put("next", path + "page=" + (currPage + 1)); |
|
189 } |
|
190 jobj.put("last", path + "page=" + totalPages); |
|
191 |
|
192 return jobj; |
|
193 } |
|
194 |
|
195 public static String escapeUrl(String input) { |
|
196 try { |
|
197 URL url = new URL(input); |
|
198 URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef()); |
|
199 return uri.toURL().toString(); |
|
200 } catch (Exception ex) { |
|
201 ex.printStackTrace(); |
|
202 return null; |
|
203 } |
|
204 } |
|
205 |
|
206 } |