@@ -21,7 +21,9 @@ import (
21
21
"fmt"
22
22
"math"
23
23
"net/http"
24
+ "net/url"
24
25
"strconv"
26
+ "strings"
25
27
"time"
26
28
"unsafe"
27
29
@@ -515,7 +517,7 @@ func (qr *queryResult) UnmarshalJSON(b []byte) error {
515
517
//
516
518
// It is safe to use the returned API from multiple goroutines.
517
519
func NewAPI (c api.Client ) API {
518
- return & httpAPI {client : apiClient { c } }
520
+ return & httpAPI {client : c }
519
521
}
520
522
521
523
type httpAPI struct {
@@ -530,7 +532,7 @@ func (h *httpAPI) Alerts(ctx context.Context) (AlertsResult, error) {
530
532
return AlertsResult {}, err
531
533
}
532
534
533
- _ , body , _ , err := h .client . Do (ctx , req )
535
+ _ , body , _ , err := h .Do (ctx , req )
534
536
if err != nil {
535
537
return AlertsResult {}, err
536
538
}
@@ -547,7 +549,7 @@ func (h *httpAPI) AlertManagers(ctx context.Context) (AlertManagersResult, error
547
549
return AlertManagersResult {}, err
548
550
}
549
551
550
- _ , body , _ , err := h .client . Do (ctx , req )
552
+ _ , body , _ , err := h .Do (ctx , req )
551
553
if err != nil {
552
554
return AlertManagersResult {}, err
553
555
}
@@ -564,7 +566,7 @@ func (h *httpAPI) CleanTombstones(ctx context.Context) error {
564
566
return err
565
567
}
566
568
567
- _ , _ , _ , err = h .client . Do (ctx , req )
569
+ _ , _ , _ , err = h .Do (ctx , req )
568
570
return err
569
571
}
570
572
@@ -576,7 +578,7 @@ func (h *httpAPI) Config(ctx context.Context) (ConfigResult, error) {
576
578
return ConfigResult {}, err
577
579
}
578
580
579
- _ , body , _ , err := h .client . Do (ctx , req )
581
+ _ , body , _ , err := h .Do (ctx , req )
580
582
if err != nil {
581
583
return ConfigResult {}, err
582
584
}
@@ -603,7 +605,7 @@ func (h *httpAPI) DeleteSeries(ctx context.Context, matches []string, startTime
603
605
return err
604
606
}
605
607
606
- _ , _ , _ , err = h .client . Do (ctx , req )
608
+ _ , _ , _ , err = h .Do (ctx , req )
607
609
return err
608
610
}
609
611
@@ -615,7 +617,7 @@ func (h *httpAPI) Flags(ctx context.Context) (FlagsResult, error) {
615
617
return FlagsResult {}, err
616
618
}
617
619
618
- _ , body , _ , err := h .client . Do (ctx , req )
620
+ _ , body , _ , err := h .Do (ctx , req )
619
621
if err != nil {
620
622
return FlagsResult {}, err
621
623
}
@@ -630,7 +632,7 @@ func (h *httpAPI) LabelNames(ctx context.Context) ([]string, api.Warnings, error
630
632
if err != nil {
631
633
return nil , nil , err
632
634
}
633
- _ , body , w , err := h .client . Do (ctx , req )
635
+ _ , body , w , err := h .Do (ctx , req )
634
636
if err != nil {
635
637
return nil , w , err
636
638
}
@@ -644,7 +646,7 @@ func (h *httpAPI) LabelValues(ctx context.Context, label string) (model.LabelVal
644
646
if err != nil {
645
647
return nil , nil , err
646
648
}
647
- _ , body , w , err := h .client . Do (ctx , req )
649
+ _ , body , w , err := h .Do (ctx , req )
648
650
if err != nil {
649
651
return nil , w , err
650
652
}
@@ -661,7 +663,7 @@ func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time) (model.
661
663
q .Set ("time" , formatTime (ts ))
662
664
}
663
665
664
- _ , body , warnings , err := api .DoGetFallback (h . client , ctx , u , q )
666
+ _ , body , warnings , err := h .DoGetFallback (ctx , u , q )
665
667
if err != nil {
666
668
return nil , warnings , err
667
669
}
@@ -679,7 +681,7 @@ func (h *httpAPI) QueryRange(ctx context.Context, query string, r Range) (model.
679
681
q .Set ("end" , formatTime (r .End ))
680
682
q .Set ("step" , strconv .FormatFloat (r .Step .Seconds (), 'f' , - 1 , 64 ))
681
683
682
- _ , body , warnings , err := api .DoGetFallback (h . client , ctx , u , q )
684
+ _ , body , warnings , err := h .DoGetFallback (ctx , u , q )
683
685
if err != nil {
684
686
return nil , warnings , err
685
687
}
@@ -707,7 +709,7 @@ func (h *httpAPI) Series(ctx context.Context, matches []string, startTime time.T
707
709
return nil , nil , err
708
710
}
709
711
710
- _ , body , warnings , err := h .client . Do (ctx , req )
712
+ _ , body , warnings , err := h .Do (ctx , req )
711
713
if err != nil {
712
714
return nil , warnings , err
713
715
}
@@ -729,7 +731,7 @@ func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult,
729
731
return SnapshotResult {}, err
730
732
}
731
733
732
- _ , body , _ , err := h .client . Do (ctx , req )
734
+ _ , body , _ , err := h .Do (ctx , req )
733
735
if err != nil {
734
736
return SnapshotResult {}, err
735
737
}
@@ -746,7 +748,7 @@ func (h *httpAPI) Rules(ctx context.Context) (RulesResult, error) {
746
748
return RulesResult {}, err
747
749
}
748
750
749
- _ , body , _ , err := h .client . Do (ctx , req )
751
+ _ , body , _ , err := h .Do (ctx , req )
750
752
if err != nil {
751
753
return RulesResult {}, err
752
754
}
@@ -763,7 +765,7 @@ func (h *httpAPI) Targets(ctx context.Context) (TargetsResult, error) {
763
765
return TargetsResult {}, err
764
766
}
765
767
766
- _ , body , _ , err := h .client . Do (ctx , req )
768
+ _ , body , _ , err := h .Do (ctx , req )
767
769
if err != nil {
768
770
return TargetsResult {}, err
769
771
}
@@ -787,7 +789,7 @@ func (h *httpAPI) TargetsMetadata(ctx context.Context, matchTarget string, metri
787
789
return nil , err
788
790
}
789
791
790
- _ , body , _ , err := h .client . Do (ctx , req )
792
+ _ , body , _ , err := h .Do (ctx , req )
791
793
if err != nil {
792
794
return nil , err
793
795
}
@@ -796,12 +798,6 @@ func (h *httpAPI) TargetsMetadata(ctx context.Context, matchTarget string, metri
796
798
return res , json .Unmarshal (body , & res )
797
799
}
798
800
799
- // apiClient wraps a regular client and processes successful API responses.
800
- // Successful also includes responses that errored at the API level.
801
- type apiClient struct {
802
- api.Client
803
- }
804
-
805
801
type apiResponse struct {
806
802
Status string `json:"status"`
807
803
Data json.RawMessage `json:"data"`
@@ -825,8 +821,8 @@ func errorTypeAndMsgFor(resp *http.Response) (ErrorType, string) {
825
821
return ErrBadResponse , fmt .Sprintf ("bad response code %d" , resp .StatusCode )
826
822
}
827
823
828
- func (c apiClient ) Do (ctx context.Context , req * http.Request ) (* http.Response , []byte , api.Warnings , error ) {
829
- resp , body , warnings , err := c . Client .Do (ctx , req )
824
+ func (h * httpAPI ) Do (ctx context.Context , req * http.Request ) (* http.Response , []byte , api.Warnings , error ) {
825
+ resp , body , warnings , err := h .Do (ctx , req )
830
826
if err != nil {
831
827
return resp , body , warnings , err
832
828
}
@@ -871,6 +867,31 @@ func (c apiClient) Do(ctx context.Context, req *http.Request) (*http.Response, [
871
867
872
868
}
873
869
870
+ // DoGetFallback will attempt to do the request as-is, and on a 405 it will fallback to a GET request.
871
+ func (h * httpAPI ) DoGetFallback (ctx context.Context , u * url.URL , args url.Values ) (* http.Response , []byte , api.Warnings , error ) {
872
+ req , err := http .NewRequest (http .MethodPost , u .String (), strings .NewReader (args .Encode ()))
873
+ if err != nil {
874
+ return nil , nil , nil , err
875
+ }
876
+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
877
+
878
+ resp , body , warnings , err := h .Do (ctx , req )
879
+ if resp != nil && resp .StatusCode == http .StatusMethodNotAllowed {
880
+ u .RawQuery = args .Encode ()
881
+ req , err = http .NewRequest (http .MethodGet , u .String (), nil )
882
+ if err != nil {
883
+ return nil , nil , warnings , err
884
+ }
885
+
886
+ } else {
887
+ if err != nil {
888
+ return resp , body , warnings , err
889
+ }
890
+ return resp , body , warnings , nil
891
+ }
892
+ return h .Do (ctx , req )
893
+ }
894
+
874
895
func formatTime (t time.Time ) string {
875
896
return strconv .FormatFloat (float64 (t .Unix ())+ float64 (t .Nanosecond ())/ 1e9 , 'f' , - 1 , 64 )
876
897
}
0 commit comments