spatialdds 0.5.3__tar.gz → 0.5.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. {spatialdds-0.5.3 → spatialdds-0.5.4}/PKG-INFO +21 -3
  2. {spatialdds-0.5.3 → spatialdds-0.5.4}/README.md +20 -2
  3. {spatialdds-0.5.3 → spatialdds-0.5.4}/pyproject.toml +1 -1
  4. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/__init__.py +1 -1
  5. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/gw_http.py +44 -1
  6. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds.egg-info/PKG-INFO +21 -3
  7. {spatialdds-0.5.3 → spatialdds-0.5.4}/setup.cfg +0 -0
  8. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/idl/core.idl +0 -0
  9. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/idl/discovery.idl +0 -0
  10. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/idl/types.idl +0 -0
  11. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/builtin_Time.json +0 -0
  12. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_anchors_AnchorDelta.json +0 -0
  13. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_anchors_AnchorEntry.json +0 -0
  14. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSet.json +0 -0
  15. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetRequest.json +0 -0
  16. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_anchors_AnchorSetResponse.json +0 -0
  17. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_argeo_NodeGeo.json +0 -0
  18. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_argeo_QualityRequirements.json +0 -0
  19. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_argeo_VpsRequest.json +0 -0
  20. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_argeo_VpsResponse.json +0 -0
  21. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_common_AssetRef.json +0 -0
  22. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_common_FrameRef.json +0 -0
  23. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_common_KV.json +0 -0
  24. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_common_MetaKV.json +0 -0
  25. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_common_Vec2.json +0 -0
  26. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_Aabb3.json +0 -0
  27. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_BlobChunk.json +0 -0
  28. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_BlobRef.json +0 -0
  29. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_ComponentRef.json +0 -0
  30. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_Edge.json +0 -0
  31. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_EntityBinding.json +0 -0
  32. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_FrameTransform.json +0 -0
  33. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_FramedPose.json +0 -0
  34. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_GeoAnchor.json +0 -0
  35. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_GeoPose.json +0 -0
  36. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_NavSatStatus.json +0 -0
  37. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_Node.json +0 -0
  38. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_PlannedTrajectory.json +0 -0
  39. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_PlannedWaypoint.json +0 -0
  40. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_PoseSE3.json +0 -0
  41. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_SnapshotRequest.json +0 -0
  42. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_SnapshotResponse.json +0 -0
  43. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_TileKey.json +0 -0
  44. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_TileMeta.json +0 -0
  45. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_core_TilePatch.json +0 -0
  46. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_Announce.json +0 -0
  47. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_Capabilities.json +0 -0
  48. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_ContentAnnounce.json +0 -0
  49. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_CoverageElement.json +0 -0
  50. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_CoverageFilter.json +0 -0
  51. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_CoverageHint.json +0 -0
  52. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_CoverageQuery.json +0 -0
  53. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_CoverageResponse.json +0 -0
  54. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_Depart.json +0 -0
  55. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_KV.json +0 -0
  56. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_ProfileSupport.json +0 -0
  57. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_ServiceSummary.json +0 -0
  58. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_TopicMeta.json +0 -0
  59. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_Transform.json +0 -0
  60. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_disco_ValidityWindow.json +0 -0
  61. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_events_CrossingLine.json +0 -0
  62. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_events_SpatialEvent.json +0 -0
  63. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_events_SpatialZone.json +0 -0
  64. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_events_ZoneState.json +0 -0
  65. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_mapping_Edge.json +0 -0
  66. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_mapping_MapAlignment.json +0 -0
  67. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_mapping_MapEvent.json +0 -0
  68. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_mapping_MapMeta.json +0 -0
  69. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_mapping_MapQuality.json +0 -0
  70. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_owm_Entity.json +0 -0
  71. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_owm_ModelCommand.json +0 -0
  72. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_owm_ModelPose.json +0 -0
  73. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_semantics_Detection2D.json +0 -0
  74. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_semantics_Detection2DSet.json +0 -0
  75. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_semantics_Detection3D.json +0 -0
  76. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_semantics_Detection3DSet.json +0 -0
  77. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrack.json +0 -0
  78. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_semantics_FusedTrackSet.json +0 -0
  79. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_semantics_Keypoint3D.json +0 -0
  80. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_semantics_KeypointLink.json +0 -0
  81. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_common_Axis.json +0 -0
  82. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameHeader.json +0 -0
  83. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_common_FrameQuality.json +0 -0
  84. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_common_Linspace.json +0 -0
  85. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_common_ROI.json +0 -0
  86. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIReply.json +0 -0
  87. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_common_ROIRequest.json +0 -0
  88. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_common_StreamMeta.json +0 -0
  89. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetection.json +0 -0
  90. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarDetectionSet.json +0 -0
  91. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarFrame.json +0 -0
  92. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_lidar_LidarMeta.json +0 -0
  93. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetection.json +0 -0
  94. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadDetectionSet.json +0 -0
  95. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadSensorMeta.json +0 -0
  96. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorFrame.json +0 -0
  97. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_rad_RadTensorMeta.json +0 -0
  98. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioObservation.json +0 -0
  99. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioScan.json +0 -0
  100. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_radio_RadioSensorMeta.json +0 -0
  101. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamArraySet.json +0 -0
  102. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamFrame.json +0 -0
  103. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_rf_beam_RfBeamMeta.json +0 -0
  104. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_vision_CamIntrinsics.json +0 -0
  105. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_vision_Keypoint2D.json +0 -0
  106. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_vision_Track2D.json +0 -0
  107. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionDetections.json +0 -0
  108. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionFrame.json +0 -0
  109. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_sensing_vision_VisionMeta.json +0 -0
  110. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_slam_frontend_CameraInfo.json +0 -0
  111. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_slam_frontend_Feature2D.json +0 -0
  112. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_slam_frontend_FeatureMatch.json +0 -0
  113. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_slam_frontend_KeyframeFeatures.json +0 -0
  114. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_slam_frontend_Landmark.json +0 -0
  115. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_slam_frontend_MatchSet.json +0 -0
  116. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_slam_frontend_TrackObs.json +0 -0
  117. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_slam_frontend_Tracklet.json +0 -0
  118. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_vio_FusedState.json +0 -0
  119. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_vio_ImuInfo.json +0 -0
  120. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_vio_ImuSample.json +0 -0
  121. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_vio_MagnetometerSample.json +0 -0
  122. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/schemas/spatial_vio_SensorFusionSample.json +0 -0
  123. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/artifacts/serializer_tables.json +0 -0
  124. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/canonical.py +0 -0
  125. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/canonjson.py +0 -0
  126. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/client.py +0 -0
  127. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/demo/assets/duck.gltf +0 -0
  128. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/demo/assets/fountain-label.txt +0 -0
  129. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/demo/assets/fountain-marker.gltf +0 -0
  130. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/demo/fountain-anchors.mcap +0 -0
  131. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/demo/manifests/content-fountain-label.json +0 -0
  132. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/demo/manifests/content-fountain-marker.json +0 -0
  133. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/errors.py +0 -0
  134. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/records.py +0 -0
  135. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/serve.py +0 -0
  136. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/__init__.py +0 -0
  137. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/commands.py +0 -0
  138. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/gateway.py +0 -0
  139. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/idlmodel.py +0 -0
  140. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/pin.py +0 -0
  141. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/publish.py +0 -0
  142. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/webjson.py +0 -0
  143. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds/server/xcdr2.py +0 -0
  144. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds.egg-info/SOURCES.txt +0 -0
  145. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds.egg-info/dependency_links.txt +0 -0
  146. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds.egg-info/entry_points.txt +0 -0
  147. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds.egg-info/requires.txt +0 -0
  148. {spatialdds-0.5.3 → spatialdds-0.5.4}/spatialdds.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spatialdds
3
- Version: 0.5.3
3
+ Version: 0.5.4
4
4
  Summary: SpatialDDS over plain HTTPS and a WebSocket: a client for the web binding (Appendix N), and the reference registry behind one command.
5
5
  Author: Open AR Cloud
6
6
  License: Apache-2.0
@@ -428,7 +428,7 @@ pumping 202 samples into two registered subscriber queues delivered 0 live
428
428
  events. If you call `notify` only from the serving loop, 0.5.0 and 0.5.1 were
429
429
  correct for you.
430
430
 
431
- 0.5.3 lets a browser reach this gateway at all. `Authorization` is not a
431
+ 0.5.3 let a browser reach this gateway at all. `Authorization` is not a
432
432
  CORS-safelisted request header, so a cross-origin request carrying one is
433
433
  preceded by an `OPTIONS` preflight — and no `OPTIONS` was routed, so aiohttp
434
434
  answered `405 Allow: GET,HEAD,POST` and the browser stopped there without
@@ -453,7 +453,25 @@ required, and nothing is newly reachable without one.
453
453
  If your clients are not browsers, 0.5.0 through 0.5.2 were correct for you:
454
454
  nothing else changes, and no response loses a header it had.
455
455
 
456
- ## Not in 0.5.3
456
+ 0.5.4 finishes what 0.5.3 started, and the gap is instructive. 0.5.3 threaded
457
+ the asking origin through the three places that build a response from
458
+ `_cache_headers` and missed the two that build one by hand: the N.6 command
459
+ lane's own reply, and **every N.8 problem document**. So a command published
460
+ and the page could not read the outcome --- a cross-origin `fetch` rejects a
461
+ response with no allowed origin, so a client saw a failure for a command that
462
+ had in fact succeeded --- and a `401`, `409` or `400` was unreadable by the
463
+ client it was written for, which is N.8 failing at the one thing that
464
+ distinguishes it from a bare status.
465
+
466
+ The fix is a one-rule middleware rather than a fourth and fifth call site:
467
+ where a response names no origin and the request had one, echo it with
468
+ `Vary: Origin`. `_cache_headers` remains the place that decides cacheability
469
+ and reach together and is unchanged where it already acts. Threading it
470
+ explicitly was tried first and is what missed two paths.
471
+
472
+ If your clients are not browsers, nothing here changes anything for you.
473
+
474
+ ## Not in 0.5.4
457
475
 
458
476
  Stated so nobody waits for them: no async API, no caching beyond ETag
459
477
  revalidation, no retry policy, no MCAP tooling beyond the journal the server
@@ -404,7 +404,7 @@ pumping 202 samples into two registered subscriber queues delivered 0 live
404
404
  events. If you call `notify` only from the serving loop, 0.5.0 and 0.5.1 were
405
405
  correct for you.
406
406
 
407
- 0.5.3 lets a browser reach this gateway at all. `Authorization` is not a
407
+ 0.5.3 let a browser reach this gateway at all. `Authorization` is not a
408
408
  CORS-safelisted request header, so a cross-origin request carrying one is
409
409
  preceded by an `OPTIONS` preflight — and no `OPTIONS` was routed, so aiohttp
410
410
  answered `405 Allow: GET,HEAD,POST` and the browser stopped there without
@@ -429,7 +429,25 @@ required, and nothing is newly reachable without one.
429
429
  If your clients are not browsers, 0.5.0 through 0.5.2 were correct for you:
430
430
  nothing else changes, and no response loses a header it had.
431
431
 
432
- ## Not in 0.5.3
432
+ 0.5.4 finishes what 0.5.3 started, and the gap is instructive. 0.5.3 threaded
433
+ the asking origin through the three places that build a response from
434
+ `_cache_headers` and missed the two that build one by hand: the N.6 command
435
+ lane's own reply, and **every N.8 problem document**. So a command published
436
+ and the page could not read the outcome --- a cross-origin `fetch` rejects a
437
+ response with no allowed origin, so a client saw a failure for a command that
438
+ had in fact succeeded --- and a `401`, `409` or `400` was unreadable by the
439
+ client it was written for, which is N.8 failing at the one thing that
440
+ distinguishes it from a bare status.
441
+
442
+ The fix is a one-rule middleware rather than a fourth and fifth call site:
443
+ where a response names no origin and the request had one, echo it with
444
+ `Vary: Origin`. `_cache_headers` remains the place that decides cacheability
445
+ and reach together and is unchanged where it already acts. Threading it
446
+ explicitly was tried first and is what missed two paths.
447
+
448
+ If your clients are not browsers, nothing here changes anything for you.
449
+
450
+ ## Not in 0.5.4
433
451
 
434
452
  Stated so nobody waits for them: no async API, no caching beyond ETag
435
453
  revalidation, no retry policy, no MCAP tooling beyond the journal the server
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "spatialdds"
7
- version = "0.5.3"
7
+ version = "0.5.4"
8
8
  description = "SpatialDDS over plain HTTPS and a WebSocket: a client for the web binding (Appendix N), and the reference registry behind one command."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -37,7 +37,7 @@ __all__ = [
37
37
  "content_manifest", "geo_anchor", "service_uri", "content_uri",
38
38
  ]
39
39
 
40
- __version__ = "0.5.3"
40
+ __version__ = "0.5.4"
41
41
  #: The SpatialDDS-spec commit whose Appendix N and generated artifacts this
42
42
  #: package implements. Package versions and specification versions move
43
43
  #: independently; this is the one that says what the wire looks like.
@@ -164,6 +164,49 @@ def _cache_headers(access: str, doc_ttl: int | None = None,
164
164
  return headers
165
165
 
166
166
 
167
+ @web.middleware
168
+ async def _reach(request: web.Request, handler) -> web.StreamResponse:
169
+ """Make sure every answer names the origin that asked for it.
170
+
171
+ **A backstop, not the policy.** `_cache_headers` remains the single place
172
+ that decides cacheability and reach together, and where it has already set
173
+ `Access-Control-Allow-Origin` this changes nothing. What it covers is the
174
+ responses that set no reach at all, because they are built by hand rather
175
+ than through that function --- and the reason it exists is that threading
176
+ the origin explicitly through every construction site was tried first, in
177
+ 0.5.3, and missed two:
178
+
179
+ * `post_command`'s `202`. The command published and the page could not
180
+ read the outcome: a cross-origin `fetch` rejects a response with no
181
+ allowed origin, so `bindingCommand` in the demo's client landed in its
182
+ `catch` with no status at all, for a command that had in fact succeeded.
183
+ * **Every N.8 problem document.** `_problem` set `no-store` and nothing
184
+ else, so a `401`, `409` or `400` was unreadable by the client it was
185
+ written for. N.8 exists to hand a client a *reason*; a reason a browser
186
+ cannot read is the surface failing at the one thing that distinguishes
187
+ it from a bare status.
188
+
189
+ Both were found by curling the running demo after 0.5.3 shipped, not by
190
+ this repository's gates --- the same way the original defect was found,
191
+ which is the lesson repeating rather than a new one.
192
+
193
+ Only the origin is echoed here, and only when absent. `Vary: Origin` goes
194
+ with it so a shared cache cannot serve one origin's answer to another; the
195
+ `Expose-Headers` set is added for the same reason it is on a GET, since a
196
+ reader that cannot see the ETag cannot revalidate. `Allow-Credentials` is
197
+ still set nowhere.
198
+ """
199
+ response = await handler(request)
200
+ origin = request.headers.get("Origin")
201
+ if origin and "Access-Control-Allow-Origin" not in response.headers:
202
+ response.headers["Access-Control-Allow-Origin"] = origin
203
+ vary = response.headers.get("Vary")
204
+ response.headers["Vary"] = f"{vary}, Origin" if vary else "Origin"
205
+ response.headers.setdefault("Access-Control-Expose-Headers",
206
+ EXPOSE_HEADERS)
207
+ return response
208
+
209
+
167
210
  async def preflight(request: web.Request) -> web.Response:
168
211
  """Answer the `OPTIONS` a browser sends before a credentialed request.
169
212
 
@@ -1001,7 +1044,7 @@ def make_app(state: gateway.State, base: str, token: str | None,
1001
1044
  embedder passes `publish_enabled=False, live_subscriptions=True` and gets
1002
1045
  the live lane with no write surface at all.
1003
1046
  """
1004
- app = web.Application()
1047
+ app = web.Application(middlewares=[_reach])
1005
1048
  app["state"] = state
1006
1049
  app["base"] = base.rstrip("/")
1007
1050
  app["token"] = token
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spatialdds
3
- Version: 0.5.3
3
+ Version: 0.5.4
4
4
  Summary: SpatialDDS over plain HTTPS and a WebSocket: a client for the web binding (Appendix N), and the reference registry behind one command.
5
5
  Author: Open AR Cloud
6
6
  License: Apache-2.0
@@ -428,7 +428,7 @@ pumping 202 samples into two registered subscriber queues delivered 0 live
428
428
  events. If you call `notify` only from the serving loop, 0.5.0 and 0.5.1 were
429
429
  correct for you.
430
430
 
431
- 0.5.3 lets a browser reach this gateway at all. `Authorization` is not a
431
+ 0.5.3 let a browser reach this gateway at all. `Authorization` is not a
432
432
  CORS-safelisted request header, so a cross-origin request carrying one is
433
433
  preceded by an `OPTIONS` preflight — and no `OPTIONS` was routed, so aiohttp
434
434
  answered `405 Allow: GET,HEAD,POST` and the browser stopped there without
@@ -453,7 +453,25 @@ required, and nothing is newly reachable without one.
453
453
  If your clients are not browsers, 0.5.0 through 0.5.2 were correct for you:
454
454
  nothing else changes, and no response loses a header it had.
455
455
 
456
- ## Not in 0.5.3
456
+ 0.5.4 finishes what 0.5.3 started, and the gap is instructive. 0.5.3 threaded
457
+ the asking origin through the three places that build a response from
458
+ `_cache_headers` and missed the two that build one by hand: the N.6 command
459
+ lane's own reply, and **every N.8 problem document**. So a command published
460
+ and the page could not read the outcome --- a cross-origin `fetch` rejects a
461
+ response with no allowed origin, so a client saw a failure for a command that
462
+ had in fact succeeded --- and a `401`, `409` or `400` was unreadable by the
463
+ client it was written for, which is N.8 failing at the one thing that
464
+ distinguishes it from a bare status.
465
+
466
+ The fix is a one-rule middleware rather than a fourth and fifth call site:
467
+ where a response names no origin and the request had one, echo it with
468
+ `Vary: Origin`. `_cache_headers` remains the place that decides cacheability
469
+ and reach together and is unchanged where it already acts. Threading it
470
+ explicitly was tried first and is what missed two paths.
471
+
472
+ If your clients are not browsers, nothing here changes anything for you.
473
+
474
+ ## Not in 0.5.4
457
475
 
458
476
  Stated so nobody waits for them: no async API, no caching beyond ETag
459
477
  revalidation, no retry policy, no MCAP tooling beyond the journal the server
File without changes