001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.reef.webserver; 020 021import javax.servlet.ServletException; 022import javax.servlet.http.HttpServletRequest; 023import java.io.IOException; 024import java.net.URLDecoder; 025import java.util.*; 026 027/** 028 * Parsed HttpServletRequest 029 */ 030public final class ParsedHttpRequest { 031 private final String pathInfo; 032 private final String method; 033 private final String queryString; 034 private final String requestUri; 035 private final String requestUrl; 036 private final byte[] inputStream; 037 private final String targetSpecification; 038 private final String version; 039 private final String targetEntity; 040 041 private final Map<String, String> headers = new HashMap(); 042 private final Map<String, List<String>> queryPairs = new LinkedHashMap<>(); 043 044 /** 045 * parse HttpServletRequest 046 * 047 * @param request 048 * @throws IOException 049 * @throws ServletException 050 */ 051 public ParsedHttpRequest(final HttpServletRequest request) throws IOException { 052 this.pathInfo = request.getPathInfo() != null ? request.getPathInfo() : ""; 053 this.method = request.getMethod() != null ? request.getMethod() : ""; 054 this.queryString = request.getQueryString() != null ? request.getQueryString() : ""; 055 this.requestUri = request.getRequestURI() != null ? request.getRequestURI() : ""; 056 this.requestUrl = request.getRequestURL().toString(); 057 058 for (final Enumeration en = request.getHeaderNames(); en.hasMoreElements(); ) { 059 final String headerName = en.nextElement().toString(); 060 this.headers.put(headerName, request.getHeader(headerName)); 061 } 062 063 final int len = request.getContentLength(); 064 if (len > 0) { 065 this.inputStream = new byte[len]; 066 request.getInputStream().read(this.inputStream); 067 } else { 068 this.inputStream = new byte[0]; 069 } 070 071 final String[] parts = this.requestUri.split("/"); 072 this.targetSpecification = parts.length > 1 ? parts[1] : null; 073 this.version = parts.length > 2 ? parts[2] : null; 074 this.targetEntity = parts.length > 3 ? parts[3] : null; 075 076 if (this.queryString != null && !this.queryString.isEmpty()) { 077 final String[] pairs = this.queryString.split("&"); 078 for (final String pair : pairs) { 079 final int idx = pair.indexOf("="); 080 if (idx != -1) { 081 final String rKey = pair.substring(0, idx); 082 final String rValue = pair.substring(idx + 1); 083 final String key = URLDecoder.decode(rKey, "UTF-8"); 084 final String value = URLDecoder.decode(rValue, "UTF-8"); 085 List<String> valuesList = this.queryPairs.get(key.toLowerCase()); 086 if (valuesList == null) { 087 valuesList = new ArrayList<>(1); 088 this.queryPairs.put(key, valuesList); 089 } 090 valuesList.add(value); 091 } 092 } 093 } 094 } 095 096 /** 097 * get target to match specification like "Reef" 098 * 099 * @return specification 100 */ 101 public String getTargetSpecification() { 102 return this.targetSpecification; 103 } 104 105 /** 106 * get query string like "id=12345" . If no query string is provided in request, return empty string. 107 * 108 * @return 109 */ 110 public String getQueryString() { 111 return this.queryString; 112 } 113 114 /** 115 * get target target entity like "Evaluators" 116 * 117 * @return 118 */ 119 public String getTargetEntity() { 120 return this.targetEntity; 121 } 122 123 /** 124 * get http request method like "Get" 125 * 126 * @return 127 */ 128 public String getMethod() { 129 return this.method; 130 } 131 132 /** 133 * get input Stream 134 * 135 * @return 136 */ 137 public byte[] getInputStream() { 138 return this.inputStream; 139 } 140 141 /** 142 * get request headers 143 * 144 * @return 145 */ 146 public Map<String, String> getHeaders() { 147 return this.headers; 148 } 149 150 /** 151 * get parsed queries 152 * 153 * @return 154 */ 155 public Map<String, List<String>> getQueryMap() { 156 return this.queryPairs; 157 } 158 159 /** 160 * get URL like //http://localhost:8080/Reef/Evaluators/ 161 * 162 * @return 163 */ 164 public String getRequestUrl() { 165 return this.requestUrl; 166 } 167 168 /** 169 * get path infor, like /Reef/Evaluators/ 170 * 171 * @return 172 */ 173 public String getPathInfo() { 174 return pathInfo; 175 } 176 177 /** 178 * get URI, like /Reef/Evaluators/ 179 * 180 * @return 181 */ 182 public String getRequestUri() { 183 return this.requestUri; 184 } 185 186 /** 187 * get version of the request for Rest API 188 * 189 * @return 190 */ 191 public String getVersion() { 192 return version; 193 } 194}