Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to disable urlencoding get-params in Refit? #277

Closed
dmitrydvm opened this issue Nov 16, 2016 · 9 comments
Closed

How to disable urlencoding get-params in Refit? #277

dmitrydvm opened this issue Nov 16, 2016 · 9 comments

Comments

@dmitrydvm
Copy link

Please help me with my question
http://stackoverflow.com/questions/40632827/how-to-disable-urlencoding-get-params-in-refit

@dmitrydvm
Copy link
Author

@onovotny please help

@ahmedalejo
Copy link

ahmedalejo commented Nov 26, 2016

@onovotny is quite a busy developer in terms of opensource project he actively contributes to (like everyone else),

So navigating to GitHub and then navigating SO isn´t work that someone paid for,
If you can´t go through the work of duplicating you question, then it´s most like nobody sees the issue as important. If you really needed help here you´d take the time to post here and also include a link to SO

Instead of ignoring you, i opted on giving feedback.

Regarding the issue(link), if you don´t mind me taking a shot at it instead of @onovotny 😃 then i suggest:

First of all was your api server able to parse the follow?
api/item?c%5B%5D=14%26c%5B%5D%3D74

Encoding is great for avoiding code injection to your server.

This is something Refit is a bit opinionated about, i.e uris should be encoded, the server should be upgraded to read encoded uris.

But this clearly should be a opt-in settings in Refit but it´s not.

So you can currently do this by using a DelegatingHandler:

	/// <summary>
	/// Makes sure the query string of an <see cref="System.Uri"/>
	/// </summary>
	public class UriQueryUnescapingHandler : DelegatingHandler
	{	
		public UriQueryUnescapingHandler()
			: base(new HttpClientHandler()) { }
		public UriQueryUnescapingHandler(HttpMessageHandler innerHandler)
			: base(innerHandler)
		{ }
	
		protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
		{
			var uri = request.RequestUri;
			//You could also simply unescape the whole uri.OriginalString
			//but i don´t recommend that, i.e only fix what´s broken
			var unescapedQuery = Uri.UnescapeDataString(uri.Query);
			
			var userInfo = string.IsNullOrWhiteSpace(uri.UserInfo) ? "" : $"{uri.UserInfo}@";
			var scheme = string.IsNullOrWhiteSpace(uri.Scheme) ? "" : $"{uri.Scheme}://";
			
			request.RequestUri = new Uri($"{scheme}{userInfo}{uri.Authority}{uri.AbsolutePath}{unescapedQuery}{uri.Fragment}");
			return base.SendAsync(request, cancellationToken);
		}
	}

Then you could use it as follows:

Refit.RestService.For<IYourService>(new HttpClient(new UriQueryUnescapingHandler()))

I recommend posting the question here as well, the suggested answer just don´t make sense without it.

Cheers

@clairernovotny
Copy link
Member

There may be valid reasons for disabling the automatic UrlEncoding, but it's not something that's currently available. If someone wants to try a PR to make it optional by parameter (an additional attribute?), I'd certainly entertain it.

@clairernovotny clairernovotny added this to the v4.0 milestone Nov 27, 2016
@clairernovotny clairernovotny modified the milestones: v4.1, v4.0 Aug 15, 2017
@clairernovotny clairernovotny modified the milestones: v4.1, v4.2 Jan 14, 2018
@clairernovotny clairernovotny removed this from the v4.2 milestone Jan 29, 2018
@Deilan
Copy link

Deilan commented Aug 29, 2018

This is a must-have one. :)

@Cheesebaron
Copy link
Contributor

@Deilan go ahead and make a PR for it. It is marked up for grabs ;)

@pieteckhart
Copy link

I'm trying to use Refit to download a file from a dynamic (but relative to the base) url.

[Get("/{**url}")]
Task GetDocument(string url);
The url argument itself also contains a querystring. (for example GetDocument(url: "download.php?filename=somefile.pdf");

I notice my url argument gets encoded so I get an 404 error.

Will this be possible after @deesejohn 's pullrequest gets merged?

@ahmedalejo
Copy link

ahmedalejo commented Dec 16, 2019

@pieteckhart you should write the following instead:

[Get("/download")]
Task<Stream> GetDocument(string filename);

calling the following

[Get("/download")]
var filestream = await client.GetDocument(filename: "somefile.pdf");

would result in

HTTP GET /download?filename=somefile.pdf

hope it makes sense to you. If it doesn´t, please comment on, or let wait for @deesejohn 😊

@pieteckhart
Copy link

Thanks for the suggestion, but the thing is that the download url is provided to me as is by another API call. I have no influence on the API so I was looking for a way to just blindly use the url without taking it apart and construct a proper request. For now I've hand rolled a request using the same httpClient so that it has access to a session cookie.

@deesejohn
Copy link

I actually closed that PR because I wasn't very happy with the implementation. I've since migrated my project to RestEase as it was already able to satisfy my requirements.

@benjaminhowarth1 I'm actually unable to reply to you on the PR directly, now that is has been locked, but it was never merged. If you and/or others feel the implementation is satisfactory, please feel free to merge it.

@jamiehowarth0 jamiehowarth0 self-assigned this Jan 11, 2020
jamiehowarth0 added a commit that referenced this issue Jan 11, 2020
@lock lock bot added the outdated label Apr 15, 2020
@lock lock bot locked and limited conversation to collaborators Apr 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants