3131 * the utility methods
3232 */
3333public abstract class AwsHttpServletRequest implements HttpServletRequest {
34+
3435 //-------------------------------------------------------------
3536 // Constants
3637 //-------------------------------------------------------------
@@ -46,6 +47,7 @@ public abstract class AwsHttpServletRequest implements HttpServletRequest {
4647 // information from anywhere else
4748 static final String CF_PROTOCOL_HEADER_NAME = "CloudFront-Forwarded-Proto" ;
4849
50+
4951 //-------------------------------------------------------------
5052 // Variables - Private
5153 //-------------------------------------------------------------
@@ -54,6 +56,7 @@ public abstract class AwsHttpServletRequest implements HttpServletRequest {
5456 private DispatcherType dispatcherType ;
5557 private Map <String , Object > attributes ;
5658
59+
5760 //-------------------------------------------------------------
5861 // Constructors
5962 //-------------------------------------------------------------
@@ -71,96 +74,6 @@ public abstract class AwsHttpServletRequest implements HttpServletRequest {
7174 dispatcherType = DispatcherType .REQUEST ;
7275 }
7376
74- //-------------------------------------------------------------
75- // Methods - Protected
76- //-------------------------------------------------------------
77-
78- /**
79- * Given the Cookie header value, parses it and creates a Cookie object
80- * @param headerValue The string value of the HTTP Cookie header
81- * @return An array of Cookie objects from the header
82- */
83- protected Cookie [] parseCookies (String headerValue ) {
84- List <Cookie > output = new ArrayList <>();
85-
86- for (AbstractMap .SimpleEntry <String , String > entry : this .parseHeaderValue (headerValue )) {
87- if (entry .getKey () != null ) {
88- output .add (new Cookie (entry .getKey (), entry .getValue ()));
89- }
90- }
91- Cookie [] returnValue = new Cookie [output .size ()];
92- return output .toArray (returnValue );
93- }
94-
95- protected String readPathInfo (String path , String resource ) {
96- // TODO: Implement
97- return "/" ;
98- }
99-
100- protected String readPathTranslated (String path ) {
101- // TODO: Implement
102- return path ;
103- }
104-
105- /**
106- * Given a map of key/values query string parameters from API Gateway, creates a query string as it would have
107- * been in the original url.
108- * @param parameters A Map<String, String> of query string parameters
109- * @return The generated query string for the URI
110- */
111- protected String generateQueryString (Map <String , String > parameters ) {
112- String params = null ;
113- if (parameters != null && parameters .size () > 0 ) {
114- params = "" ;
115- for (String key : parameters .keySet ()) {
116- String separator = params .equals ("" ) ? "?" : "&" ;
117- String queryStringKey = key ;
118- String queryStringValue = parameters .get (key );
119- try {
120- // if they were URLDecoded along the way we should re-encode them for the URI
121- if (!URLEncoder .encode (queryStringKey , StandardCharsets .UTF_8 .name ()).equals (key )) {
122- queryStringKey = URLEncoder .encode (queryStringKey , StandardCharsets .UTF_8 .name ());
123- }
124- if (!URLEncoder .encode (queryStringValue , StandardCharsets .UTF_8 .name ()).equals (queryStringValue )) {
125- queryStringValue = URLEncoder .encode (queryStringValue , StandardCharsets .UTF_8 .name ());
126- }
127- } catch (UnsupportedEncodingException e ) {
128- // TODO: Should we stop for the exception?
129- lamdaContext .getLogger ().log ("Could not URLEncode: " + queryStringKey );
130- e .printStackTrace ();
131- }
132- params += separator + queryStringKey + "=" + queryStringValue ;
133- }
134- }
135-
136- return params ;
137- }
138-
139- /**
140- * Generic method to parse an HTTP header value and split it into a list of key/values for all its components.
141- * When the property in the header does not specify a key the key field in the output pair is null and only the value
142- * is populated. For example, The header <code>Accept: application/json; application/xml</code> will contain two
143- * key value pairs with key null and the value set to application/json and application/xml respectively.
144- *
145- * @param headerContent The string value for the HTTP header
146- * @return A list of SimpleMapEntry objects with all of the possible values for the header.
147- */
148- protected List <AbstractMap .SimpleEntry <String , String >> parseHeaderValue (String headerContent ) {
149- List <AbstractMap .SimpleEntry <String , String >> values = new ArrayList <>();
150- if (headerContent != null ) {
151- for (String kv : headerContent .split (HEADER_VALUE_SEPARATOR )) {
152- String [] kvSplit = kv .split (HEADER_KEY_VALUE_SEPARATOR );
153-
154- if (kvSplit .length != 2 ) {
155- values .add (new AbstractMap .SimpleEntry <>(null , kv .trim ()));
156- } else {
157- values .add (new AbstractMap .SimpleEntry <>(kvSplit [0 ].trim (), kvSplit [1 ].trim ()));
158- }
159- }
160- }
161- return values ;
162- }
163-
16477 //-------------------------------------------------------------
16578 // Implementation - HttpServletRequest
16679 //-------------------------------------------------------------
@@ -171,6 +84,7 @@ public String getRequestedSessionId() {
17184 return null ;
17285 }
17386
87+
17488 @ Override
17589 public HttpSession getSession (boolean b ) {
17690 return null ;
@@ -212,38 +126,48 @@ public boolean isRequestedSessionIdFromUrl() {
212126 return false ;
213127 }
214128
129+
130+ //-------------------------------------------------------------
131+ // Implementation - ServletRequest
132+ //-------------------------------------------------------------
133+
134+
215135 @ Override
216136 public Object getAttribute (String s ) {
217137 return attributes .get (s );
218138 }
219139
140+
220141 @ Override
221142 public Enumeration <String > getAttributeNames () {
222143 return Collections .enumeration (attributes .keySet ());
223144 }
224145
146+
225147 @ Override
226- public void setAttribute ( String s , Object o ) {
227- attributes . put ( s , o ) ;
148+ public String getServerName ( ) {
149+ return "lambda.amazonaws.com" ;
228150 }
229151
230152
231153 @ Override
232- public void removeAttribute ( String s ) {
233- attributes . remove ( s ) ;
154+ public int getServerPort ( ) {
155+ return 0 ;
234156 }
235157
158+
236159 @ Override
237- public String getServerName ( ) {
238- return "lambda.amazonaws.com" ;
160+ public void setAttribute ( String s , Object o ) {
161+ attributes . put ( s , o ) ;
239162 }
240163
241164
242165 @ Override
243- public int getServerPort ( ) {
244- return 0 ;
166+ public void removeAttribute ( String s ) {
167+ attributes . remove ( s ) ;
245168 }
246169
170+
247171 @ Override
248172 public String getLocalName () {
249173 return "lambda.amazonaws.com" ;
@@ -261,6 +185,13 @@ public int getLocalPort() {
261185 return 0 ;
262186 }
263187
188+
189+ @ Override
190+ public ServletContext getServletContext () {
191+ return AwsServletContext .getInstance (lamdaContext );
192+ }
193+
194+
264195 @ Override
265196 public boolean isAsyncStarted () {
266197 return false ;
@@ -278,13 +209,104 @@ public AsyncContext getAsyncContext() {
278209 return null ;
279210 }
280211
281- @ Override
282- public ServletContext getServletContext () {
283- return AwsServletContext .getInstance (lamdaContext );
284- }
285212
286213 @ Override
287214 public DispatcherType getDispatcherType () {
288215 return dispatcherType ;
289216 }
217+
218+
219+ //-------------------------------------------------------------
220+ // Methods - Protected
221+ //-------------------------------------------------------------
222+
223+ /**
224+ * Given the Cookie header value, parses it and creates a Cookie object
225+ * @param headerValue The string value of the HTTP Cookie header
226+ * @return An array of Cookie objects from the header
227+ */
228+ protected Cookie [] parseCookies (String headerValue ) {
229+ List <Cookie > output = new ArrayList <>();
230+
231+ for (AbstractMap .SimpleEntry <String , String > entry : this .parseHeaderValue (headerValue )) {
232+ if (entry .getKey () != null ) {
233+ output .add (new Cookie (entry .getKey (), entry .getValue ()));
234+ }
235+ }
236+ Cookie [] returnValue = new Cookie [output .size ()];
237+ return output .toArray (returnValue );
238+ }
239+
240+
241+ protected String readPathInfo (String path , String resource ) {
242+ // TODO: Implement
243+ return "/" ;
244+ }
245+
246+
247+ protected String readPathTranslated (String path ) {
248+ // TODO: Implement
249+ return path ;
250+ }
251+
252+
253+ /**
254+ * Given a map of key/values query string parameters from API Gateway, creates a query string as it would have
255+ * been in the original url.
256+ * @param parameters A Map<String, String> of query string parameters
257+ * @return The generated query string for the URI
258+ */
259+ protected String generateQueryString (Map <String , String > parameters ) {
260+ String params = null ;
261+ if (parameters != null && parameters .size () > 0 ) {
262+ params = "" ;
263+ for (String key : parameters .keySet ()) {
264+ String separator = params .equals ("" ) ? "?" : "&" ;
265+ String queryStringKey = key ;
266+ String queryStringValue = parameters .get (key );
267+ try {
268+ // if they were URLDecoded along the way we should re-encode them for the URI
269+ if (!URLEncoder .encode (queryStringKey , StandardCharsets .UTF_8 .name ()).equals (key )) {
270+ queryStringKey = URLEncoder .encode (queryStringKey , StandardCharsets .UTF_8 .name ());
271+ }
272+ if (!URLEncoder .encode (queryStringValue , StandardCharsets .UTF_8 .name ()).equals (queryStringValue )) {
273+ queryStringValue = URLEncoder .encode (queryStringValue , StandardCharsets .UTF_8 .name ());
274+ }
275+ } catch (UnsupportedEncodingException e ) {
276+ // TODO: Should we stop for the exception?
277+ lamdaContext .getLogger ().log ("Could not URLEncode: " + queryStringKey );
278+ e .printStackTrace ();
279+ }
280+ params += separator + queryStringKey + "=" + queryStringValue ;
281+ }
282+ }
283+
284+ return params ;
285+ }
286+
287+
288+ /**
289+ * Generic method to parse an HTTP header value and split it into a list of key/values for all its components.
290+ * When the property in the header does not specify a key the key field in the output pair is null and only the value
291+ * is populated. For example, The header <code>Accept: application/json; application/xml</code> will contain two
292+ * key value pairs with key null and the value set to application/json and application/xml respectively.
293+ *
294+ * @param headerContent The string value for the HTTP header
295+ * @return A list of SimpleMapEntry objects with all of the possible values for the header.
296+ */
297+ protected List <AbstractMap .SimpleEntry <String , String >> parseHeaderValue (String headerContent ) {
298+ List <AbstractMap .SimpleEntry <String , String >> values = new ArrayList <>();
299+ if (headerContent != null ) {
300+ for (String kv : headerContent .split (HEADER_VALUE_SEPARATOR )) {
301+ String [] kvSplit = kv .split (HEADER_KEY_VALUE_SEPARATOR );
302+
303+ if (kvSplit .length != 2 ) {
304+ values .add (new AbstractMap .SimpleEntry <>(null , kv .trim ()));
305+ } else {
306+ values .add (new AbstractMap .SimpleEntry <>(kvSplit [0 ].trim (), kvSplit [1 ].trim ()));
307+ }
308+ }
309+ }
310+ return values ;
311+ }
290312}
0 commit comments