1010import io .scalecube .services .exceptions .ForbiddenException ;
1111import io .scalecube .services .methods .MethodInfo ;
1212import java .util .Collections ;
13+ import java .util .HashMap ;
1314import java .util .Map ;
1415import java .util .Map .Entry ;
1516import java .util .Objects ;
@@ -100,17 +101,40 @@ public Context delete(Object key) {
100101 /**
101102 * Returns request headers.
102103 *
103- * @return headers, or {@code null} if not set
104+ * @return headers, or empty map if not set
104105 */
105106 public Map <String , String > headers () {
106107 return source .getOrDefault (HEADERS_KEY , Collections .emptyMap ());
107108 }
108109
110+ /**
111+ * Returns typed access to all request headers.
112+ *
113+ * @return typed parameters for headers
114+ */
115+ public TypedParameters headerParams () {
116+ return new TypedParameters (headers ());
117+ }
118+
119+ /**
120+ * Returns typed access to request headers filtered by the given prefix. Headers matching
121+ * "{prefix}." are included with the prefix stripped from the key.
122+ *
123+ * @param prefix header prefix to filter by (if null or empty, returns all headers)
124+ * @return typed parameters for filtered headers
125+ */
126+ public TypedParameters headerParams (String prefix ) {
127+ if (prefix == null || prefix .isEmpty ()) {
128+ return headerParams ();
129+ }
130+ return new TypedParameters (filterByPrefix (headers (), prefix ));
131+ }
132+
109133 /**
110134 * Puts request headers to the context.
111135 *
112136 * @param headers headers
113- * @return new {@code RequestContext} instance with updated headers
137+ * @return new {@code RequestContext}
114138 */
115139 public RequestContext headers (Map <String , String > headers ) {
116140 return put (HEADERS_KEY , headers );
@@ -129,7 +153,7 @@ public Object request() {
129153 * Puts request to the context.
130154 *
131155 * @param request request
132- * @return new {@code RequestContext} instance with updated request
156+ * @return new {@code RequestContext}
133157 */
134158 public RequestContext request (Object request ) {
135159 return put (REQUEST_KEY , request );
@@ -185,7 +209,7 @@ public Principal principal() {
185209 * Puts principal to the context.
186210 *
187211 * @param principal principal
188- * @return new {@code RequestContext} instance with the updated principal
212+ * @return new {@code RequestContext}
189213 */
190214 public RequestContext principal (Principal principal ) {
191215 return put (PRINCIPAL_KEY , principal );
@@ -224,7 +248,7 @@ public RequestContext methodInfo(MethodInfo methodInfo) {
224248 /**
225249 * Returns path parameters associated with the request.
226250 *
227- * @return path parameters, or {@code null} if not set
251+ * @return path parameters, or empty map if not set
228252 */
229253 public TypedParameters pathParams () {
230254 return new TypedParameters (source .getOrDefault (PATH_PARAMS_KEY , Collections .emptyMap ()));
@@ -233,7 +257,7 @@ public TypedParameters pathParams() {
233257 /**
234258 * Puts path parameters associated with the request.
235259 *
236- * @return path parameters, or {@code null} if not set
260+ * @return new {@code RequestContext}
237261 */
238262 public RequestContext pathParams (Map <String , String > pathParams ) {
239263 return put (PATH_PARAMS_KEY , pathParams );
@@ -310,6 +334,21 @@ public static Mono<RequestContext> deferSecured() {
310334 });
311335 }
312336
337+ private static Map <String , String > filterByPrefix (Map <String , String > map , String prefix ) {
338+ if (map == null || map .isEmpty ()) {
339+ return Map .of ();
340+ }
341+ final var finalPrefix = prefix + "." ;
342+ final var result = new HashMap <String , String >();
343+ map .forEach (
344+ (k , v ) -> {
345+ if (k .startsWith (finalPrefix )) {
346+ result .put (k .substring (finalPrefix .length ()), v );
347+ }
348+ });
349+ return result ;
350+ }
351+
313352 @ Override
314353 public String toString () {
315354 return new StringJoiner (", " , RequestContext .class .getSimpleName () + "[" , "]" )
0 commit comments