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.http.HttpServletRequest; 022import java.io.IOException; 023import java.net.URLDecoder; 024import java.util.*; 025 026/** 027 * Parsed HttpServletRequest. 028 */ 029public final class ParsedHttpRequest { 030 private final String pathInfo; 031 private final String method; 032 private final String queryString; 033 private final String requestUri; 034 private final String requestUrl; 035 private final byte[] inputStream; 036 private final String targetSpecification; 037 private final String version; 038 private final String targetEntity; 039 040 private final Map<String, String> headers = new HashMap(); 041 private final Map<String, List<String>> queryPairs = new LinkedHashMap<>(); 042 043 /** 044 * parse HttpServletRequest. 045 * 046 * @param request 047 * @throws IOException 048 */ 049 public ParsedHttpRequest(final HttpServletRequest request) throws IOException { 050 this.pathInfo = request.getPathInfo() != null ? request.getPathInfo() : ""; 051 this.method = request.getMethod() != null ? request.getMethod() : ""; 052 this.queryString = request.getQueryString() != null ? request.getQueryString() : ""; 053 this.requestUri = request.getRequestURI() != null ? request.getRequestURI() : ""; 054 this.requestUrl = request.getRequestURL().toString(); 055 056 for (final Enumeration en = request.getHeaderNames(); en.hasMoreElements();) { 057 final String headerName = en.nextElement().toString(); 058 this.headers.put(headerName, request.getHeader(headerName)); 059 } 060 061 final int len = request.getContentLength(); 062 if (len > 0) { 063 this.inputStream = new byte[len]; 064 request.getInputStream().read(this.inputStream); 065 } else { 066 this.inputStream = new byte[0]; 067 } 068 069 final String[] parts = this.requestUri.split("/"); 070 this.targetSpecification = parts.length > 1 ? parts[1] : null; 071 this.version = parts.length > 2 ? parts[2] : null; 072 this.targetEntity = parts.length > 3 ? parts[3] : null; 073 074 if (!this.queryString.isEmpty()) { 075 final String[] pairs = this.queryString.split("&"); 076 for (final String pair : pairs) { 077 final int idx = pair.indexOf("="); 078 if (idx != -1) { 079 final String rKey = pair.substring(0, idx); 080 final String rValue = pair.substring(idx + 1); 081 final String key = URLDecoder.decode(rKey, "UTF-8"); 082 final String value = URLDecoder.decode(rValue, "UTF-8"); 083 List<String> valuesList = this.queryPairs.get(key.toLowerCase()); 084 if (valuesList == null) { 085 valuesList = new ArrayList<>(1); 086 this.queryPairs.put(key, valuesList); 087 } 088 valuesList.add(value); 089 } 090 } 091 } 092 } 093 094 /** 095 * get http header as a list of HeaderEntry. 096 * @return 097 */ 098 public List<HeaderEntry> getHeaderEntryList() { 099 final List<HeaderEntry> list = new ArrayList<>(); 100 final Iterator it = this.headers.entrySet().iterator(); 101 while (it.hasNext()) { 102 final Map.Entry pair = (Map.Entry)it.next(); 103 System.out.println(pair.getKey() + " = " + pair.getValue()); 104 final HeaderEntry e = HeaderEntry.newBuilder() 105 .setKey((String) pair.getKey()) 106 .setValue((String) pair.getValue()) 107 .build(); 108 list.add(e); 109 it.remove(); // avoids a ConcurrentModificationException 110 } 111 return list; 112 } 113 114 /** 115 * get target to match specification like "Reef". 116 * 117 * @return specification 118 */ 119 public String getTargetSpecification() { 120 return this.targetSpecification; 121 } 122 123 /** 124 * get query string like "id=12345" . If no query string is provided in request, return empty string. 125 * 126 * @return 127 */ 128 public String getQueryString() { 129 return this.queryString; 130 } 131 132 /** 133 * get target target entity like "Evaluators". 134 * 135 * @return 136 */ 137 public String getTargetEntity() { 138 return this.targetEntity; 139 } 140 141 /** 142 * get http request method like "Get". 143 * 144 * @return 145 */ 146 public String getMethod() { 147 return this.method; 148 } 149 150 /** 151 * get input Stream. 152 * 153 * @return 154 */ 155 public byte[] getInputStream() { 156 return this.inputStream; 157 } 158 159 /** 160 * get request headers. 161 * 162 * @return 163 */ 164 public Map<String, String> getHeaders() { 165 return this.headers; 166 } 167 168 /** 169 * get parsed queries. 170 * 171 * @return 172 */ 173 public Map<String, List<String>> getQueryMap() { 174 return this.queryPairs; 175 } 176 177 /** 178 * get URL like //http://localhost:8080/Reef/Evaluators/. 179 * 180 * @return 181 */ 182 public String getRequestUrl() { 183 return this.requestUrl; 184 } 185 186 /** 187 * get path infor, like /Reef/Evaluators/. 188 * 189 * @return 190 */ 191 public String getPathInfo() { 192 return pathInfo; 193 } 194 195 /** 196 * get URI, like /Reef/Evaluators/. 197 * 198 * @return 199 */ 200 public String getRequestUri() { 201 return this.requestUri; 202 } 203 204 /** 205 * get version of the request for Rest API. 206 * 207 * @return 208 */ 209 public String getVersion() { 210 return version; 211 } 212}