001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package core.tut.pori.http; 017 018import java.io.IOException; 019import java.io.InputStream; 020import java.util.List; 021import java.util.Map; 022 023import javax.servlet.http.HttpServletRequest; 024import javax.servlet.http.HttpSession; 025 026import org.apache.commons.collections4.map.CaseInsensitiveMap; 027import org.apache.commons.lang3.StringUtils; 028import org.apache.log4j.Logger; 029 030import core.tut.pori.users.UserIdentity; 031import core.tut.pori.utils.HTTPParameterUtil; 032 033/** 034 * A service request definitions, which can be passed to ServiceHandler for service invocation. 035 * 036 */ 037public class ServiceRequest { 038 private static final Logger LOGGER = Logger.getLogger(ServiceRequest.class); 039 private UserIdentity _authenticatedUser = null; 040 private boolean _bodyRequested = false; 041 private CaseInsensitiveMap<String, String> _headers = null; 042 private String _httpMethod = null; // e.g. GET, POST 043 private String _methodName = null; 044 private Map<String, List<String>> _rawParameters = null; // the list of raw, URL decoded parameters 045 private HttpServletRequest _request = null; 046 private String _serviceName = null; 047 048 /** 049 * 050 */ 051 public ServiceRequest(){ 052 // nothing needed 053 } 054 055 /** 056 * this is only for sub-classing, use the static 057 * 058 * @return true if service name, method name and http method are given 059 */ 060 protected boolean isValid(){ 061 if(_serviceName == null || _methodName == null || _httpMethod == null){ 062 return false; 063 }else{ 064 return true; 065 } 066 } 067 068 /** 069 * 070 * @param request 071 * @return true if the given request was valid and != null 072 */ 073 public static boolean isValid(ServiceRequest request){ 074 if(request == null){ 075 return false; 076 }else{ 077 return request.isValid(); 078 } 079 } 080 081 /** 082 * 083 * @param authenticatedUser 084 * @param httpServletRequest 085 * @return new request or null on failure 086 */ 087 public static ServiceRequest createRequest(UserIdentity authenticatedUser, HttpServletRequest httpServletRequest){ 088 String path[] = StringUtils.split(httpServletRequest.getPathInfo(), Definitions.SEPARATOR_URI_PATH, 2); // get service and "the rest of the string" 089 ServiceRequest r = null; 090 if(path != null && path.length == 2){ 091 r = new ServiceRequest(); 092 r._serviceName = path[0]; 093 r._methodName = (path[1].endsWith(Definitions.SEPARATOR_URI_PATH) ? path[1].substring(0, path[1].length()-1) : path[1]); 094 r._request = httpServletRequest; 095 r._authenticatedUser = authenticatedUser; 096 r._httpMethod = httpServletRequest.getMethod(); 097 }else{ 098 LOGGER.debug("Method name is missing."); 099 } 100 return r; 101 } 102 103 /** 104 * Note: you can only read the body once. Further attempts will return null 105 * 106 * @return body or null if none available 107 */ 108 public InputStream getBody(){ 109 if(_bodyRequested){ 110 LOGGER.warn("Tried to read HTTP body, but it has already been read."); 111 }else if(_request != null){ 112 _bodyRequested = true; 113 try { 114 return _request.getInputStream(); 115 } catch (IOException ex) { 116 LOGGER.error(ex, ex); 117 } 118 } 119 return null; 120 } 121 122 /** 123 * @return the serviceName 124 */ 125 public String getServiceName() { 126 return _serviceName; 127 } 128 129 /** 130 * 131 * @return the http session for this request. A new session will be created if one does not already exist. Returns null if no HttpRequest is associated with this request. 132 */ 133 public HttpSession getSession(){ 134 if(_request == null){ 135 LOGGER.warn("No request object."); 136 return null; 137 }else{ 138 return _request.getSession(); 139 } 140 } 141 142 /** 143 * @param serviceName the serviceName to set 144 */ 145 public void setServiceName(String serviceName) { 146 _serviceName = serviceName; 147 } 148 149 /** 150 * @return the methodName 151 */ 152 public String getMethodName() { 153 return _methodName; 154 } 155 156 /** 157 * @param methodName the methodName to set 158 */ 159 public void setMethodName(String methodName) { 160 _methodName = methodName; 161 } 162 163 /** 164 * @return the raw URL encoded parameters 165 */ 166 public Map<String, List<String>> getRawParameters() { 167 if(_rawParameters == null){ 168 _rawParameters = HTTPParameterUtil.getParameterMap(_request, false); 169 } 170 return _rawParameters; 171 } 172 173 /** 174 * @return the authenticatedUser 175 */ 176 public UserIdentity getAuthenticatedUser() { 177 return _authenticatedUser; 178 } 179 180 /** 181 * @param authenticatedUser the authenticatedUser to set 182 */ 183 public void setAuthenticatedUser(UserIdentity authenticatedUser) { 184 _authenticatedUser = authenticatedUser; 185 } 186 187 /** 188 * @return the bodyRequested 189 */ 190 public boolean isBodyRequested() { 191 return _bodyRequested; 192 } 193 194 /** 195 * @return the method, e.g. GET, POST 196 */ 197 public String getHttpMethod() { 198 return _httpMethod; 199 } 200 201 /** 202 * @param method the method to set, e.g. GET, POST 203 */ 204 public void setHttpMethod(String method) { 205 _httpMethod = method; 206 } 207 208 /** 209 * Set/override the previously set headers. 210 * 211 * Note that HTTP headers are case insensitive and thus duplicate header names with only difference being the case will be removed. 212 * 213 * 214 * @param headers the map of header names/values, note that the passed list will NOT be used, and an internal copy of the map will be made. 215 */ 216 public void setHeaders(Map<String, String> headers) { 217 _headers = (headers == null || headers.isEmpty() ? null : new CaseInsensitiveMap<>(headers)); 218 } 219 220 /** 221 * 222 * @param headerName 223 * @return the value of header or null if the header does not exist 224 */ 225 public String getHeaderValue(String headerName) { 226 if(_headers != null){ // use the set map if available 227 return _headers.get(headerName); 228 }else if(_request != null){ 229 return _request.getHeader(headerName); 230 }else{ 231 return null; 232 } 233 } 234 235 /** 236 * @return the request 237 */ 238 public HttpServletRequest getRequest() { 239 return _request; 240 } 241}