Skip to content

Commit

Permalink
use %20 instead of spaces when encoding URL params (#844)
Browse files Browse the repository at this point in the history
  • Loading branch information
josiahg authored May 16, 2024
1 parent 6a56bd2 commit 55c5709
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/odd-melons-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'grafana-infinity-datasource': minor
---

Add support for encoding space characters in URLs with '%20' instead of '+'
7 changes: 6 additions & 1 deletion pkg/infinity/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ func GetQueryURL(ctx context.Context, settings models.InfinitySettings, query mo
}
q.Set(settings.ApiKeyKey, val)
}
u.RawQuery = q.Encode()
if settings.PathEncodedURLsEnabled {
customEncoder := strings.NewReplacer("+", "%20")
u.RawQuery = customEncoder.Replace(q.Encode())
} else {
u.RawQuery = q.Encode()
}
return NormalizeURL(u.String()), nil
}

Expand Down
34 changes: 34 additions & 0 deletions pkg/infinity/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,40 @@ func Test_getQueryURL(t *testing.T) {
excludeSecret: true,
want: "https://foo.com/xxxxxxxx/hello?foo=bar&hello=xxxxxxxx&key=val&key_one=xxxxxxxx&key_three=xxxxxxxx&key_two=xxxxxxxx&mee=too",
},
{
name: "should use %20 instead of ' ' for all the query parameters",
settings: models.InfinitySettings{
URL: "https://foo.com",
PathEncodedURLsEnabled: true,
},
query: models.Query{
URL: "/hello?key=val10&foo=bar",
URLOptions: models.URLOptions{
Params: []models.URLOptionKeyValuePair{
{Key: "key", Value: "val11 val12"},
{Key: "key2", Value: "value2 value3"},
},
},
},
want: "https://foo.com/hello?foo=bar&key=val10&key=val11%20val12&key2=value2%20value3",
},
{
name: "do not overwrite + that isn't a space in query parameters",
settings: models.InfinitySettings{
URL: "https://foo.com",
PathEncodedURLsEnabled: true,
},
query: models.Query{
URL: "/hello?key=val10&foo=bar",
URLOptions: models.URLOptions{
Params: []models.URLOptionKeyValuePair{
{Key: "key", Value: "val11 val+12"},
{Key: "key2", Value: "value2+value3"},
},
},
},
want: "https://foo.com/hello?foo=bar&key=val10&key=val11%20val%2B12&key2=value2%2Bvalue3",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/models/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ type InfinitySettings struct {
AzureBlobAccountName string
AzureBlobAccountKey string
UnsecuredQueryHandling UnsecuredQueryHandlingMode
PathEncodedURLsEnabled bool
// ProxyOpts is used for Secure Socks Proxy configuration
ProxyOpts httpclient.Options
}
Expand Down Expand Up @@ -198,6 +199,7 @@ type InfinitySettingsJson struct {
CustomHealthCheckUrl string `json:"customHealthCheckUrl,omitempty"`
AzureBlobAccountUrl string `json:"azureBlobAccountUrl,omitempty"`
AzureBlobAccountName string `json:"azureBlobAccountName,omitempty"`
PathEncodedURLsEnabled bool `json:"pathEncodedUrlsEnabled,omitempty"`
// Security
AllowedHosts []string `json:"allowedHosts,omitempty"`
UnsecuredQueryHandling UnsecuredQueryHandlingMode `json:"unsecuredQueryHandling,omitempty"`
Expand Down Expand Up @@ -240,6 +242,7 @@ func LoadSettings(ctx context.Context, config backend.DataSourceInstanceSettings
settings.TimeoutInSeconds = 60
settings.ProxyType = infJson.ProxyType
settings.ProxyUrl = infJson.ProxyUrl
settings.PathEncodedURLsEnabled = infJson.PathEncodedURLsEnabled
if settings.ProxyType == "" {
settings.ProxyType = ProxyTypeEnv
}
Expand Down
4 changes: 4 additions & 0 deletions src/editors/config.editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ReferenceDataEditor } from './config/ReferenceData';
import { CustomHealthCheckEditor } from './config/CustomHealthCheckEditor';
import type { DataSourcePluginOptionsEditorProps } from '@grafana/data';
import type { InfinityOptions } from './../types';
import { QueryParamEditor } from './config/QueryParamEditor';

const Collapse = CollapseOriginal as any;

Expand Down Expand Up @@ -79,6 +80,9 @@ export const HeadersEditor = (props: DataSourcePluginOptionsEditorProps<Infinity
<Collapse isOpen={true} collapsible={true} label="URL Query Param">
<SecureFieldsEditor dataSourceConfig={options} onChange={onOptionsChange} title="URL Query Param" secureFieldName="secureQueryName" secureFieldValue="secureQueryValue" hideTile={true} />
</Collapse>
<Collapse isOpen={true} collapsible={true} label="Query Param Encoding (EXPERIMENTAL)">
<QueryParamEditor options={options} onOptionsChange={onOptionsChange}/>
</Collapse>
</>
);
};
Expand Down
20 changes: 20 additions & 0 deletions src/editors/config/QueryParamEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { InlineLabel, InlineSwitch } from '@grafana/ui';
import type { DataSourcePluginOptionsEditorProps } from '@grafana/data';
import type { InfinityOptions } from '../../types';

export const QueryParamEditor = (props: DataSourcePluginOptionsEditorProps<InfinityOptions>) => {
const { options, onOptionsChange } = props;
const { jsonData = {} } = options;
return (
<>
<div className="gf-form">
<InlineLabel width={36}>Encode query parameters with %20</InlineLabel>
<InlineSwitch
value={jsonData.pathEncodedUrlsEnabled || false}
onChange={(e) => onOptionsChange({ ...options, jsonData: { ...jsonData, pathEncodedUrlsEnabled: e.currentTarget.checked } })}
/>
</div>
</>
);
};
1 change: 1 addition & 0 deletions src/types/config.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export interface InfinityOptions extends DataSourceJsonData {
azureBlobAccountName?: string;
unsecuredQueryHandling?: UnsecureQueryHandling;
enableSecureSocksProxy?: boolean;
pathEncodedUrlsEnabled?: boolean;
}

export interface InfinitySecureOptions {
Expand Down

0 comments on commit 55c5709

Please sign in to comment.