2929import java .util .*;
3030import java .util .regex .Matcher ;
3131import java .util .regex .Pattern ;
32+ import java .util .stream .Collectors ;
3233
3334public class HttpDriver implements Driver {
3435
@@ -42,6 +43,7 @@ public class HttpDriver implements Driver {
4243 private Pattern pattern = null ;
4344 private URI resolveUri = null ;
4445 private URI propertiesUri = null ;
46+ private boolean supportsOptions = false ;
4547 private boolean supportsDereference = false ;
4648 private String acceptHeaderValue = null ;
4749 private List <String > testIdentifiers = Collections .emptyList ();
@@ -92,18 +94,27 @@ public ResolveResult resolve(DID did, Map<String, Object> resolutionOptions) thr
9294
9395 // set HTTP URI
9496
95- String uriString = this .getResolveUri ().toString ();
97+ StringBuilder uriString = new StringBuilder ( this .getResolveUri ().toString () );
9698
97- if (uriString .contains ("$1" )) {
99+ if (uriString .toString (). contains ("$1" )) {
98100
99- uriString = uriString .replace ("$1" , matchedString .toString ());
100- } else if (uriString .contains ("$2" )) {
101+ uriString = new StringBuilder ( uriString .toString (). replace ("$1" , matchedString .toString () ));
102+ } else if (uriString .toString (). contains ("$2" )) {
101103
102- uriString = uriString .replace ("$2" , URLEncoder .encode (matchedString .toString (), StandardCharsets .UTF_8 ));
104+ uriString = new StringBuilder ( uriString .toString (). replace ("$2" , URLEncoder .encode (matchedString .toString (), StandardCharsets .UTF_8 ) ));
103105 } else {
104106
105- if (! uriString .endsWith ("/" )) uriString += "/" ;
106- uriString += matchedString ;
107+ if (! uriString .toString ().endsWith ("/" )) uriString .append ("/" );
108+ if (this .getSupportsOptions () && ! optionsForHttpUriQuery (resolutionOptions ).isEmpty ()) {
109+ uriString .append (URLEncoder .encode (matchedString .toString (), StandardCharsets .UTF_8 ));
110+ uriString .append ("?" );
111+ for (Map .Entry <String , Object > entry : optionsForHttpUriQuery (resolutionOptions ).entrySet ()) {
112+ uriString .append (entry .getKey ()).append ("=" ).append (entry .getValue ()).append ("&" );
113+ }
114+ if (uriString .lastIndexOf ("&" ) == uriString .length () - 1 ) uriString .deleteCharAt (uriString .length () - 1 );
115+ } else {
116+ uriString .append (matchedString );
117+ }
107118 }
108119
109120 // set Accept header
@@ -119,7 +130,7 @@ public ResolveResult resolve(DID did, Map<String, Object> resolutionOptions) thr
119130
120131 // prepare HTTP request
121132
122- HttpGet httpGet = new HttpGet (URI .create (uriString ));
133+ HttpGet httpGet = new HttpGet (URI .create (uriString . toString () ));
123134 httpGet .addHeader ("Accept" , acceptMediaTypesString );
124135
125136 // execute HTTP request and read response
@@ -199,13 +210,13 @@ public DereferenceResult dereference(DIDURL didUrl, Map<String, Object> derefere
199210
200211 if (this .getPattern () != null ) {
201212
202- Matcher matcher = this .getPattern ().matcher (didUrl .getDid (). getDidString ());
213+ Matcher matcher = this .getPattern ().matcher (didUrl .getDidUrlString ());
203214
204215 if (! matcher .matches ()) {
205- if (log .isDebugEnabled ()) log .debug ("Skipping identifier " + didUrl . getDid () + " - does not match pattern " + this .getPattern ());
216+ if (log .isDebugEnabled ()) log .debug ("Skipping identifier " + didUrl + " - does not match pattern " + this .getPattern ());
206217 return null ;
207218 } else {
208- if (log .isDebugEnabled ()) log .debug ("Identifier " + didUrl . getDid () + " matches pattern " + this .getPattern () + " with " + matcher .groupCount () + " groups" );
219+ if (log .isDebugEnabled ()) log .debug ("Identifier " + didUrl + " matches pattern " + this .getPattern () + " with " + matcher .groupCount () + " groups" );
209220 }
210221
211222 if (matcher .groupCount () > 0 ) {
@@ -215,23 +226,32 @@ public DereferenceResult dereference(DIDURL didUrl, Map<String, Object> derefere
215226 }
216227 }
217228
218- if (matchedString == null ) matchedString = new StringBuilder (didUrl .getDid (). getDidString ());
229+ if (matchedString == null ) matchedString = new StringBuilder (didUrl .getDidUrlString ());
219230 if (log .isDebugEnabled ()) log .debug ("Matched string: " + matchedString );
220231
221232 // set HTTP URI
222233
223- String uriString = this .getResolveUri ().toString ();
234+ StringBuilder uriString = new StringBuilder ( this .getResolveUri ().toString () );
224235
225- if (uriString .contains ("$1" )) {
236+ if (uriString .toString (). contains ("$1" )) {
226237
227- uriString = uriString .replace ("$1" , didUrl . toString ( ));
228- } else if (uriString .contains ("$2" )) {
238+ uriString = new StringBuilder ( uriString .toString (). replace ("$1" , matchedString ));
239+ } else if (uriString .toString (). contains ("$2" )) {
229240
230- uriString = uriString .replace ("$2" , URLEncoder .encode (didUrl .toString (), StandardCharsets .UTF_8 ));
241+ uriString = new StringBuilder ( uriString .toString (). replace ("$2" , URLEncoder .encode (matchedString .toString (), StandardCharsets .UTF_8 ) ));
231242 } else {
232243
233- if (! uriString .endsWith ("/" )) uriString += "/" ;
234- uriString += didUrl .toString ();
244+ if (! uriString .toString ().endsWith ("/" )) uriString .append ("/" );
245+ if (this .getSupportsOptions () && ! optionsForHttpUriQuery (dereferenceOptions ).isEmpty ()) {
246+ uriString .append (URLEncoder .encode (matchedString .toString (), StandardCharsets .UTF_8 ));
247+ uriString .append ("?" );
248+ for (Map .Entry <String , Object > entry : optionsForHttpUriQuery (dereferenceOptions ).entrySet ()) {
249+ uriString .append (entry .getKey ()).append ("=" ).append (entry .getValue ()).append ("&" );
250+ }
251+ if (uriString .lastIndexOf ("&" ) == uriString .length () - 1 ) uriString .deleteCharAt (uriString .length () - 1 );
252+ } else {
253+ uriString .append (matchedString );
254+ }
235255 }
236256
237257 // set Accept header
@@ -246,7 +266,7 @@ public DereferenceResult dereference(DIDURL didUrl, Map<String, Object> derefere
246266
247267 // prepare HTTP request
248268
249- HttpGet httpGet = new HttpGet (URI .create (uriString ));
269+ HttpGet httpGet = new HttpGet (URI .create (uriString . toString () ));
250270 httpGet .addHeader ("Accept" , acceptMediaTypesString );
251271
252272 // execute HTTP request and read response
@@ -411,6 +431,19 @@ public Map<String, Object> traits() {
411431 return this .getTraits ();
412432 }
413433
434+ /*
435+ * Helper methods
436+ */
437+
438+ private static Map <String , Object > optionsForHttpUriQuery (Map <String , Object > options ) {
439+ return options
440+ .entrySet ()
441+ .stream ()
442+ .filter (x -> ! "accept" .equals (x .getKey ()))
443+ .filter (x -> ! x .getKey ().startsWith ("_" ))
444+ .collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue ));
445+ }
446+
414447 /*
415448 * Getters and setters
416449 */
@@ -459,6 +492,14 @@ public void setPropertiesUri(String propertiesUri) {
459492 this .propertiesUri = URI .create (propertiesUri );
460493 }
461494
495+ public boolean getSupportsOptions () {
496+ return this .supportsOptions ;
497+ }
498+
499+ public void setSupportsOptions (boolean supportsOptions ) {
500+ this .supportsOptions = supportsOptions ;
501+ }
502+
462503 public boolean getSupportsDereference () {
463504 return this .supportsDereference ;
464505 }
0 commit comments