feat: add HTTP interceptor support#1101
feat: add HTTP interceptor support#1101dballance wants to merge 2 commits intomapbox:public/dballance-add-http-interceptor-supportfrom
Conversation
|
@mapbox/mapbox-maps-flutter - @evil159 - Any thoughts here? |
|
Hi @dballance -- Thanks for the PR! We'll take a look early next week. 😀 |
|
Great - thanks - happy to rework or extend if needed! |
# Conflicts: # CHANGELOG.md # ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/MapboxMapController.swift # lib/src/mapbox_map.dart
4015162 to
2849f76
Compare
|
Hi @dballance -- A few things came up earlier this week, but this is first on my to do list tomorrow. |
|
Thanks again for the contribution @dballance! The Dart-side API design looks good: MapboxMapsOptions as the entry point,
This is the biggest issue. Both platforms use the same pattern: block the calling thread with a semaphore/latch, post to the main thread to invoke Flutter, and wait for the response. The problem is that
The PR adds
Sending the full response body to Flutter on every intercepted response is a concern. Tile bodies are regularly 200–500 KB and during initial map load you can have dozens of these completing at once. Serializing them through the platform channel just for logging purposes may cause memory spikes and slow down map initialization noticeably. The response interceptor should omit data by default, with an explicit opt-in if body inspection is genuinely needed.
CustomHttpServiceInterceptor is a singleton whose mutable fields (customHeaders, flutterChannel, interceptRequests, interceptResponses) are written from the Flutter main thread and read from the HTTP network thread with no synchronization. I think a lock is needed here.
The deadlock won't show up in a simple unit test because you need the main thread to be the caller, but an integration test that creates a MapWidget with an interceptor already set should catch it. The response body performance issue also needs a test or at least a benchmark, since it's the kind of thing that looks fine in isolation but could degrade at scale. |
|
Thanks @pjleonard37! I mostly got this done, I think. Just ran all the integration tests locally and the sample app runs as well. I'm curious about testing for response body - what kind of benchmark were you thinking? I added some tests but unsure it covers what you're thinking about. |
| Future<void> setSnapshotLegacyMode(bool enable) => | ||
| _mapInterface.setSnapshotLegacyMode(enable); | ||
|
|
||
| /// Set custom headers for all Mapbox HTTP requests |
There was a problem hiding this comment.
This probably needs to stay to make this change non-breaking, but potentially calling over to the MapboxMapOptions controller.
What does this pull request do?
Adds HTTP interceptor support, in Dart, to match up to the native SDK functionality.
The interceptors are added before a map is instantiated, so that all requests (including fonts, images, etc) can be modified / logged / observed when the map is created. All map instances will share the same interceptor, much like the existing SDK functionality.
I'm opening this first to get feedback on the overall approach - will add tests if needed. Seems most of the native code is only tested indirectly, so would potentially just be an integration test of some sort.
What is the motivation and context behind this change?
Allow per request header modifications, logging, and tracing spans on map requests. Would potentially close #1062 and other stories.
Pull request checklist:
PRs must be submitted under the terms of our Contributor License Agreement CLA.