CodingAleCR / http_interceptor

A lightweight, simple plugin that allows you to intercept request and response objects and modify them if desired.
MIT License
133 stars 67 forks source link

Implement interception for `send` and MultipartRequests #94

Closed lukaskurz closed 2 years ago

lukaskurz commented 2 years ago

Hi there :wave:

I recently started using your package, since I was missing some decent standalone http interceptors for flutter and your package fits the description neatly.

Problem

I stumbled upon the issue of unauthenticated file upload requests (I use an interceptor for auth headers) and learned that the send method has no implemented interception. Since the job and code did not seem to difficult, I tried to implement those.

What was done

Firstly, i changed the _sendUnstreamed method to not use the send method directly (which just calls _inner.send anyways), but rather make a call to _inner.send

Since send returns StreamedResponse I duplicated and changed parts of the interception logic to handle StreamedResponse instead of normal Response .

I added a StreamedResponseData class, which can be "converted" to a normal ResponseData, just without a body/bodyBytes (since that would not make sense in the case of a streamed body). I did this, so we can still handle a StreamedResponse like a normal one, modifying headers and all that, but dont have access to the body.

In case someone wants to modify or access the streamed body, I extended the InterceptorContract to include a interceptStreamedResponse method. I took some architectural liberties here and this could probably be implemented differently, by making a subclassed StreamedInterceptorContract for example.

Then I also had to make some changes to the RequestData class, in order to support Multipart request. I did this, by simply rearranging some ifs. The fields and files are put into a MultipartBody object, that is put into the body.

CodingAleCR commented 2 years ago

Thank you so much for this PR, I'll be checking this and probably merging soon so that we can release this. This has been a feature users have requested for quite some time now so I really appreciate you taking your time to contribute 👏🏼

lukaskurz commented 2 years ago

@CodingAleCR Hi, I have been using the version on my repository for some time now, and I now I needed the StreamedRequest to work too (for a file upload progress). So I had another go at this task, and implemented it differently, now supporting all types of http request. I had to make a change to the contracts, eliminating the RequestData and ResponseData and replacing them with BaseResponse and BaseRequest. This way you have to either verify the specific type of request or (if you're sure) cast it. I don't really see any functionality in the wrapper classes, that is not also provided by the original request classes. I also added copyWith extensions for all the different request and response types, to make it easier to manipulate them.

If/When you plan to review this PR, I would recommend checking out the different version here, since I think this is the better approach and is also cleaner. Its also easier to expand for new Request types coming from the http packages. This is however a breaking change, (this PR is probably also a breaking change) so this would require a change in major version. Please let me know, if you want me to send a PR for that version, instead of the current one.

Cheers.

CodingAleCR commented 2 years ago

Hey, it'd be great if you update the PR or just create a new one with the refactor, I've been tempted to refactor in a way of what you did but in the end desisted. I'm interested to see how requests behave as I've had problems intercepting in the past (waaaay in the past) due to ongoing requests not being mutable and stuff, but it seems your approach might work.

Thanks for all your contributions!

CodingAleCR commented 2 years ago

Hi, I'm closing this since we took the extensions approach. Thank you for all the hard work you have put into this @lukaskurz ! I have added your contributions to the README.