25
25
import java .io .IOException ;
26
26
import java .io .InputStream ;
27
27
import java .io .InputStreamReader ;
28
+ import java .io .OutputStreamWriter ;
28
29
import java .io .PrintStream ;
29
30
import java .io .UnsupportedEncodingException ;
30
31
import java .net .HttpURLConnection ;
@@ -374,15 +375,30 @@ private static URL createUrl(String value) throws MalformedURLException, URISynt
374
375
public ApiResponse callApi (
375
376
String component , String type , String method , Map <String , String > params )
376
377
throws ClientApiException {
377
- Document dom = this .callApiDom (component , type , method , params );
378
+ return callApi (HttpRequest .GET_METHOD , component , type , method , params );
379
+ }
380
+
381
+ public ApiResponse callApi (
382
+ String requestMethod ,
383
+ String component ,
384
+ String type ,
385
+ String method ,
386
+ Map <String , String > params )
387
+ throws ClientApiException {
388
+ Document dom = this .callApiDom (requestMethod , component , type , method , params );
378
389
return ApiResponseFactory .getResponse (dom .getFirstChild ());
379
390
}
380
391
381
392
private Document callApiDom (
382
- String component , String type , String method , Map <String , String > params )
393
+ String requestMethod ,
394
+ String component ,
395
+ String type ,
396
+ String method ,
397
+ Map <String , String > params )
383
398
throws ClientApiException {
384
399
try {
385
- HttpRequest request = buildZapRequest ("xml" , component , type , method , params );
400
+ HttpRequest request =
401
+ buildZapRequest (requestMethod , "xml" , component , type , method , params );
386
402
if (debug ) {
387
403
debugStream .println ("Open URL: " + request .getRequestUri ());
388
404
}
@@ -422,6 +438,17 @@ private InputStream getConnectionInputStream(HttpRequest request) throws IOExcep
422
438
for (Entry <String , String > header : request .getHeaders ().entrySet ()) {
423
439
uc .setRequestProperty (header .getKey (), header .getValue ());
424
440
}
441
+ if (!isGetRequest (request .getMethod ())) {
442
+ uc .setRequestMethod (request .getMethod ());
443
+ String body = request .getBody ();
444
+ if (body != null && !body .isEmpty ()) {
445
+ uc .setDoOutput (true );
446
+ try (var os =
447
+ new OutputStreamWriter (uc .getOutputStream (), StandardCharsets .UTF_8 )) {
448
+ os .write (request .getBody ());
449
+ }
450
+ }
451
+ }
425
452
uc .connect ();
426
453
if (uc .getResponseCode () >= HttpURLConnection .HTTP_BAD_REQUEST ) {
427
454
return uc .getErrorStream ();
@@ -432,8 +459,19 @@ private InputStream getConnectionInputStream(HttpRequest request) throws IOExcep
432
459
public byte [] callApiOther (
433
460
String component , String type , String method , Map <String , String > params )
434
461
throws ClientApiException {
462
+ return callApiOther (HttpRequest .GET_METHOD , component , type , method , params );
463
+ }
464
+
465
+ public byte [] callApiOther (
466
+ String requestMethod ,
467
+ String component ,
468
+ String type ,
469
+ String method ,
470
+ Map <String , String > params )
471
+ throws ClientApiException {
435
472
try {
436
- HttpRequest request = buildZapRequest ("other" , component , type , method , params );
473
+ HttpRequest request =
474
+ buildZapRequest (requestMethod , "other" , component , type , method , params );
437
475
if (debug ) {
438
476
debugStream .println ("Open URL: " + request .getRequestUri ());
439
477
}
@@ -462,6 +500,7 @@ public byte[] callApiOther(
462
500
* <p>As the API client proxies through ZAP the built API requests use a specific domain, {@code
463
501
* zap}, to ensure that they are always handled by ZAP (and not forward).
464
502
*
503
+ * @param requestMethod the HTTP request method.
465
504
* @param format the desired format of the API response (e.g. XML, JSON, other).
466
505
* @param component the API component (e.g. core, spider).
467
506
* @param type the type of the API endpoint (e.g. action, view).
@@ -472,7 +511,12 @@ public byte[] callApiOther(
472
511
* @throws URISyntaxException if an error occurred while building the URL.
473
512
*/
474
513
private HttpRequest buildZapRequest (
475
- String format , String component , String type , String method , Map <String , String > params )
514
+ String requestMethod ,
515
+ String format ,
516
+ String component ,
517
+ String type ,
518
+ String method ,
519
+ Map <String , String > params )
476
520
throws MalformedURLException , URISyntaxException {
477
521
StringBuilder sb = new StringBuilder ();
478
522
sb .append ("http://zap/" );
@@ -484,25 +528,39 @@ private HttpRequest buildZapRequest(
484
528
sb .append ('/' );
485
529
sb .append (method );
486
530
sb .append ('/' );
531
+ String body = null ;
487
532
if (params != null ) {
488
- sb .append ('?' );
489
- for (Map .Entry <String , String > p : params .entrySet ()) {
490
- sb .append (encodeQueryParam (p .getKey ()));
491
- sb .append ('=' );
492
- if (p .getValue () != null ) {
493
- sb .append (encodeQueryParam (p .getValue ()));
494
- }
495
- sb .append ('&' );
533
+ if (isGetRequest (requestMethod )) {
534
+ sb .append ('?' );
535
+ appendParams (params , sb );
536
+ } else {
537
+ body = appendParams (params , new StringBuilder ()).toString ();
496
538
}
497
539
}
498
540
499
- HttpRequest request = new HttpRequest (createUrl (sb .toString ()));
541
+ HttpRequest request = new HttpRequest (requestMethod , createUrl (sb .toString ()), body );
500
542
if (apiKey != null && !apiKey .isEmpty ()) {
501
543
request .addHeader (ZAP_API_KEY_HEADER , apiKey );
502
544
}
503
545
return request ;
504
546
}
505
547
548
+ private static boolean isGetRequest (String requestMethod ) {
549
+ return HttpRequest .GET_METHOD .equals (requestMethod );
550
+ }
551
+
552
+ private static StringBuilder appendParams (Map <String , String > params , StringBuilder sb ) {
553
+ for (Map .Entry <String , String > p : params .entrySet ()) {
554
+ sb .append (encodeQueryParam (p .getKey ()));
555
+ sb .append ('=' );
556
+ if (p .getValue () != null ) {
557
+ sb .append (encodeQueryParam (p .getValue ()));
558
+ }
559
+ sb .append ('&' );
560
+ }
561
+ return sb ;
562
+ }
563
+
506
564
private static String encodeQueryParam (String param ) {
507
565
try {
508
566
return URLEncoder .encode (param , "UTF-8" );
@@ -748,12 +806,22 @@ private static ClientApiException newTimeoutConnectionToZap(int timeoutInSeconds
748
806
*/
749
807
private static class HttpRequest {
750
808
809
+ private static final String GET_METHOD = "GET" ;
810
+
811
+ private final String method ;
751
812
private final URL requestUri ;
752
813
private final Map <String , String > headers ;
814
+ private final String body ;
753
815
754
- public HttpRequest (URL url ) {
816
+ public HttpRequest (String method , URL url , String body ) {
817
+ this .method = method ;
755
818
this .requestUri = url ;
756
819
this .headers = new HashMap <>();
820
+ this .body = body ;
821
+ }
822
+
823
+ public String getMethod () {
824
+ return method ;
757
825
}
758
826
759
827
/**
@@ -786,5 +854,9 @@ public void addHeader(String name, String value) {
786
854
public Map <String , String > getHeaders () {
787
855
return Collections .unmodifiableMap (headers );
788
856
}
857
+
858
+ public String getBody () {
859
+ return body ;
860
+ }
789
861
}
790
862
}
0 commit comments