MapProxy 2.1.0__py3-none-any.whl

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 (459) hide show
  1. MapProxy-2.1.0.dist-info/AUTHORS.txt +33 -0
  2. MapProxy-2.1.0.dist-info/COPYING.txt +60 -0
  3. MapProxy-2.1.0.dist-info/LICENSE.txt +202 -0
  4. MapProxy-2.1.0.dist-info/METADATA +165 -0
  5. MapProxy-2.1.0.dist-info/RECORD +459 -0
  6. MapProxy-2.1.0.dist-info/WHEEL +5 -0
  7. MapProxy-2.1.0.dist-info/entry_points.txt +4 -0
  8. MapProxy-2.1.0.dist-info/top_level.txt +1 -0
  9. mapproxy/__init__.py +0 -0
  10. mapproxy/cache/__init__.py +36 -0
  11. mapproxy/cache/azureblob.py +145 -0
  12. mapproxy/cache/base.py +120 -0
  13. mapproxy/cache/compact.py +665 -0
  14. mapproxy/cache/couchdb.py +301 -0
  15. mapproxy/cache/dummy.py +36 -0
  16. mapproxy/cache/file.py +200 -0
  17. mapproxy/cache/geopackage.py +647 -0
  18. mapproxy/cache/legend.py +87 -0
  19. mapproxy/cache/mbtiles.py +411 -0
  20. mapproxy/cache/meta.py +80 -0
  21. mapproxy/cache/path.py +261 -0
  22. mapproxy/cache/redis.py +152 -0
  23. mapproxy/cache/renderd.py +100 -0
  24. mapproxy/cache/riak.py +206 -0
  25. mapproxy/cache/s3.py +209 -0
  26. mapproxy/cache/tile.py +736 -0
  27. mapproxy/client/__init__.py +0 -0
  28. mapproxy/client/arcgis.py +82 -0
  29. mapproxy/client/cgi.py +141 -0
  30. mapproxy/client/http.py +295 -0
  31. mapproxy/client/log.py +33 -0
  32. mapproxy/client/tile.py +158 -0
  33. mapproxy/client/wms.py +255 -0
  34. mapproxy/compat/__init__.py +0 -0
  35. mapproxy/compat/image.py +86 -0
  36. mapproxy/config/__init__.py +22 -0
  37. mapproxy/config/config-schema.json +813 -0
  38. mapproxy/config/config.py +213 -0
  39. mapproxy/config/coverage.py +108 -0
  40. mapproxy/config/defaults.py +102 -0
  41. mapproxy/config/loader.py +2399 -0
  42. mapproxy/config/spec.py +657 -0
  43. mapproxy/config/validator.py +242 -0
  44. mapproxy/config_template/__init__.py +0 -0
  45. mapproxy/config_template/base_config/config.wsgi +10 -0
  46. mapproxy/config_template/base_config/full_example.yaml +598 -0
  47. mapproxy/config_template/base_config/full_seed_example.yaml +79 -0
  48. mapproxy/config_template/base_config/log.ini +35 -0
  49. mapproxy/config_template/base_config/mapproxy.yaml +60 -0
  50. mapproxy/config_template/base_config/seed.yaml +27 -0
  51. mapproxy/exception.py +149 -0
  52. mapproxy/featureinfo.py +251 -0
  53. mapproxy/grid.py +1199 -0
  54. mapproxy/image/__init__.py +549 -0
  55. mapproxy/image/fonts/DejaVuSans.ttf +0 -0
  56. mapproxy/image/fonts/DejaVuSansMono.ttf +0 -0
  57. mapproxy/image/fonts/LICENSE +99 -0
  58. mapproxy/image/fonts/__init__.py +0 -0
  59. mapproxy/image/mask.py +79 -0
  60. mapproxy/image/merge.py +323 -0
  61. mapproxy/image/message.py +357 -0
  62. mapproxy/image/opts.py +185 -0
  63. mapproxy/image/tile.py +171 -0
  64. mapproxy/image/transform.py +350 -0
  65. mapproxy/layer.py +489 -0
  66. mapproxy/multiapp.py +230 -0
  67. mapproxy/proj.py +309 -0
  68. mapproxy/request/__init__.py +18 -0
  69. mapproxy/request/arcgis.py +268 -0
  70. mapproxy/request/base.py +466 -0
  71. mapproxy/request/tile.py +131 -0
  72. mapproxy/request/wms/__init__.py +829 -0
  73. mapproxy/request/wms/exception.py +107 -0
  74. mapproxy/request/wmts.py +442 -0
  75. mapproxy/response.py +237 -0
  76. mapproxy/script/__init__.py +0 -0
  77. mapproxy/script/conf/__init__.py +0 -0
  78. mapproxy/script/conf/app.py +222 -0
  79. mapproxy/script/conf/caches.py +44 -0
  80. mapproxy/script/conf/geopackage.py +136 -0
  81. mapproxy/script/conf/layers.py +54 -0
  82. mapproxy/script/conf/seeds.py +36 -0
  83. mapproxy/script/conf/sources.py +88 -0
  84. mapproxy/script/conf/utils.py +148 -0
  85. mapproxy/script/defrag.py +187 -0
  86. mapproxy/script/export.py +337 -0
  87. mapproxy/script/grids.py +198 -0
  88. mapproxy/script/scales.py +134 -0
  89. mapproxy/script/util.py +410 -0
  90. mapproxy/script/wms_capabilities.py +160 -0
  91. mapproxy/seed/__init__.py +0 -0
  92. mapproxy/seed/cachelock.py +127 -0
  93. mapproxy/seed/cleanup.py +191 -0
  94. mapproxy/seed/config.py +481 -0
  95. mapproxy/seed/script.py +391 -0
  96. mapproxy/seed/seeder.py +551 -0
  97. mapproxy/seed/spec.py +66 -0
  98. mapproxy/seed/util.py +266 -0
  99. mapproxy/service/__init__.py +14 -0
  100. mapproxy/service/base.py +45 -0
  101. mapproxy/service/demo.py +364 -0
  102. mapproxy/service/kml.py +333 -0
  103. mapproxy/service/ows.py +39 -0
  104. mapproxy/service/template_helper.py +55 -0
  105. mapproxy/service/templates/demo/capabilities_demo.html +18 -0
  106. mapproxy/service/templates/demo/demo.html +181 -0
  107. mapproxy/service/templates/demo/openlayers-demo.cfg +16 -0
  108. mapproxy/service/templates/demo/static/img/blank.gif +0 -0
  109. mapproxy/service/templates/demo/static/img/east-mini.png +0 -0
  110. mapproxy/service/templates/demo/static/img/north-mini.png +0 -0
  111. mapproxy/service/templates/demo/static/img/south-mini.png +0 -0
  112. mapproxy/service/templates/demo/static/img/west-mini.png +0 -0
  113. mapproxy/service/templates/demo/static/img/zoom-minus-mini.png +0 -0
  114. mapproxy/service/templates/demo/static/img/zoom-plus-mini.png +0 -0
  115. mapproxy/service/templates/demo/static/img/zoom-world-mini.png +0 -0
  116. mapproxy/service/templates/demo/static/logo.png +0 -0
  117. mapproxy/service/templates/demo/static/ol.css +345 -0
  118. mapproxy/service/templates/demo/static/ol.js +4 -0
  119. mapproxy/service/templates/demo/static/proj4.min.js +1 -0
  120. mapproxy/service/templates/demo/static/proj4defs.js +1 -0
  121. mapproxy/service/templates/demo/static/site.css +137 -0
  122. mapproxy/service/templates/demo/static/theme/default/framedCloud.css +0 -0
  123. mapproxy/service/templates/demo/static/theme/default/google.css +17 -0
  124. mapproxy/service/templates/demo/static/theme/default/ie6-style.css +10 -0
  125. mapproxy/service/templates/demo/static/theme/default/style.css +482 -0
  126. mapproxy/service/templates/demo/static.html +34 -0
  127. mapproxy/service/templates/demo/tms_demo.html +117 -0
  128. mapproxy/service/templates/demo/wms_demo.html +144 -0
  129. mapproxy/service/templates/demo/wmts_demo.html +118 -0
  130. mapproxy/service/templates/tms_capabilities.xml +13 -0
  131. mapproxy/service/templates/tms_exception.xml +4 -0
  132. mapproxy/service/templates/tms_root_resource.xml +7 -0
  133. mapproxy/service/templates/tms_tilemap_capabilities.xml +14 -0
  134. mapproxy/service/templates/wms100capabilities.xml +112 -0
  135. mapproxy/service/templates/wms100exception.xml +4 -0
  136. mapproxy/service/templates/wms110capabilities.xml +152 -0
  137. mapproxy/service/templates/wms110exception.xml +5 -0
  138. mapproxy/service/templates/wms111capabilities.xml +183 -0
  139. mapproxy/service/templates/wms111exception.xml +5 -0
  140. mapproxy/service/templates/wms130capabilities.xml +326 -0
  141. mapproxy/service/templates/wms130exception.xml +8 -0
  142. mapproxy/service/templates/wmts100capabilities.xml +155 -0
  143. mapproxy/service/templates/wmts100exception.xml +9 -0
  144. mapproxy/service/tile.py +540 -0
  145. mapproxy/service/wms.py +868 -0
  146. mapproxy/service/wmts.py +387 -0
  147. mapproxy/source/__init__.py +83 -0
  148. mapproxy/source/arcgis.py +39 -0
  149. mapproxy/source/error.py +40 -0
  150. mapproxy/source/mapnik.py +262 -0
  151. mapproxy/source/tile.py +97 -0
  152. mapproxy/source/wms.py +273 -0
  153. mapproxy/srs.py +734 -0
  154. mapproxy/template.py +54 -0
  155. mapproxy/test/__init__.py +0 -0
  156. mapproxy/test/conftest.py +8 -0
  157. mapproxy/test/helper.py +255 -0
  158. mapproxy/test/http.py +511 -0
  159. mapproxy/test/image.py +219 -0
  160. mapproxy/test/mocker.py +2291 -0
  161. mapproxy/test/schemas/inspire/common/1.0/common.xsd +1461 -0
  162. mapproxy/test/schemas/inspire/common/1.0/enums/enum_bul.xsd +108 -0
  163. mapproxy/test/schemas/inspire/common/1.0/enums/enum_cze.xsd +108 -0
  164. mapproxy/test/schemas/inspire/common/1.0/enums/enum_dan.xsd +108 -0
  165. mapproxy/test/schemas/inspire/common/1.0/enums/enum_dut.xsd +108 -0
  166. mapproxy/test/schemas/inspire/common/1.0/enums/enum_eng.xsd +155 -0
  167. mapproxy/test/schemas/inspire/common/1.0/enums/enum_est.xsd +108 -0
  168. mapproxy/test/schemas/inspire/common/1.0/enums/enum_fin.xsd +108 -0
  169. mapproxy/test/schemas/inspire/common/1.0/enums/enum_fre.xsd +108 -0
  170. mapproxy/test/schemas/inspire/common/1.0/enums/enum_ger.xsd +108 -0
  171. mapproxy/test/schemas/inspire/common/1.0/enums/enum_gle.xsd +109 -0
  172. mapproxy/test/schemas/inspire/common/1.0/enums/enum_gre.xsd +108 -0
  173. mapproxy/test/schemas/inspire/common/1.0/enums/enum_hun.xsd +108 -0
  174. mapproxy/test/schemas/inspire/common/1.0/enums/enum_ita.xsd +108 -0
  175. mapproxy/test/schemas/inspire/common/1.0/enums/enum_lav.xsd +108 -0
  176. mapproxy/test/schemas/inspire/common/1.0/enums/enum_lit.xsd +108 -0
  177. mapproxy/test/schemas/inspire/common/1.0/enums/enum_mlt.xsd +108 -0
  178. mapproxy/test/schemas/inspire/common/1.0/enums/enum_pol.xsd +108 -0
  179. mapproxy/test/schemas/inspire/common/1.0/enums/enum_por.xsd +108 -0
  180. mapproxy/test/schemas/inspire/common/1.0/enums/enum_rum.xsd +108 -0
  181. mapproxy/test/schemas/inspire/common/1.0/enums/enum_slo.xsd +108 -0
  182. mapproxy/test/schemas/inspire/common/1.0/enums/enum_slv.xsd +108 -0
  183. mapproxy/test/schemas/inspire/common/1.0/enums/enum_spa.xsd +108 -0
  184. mapproxy/test/schemas/inspire/common/1.0/enums/enum_swe.xsd +108 -0
  185. mapproxy/test/schemas/inspire/common/1.0/network.xsd +521 -0
  186. mapproxy/test/schemas/inspire/inspire_vs/1.0/inspire_vs.xsd +19 -0
  187. mapproxy/test/schemas/kml/2.2.0/ReadMe.txt +14 -0
  188. mapproxy/test/schemas/kml/2.2.0/atom-author-link.xsd +66 -0
  189. mapproxy/test/schemas/kml/2.2.0/ogckml22.xsd +1646 -0
  190. mapproxy/test/schemas/kml/2.2.0/xAL.xsd +1680 -0
  191. mapproxy/test/schemas/ows/1.1.0/ReadMe.txt +87 -0
  192. mapproxy/test/schemas/ows/1.1.0/ows19115subset.xsd +235 -0
  193. mapproxy/test/schemas/ows/1.1.0/owsAll.xsd +23 -0
  194. mapproxy/test/schemas/ows/1.1.0/owsCommon.xsd +157 -0
  195. mapproxy/test/schemas/ows/1.1.0/owsContents.xsd +86 -0
  196. mapproxy/test/schemas/ows/1.1.0/owsDataIdentification.xsd +127 -0
  197. mapproxy/test/schemas/ows/1.1.0/owsDomainType.xsd +279 -0
  198. mapproxy/test/schemas/ows/1.1.0/owsExceptionReport.xsd +76 -0
  199. mapproxy/test/schemas/ows/1.1.0/owsGetCapabilities.xsd +112 -0
  200. mapproxy/test/schemas/ows/1.1.0/owsGetResourceByID.xsd +51 -0
  201. mapproxy/test/schemas/ows/1.1.0/owsInputOutputData.xsd +59 -0
  202. mapproxy/test/schemas/ows/1.1.0/owsManifest.xsd +125 -0
  203. mapproxy/test/schemas/ows/1.1.0/owsOperationsMetadata.xsd +140 -0
  204. mapproxy/test/schemas/ows/1.1.0/owsServiceIdentification.xsd +60 -0
  205. mapproxy/test/schemas/ows/1.1.0/owsServiceProvider.xsd +47 -0
  206. mapproxy/test/schemas/sld/1.1.0/sld_capabilities.xsd +27 -0
  207. mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.dtd +353 -0
  208. mapproxy/test/schemas/wms/1.0.0/capabilities_1_0_0.xml +188 -0
  209. mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.dtd +524 -0
  210. mapproxy/test/schemas/wms/1.0.7/capabilities_1_0_7.xml +260 -0
  211. mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.dtd +273 -0
  212. mapproxy/test/schemas/wms/1.1.0/capabilities_1_1_0.xml +303 -0
  213. mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.dtd +6 -0
  214. mapproxy/test/schemas/wms/1.1.0/exception_1_1_0.xml +33 -0
  215. mapproxy/test/schemas/wms/1.1.1/OGC-exception.xsd +68 -0
  216. mapproxy/test/schemas/wms/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
  217. mapproxy/test/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd +274 -0
  218. mapproxy/test/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd +5 -0
  219. mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.dtd +276 -0
  220. mapproxy/test/schemas/wms/1.1.1/capabilities_1_1_1.xml +303 -0
  221. mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.dtd +6 -0
  222. mapproxy/test/schemas/wms/1.1.1/exception_1_1_1.xml +33 -0
  223. mapproxy/test/schemas/wms/1.3.0/ReadMe.txt +8 -0
  224. mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xml +277 -0
  225. mapproxy/test/schemas/wms/1.3.0/capabilities_1_3_0.xsd +611 -0
  226. mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xml +34 -0
  227. mapproxy/test/schemas/wms/1.3.0/exceptions_1_3_0.xsd +28 -0
  228. mapproxy/test/schemas/wmsc/1.1.1/OGC-exception.xsd +68 -0
  229. mapproxy/test/schemas/wmsc/1.1.1/WMS_DescribeLayerResponse.dtd +22 -0
  230. mapproxy/test/schemas/wmsc/1.1.1/WMS_MS_Capabilities.dtd +283 -0
  231. mapproxy/test/schemas/wmsc/1.1.1/WMS_exception_1_1_1.dtd +5 -0
  232. mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.dtd +276 -0
  233. mapproxy/test/schemas/wmsc/1.1.1/capabilities_1_1_1.xml +303 -0
  234. mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.dtd +6 -0
  235. mapproxy/test/schemas/wmsc/1.1.1/exception_1_1_1.xml +33 -0
  236. mapproxy/test/schemas/wmts/1.0/ReadMe.txt +32 -0
  237. mapproxy/test/schemas/wmts/1.0/wmts.xsd +28 -0
  238. mapproxy/test/schemas/wmts/1.0/wmtsAbstract.wsdl +151 -0
  239. mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_request.xsd +38 -0
  240. mapproxy/test/schemas/wmts/1.0/wmtsGetCapabilities_response.xsd +564 -0
  241. mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_request.xsd +57 -0
  242. mapproxy/test/schemas/wmts/1.0/wmtsGetFeatureInfo_response.xsd +72 -0
  243. mapproxy/test/schemas/wmts/1.0/wmtsGetTile_request.xsd +91 -0
  244. mapproxy/test/schemas/wmts/1.0/wmtsKVP.xsd +76 -0
  245. mapproxy/test/schemas/wmts/1.0/wmtsPayload_response.xsd +70 -0
  246. mapproxy/test/schemas/xlink/1.0.0/ReadMe.txt +6 -0
  247. mapproxy/test/schemas/xlink/1.0.0/xlinks.xsd +122 -0
  248. mapproxy/test/schemas/xml.xsd +287 -0
  249. mapproxy/test/system/__init__.py +98 -0
  250. mapproxy/test/system/fixture/arcgis.yaml +57 -0
  251. mapproxy/test/system/fixture/auth.yaml +70 -0
  252. mapproxy/test/system/fixture/cache.mbtiles +0 -0
  253. mapproxy/test/system/fixture/cache_azureblob.yaml +59 -0
  254. mapproxy/test/system/fixture/cache_band_merge.yaml +73 -0
  255. mapproxy/test/system/fixture/cache_bulk_meta_tiles.yaml +24 -0
  256. mapproxy/test/system/fixture/cache_coverage.yaml +84 -0
  257. mapproxy/test/system/fixture/cache_data/dop_cache_EPSG3857/00/000/000/000/000/000/000.png +0 -0
  258. mapproxy/test/system/fixture/cache_data/wms_cache_EPSG900913/01/000/000/000/000/000/001.jpeg +0 -0
  259. mapproxy/test/system/fixture/cache_data/wms_cache_transparent_EPSG900913/01/000/000/000/000/000/001.png +0 -0
  260. mapproxy/test/system/fixture/cache_geopackage.yaml +56 -0
  261. mapproxy/test/system/fixture/cache_grid_names.yaml +50 -0
  262. mapproxy/test/system/fixture/cache_mbtiles.yaml +28 -0
  263. mapproxy/test/system/fixture/cache_s3.yaml +58 -0
  264. mapproxy/test/system/fixture/cache_source.yaml +81 -0
  265. mapproxy/test/system/fixture/combined_sources.yaml +130 -0
  266. mapproxy/test/system/fixture/coverage.yaml +77 -0
  267. mapproxy/test/system/fixture/demo.yaml +135 -0
  268. mapproxy/test/system/fixture/dimension.yaml +59 -0
  269. mapproxy/test/system/fixture/disable_storage.yaml +25 -0
  270. mapproxy/test/system/fixture/empty_ogrdata.geojson +1 -0
  271. mapproxy/test/system/fixture/formats.yaml +72 -0
  272. mapproxy/test/system/fixture/inspire.yaml +101 -0
  273. mapproxy/test/system/fixture/inspire_full.yaml +124 -0
  274. mapproxy/test/system/fixture/kml_layer.yaml +66 -0
  275. mapproxy/test/system/fixture/layer.yaml +260 -0
  276. mapproxy/test/system/fixture/layergroups.yaml +57 -0
  277. mapproxy/test/system/fixture/layergroups_root.yaml +106 -0
  278. mapproxy/test/system/fixture/legendgraphic.yaml +93 -0
  279. mapproxy/test/system/fixture/mapnik_source.yaml +66 -0
  280. mapproxy/test/system/fixture/mapproxy_export.yaml +12 -0
  281. mapproxy/test/system/fixture/mapserver.yaml +23 -0
  282. mapproxy/test/system/fixture/minimal_cgi.py +16 -0
  283. mapproxy/test/system/fixture/mixed_mode.yaml +49 -0
  284. mapproxy/test/system/fixture/multi_cache_layers.yaml +111 -0
  285. mapproxy/test/system/fixture/multiapp1.yaml +20 -0
  286. mapproxy/test/system/fixture/multiapp2.yaml +19 -0
  287. mapproxy/test/system/fixture/renderd_client.yaml +55 -0
  288. mapproxy/test/system/fixture/scalehints.yaml +70 -0
  289. mapproxy/test/system/fixture/seed.yaml +94 -0
  290. mapproxy/test/system/fixture/seed_mapproxy.yaml +39 -0
  291. mapproxy/test/system/fixture/seed_old.yaml +12 -0
  292. mapproxy/test/system/fixture/seed_timeouts.yaml +12 -0
  293. mapproxy/test/system/fixture/seed_timeouts_mapproxy.yaml +27 -0
  294. mapproxy/test/system/fixture/seedonly.yaml +51 -0
  295. mapproxy/test/system/fixture/sld.yaml +35 -0
  296. mapproxy/test/system/fixture/source_errors.yaml +84 -0
  297. mapproxy/test/system/fixture/source_errors_raise.yaml +82 -0
  298. mapproxy/test/system/fixture/tileservice_origin.yaml +26 -0
  299. mapproxy/test/system/fixture/tileservice_refresh.yaml +59 -0
  300. mapproxy/test/system/fixture/tilesource_minmax_res.yaml +22 -0
  301. mapproxy/test/system/fixture/util-conf-base-grids.yaml +5 -0
  302. mapproxy/test/system/fixture/util-conf-overwrite.yaml +13 -0
  303. mapproxy/test/system/fixture/util-conf-wms-111-cap.xml +90 -0
  304. mapproxy/test/system/fixture/util_grids.yaml +29 -0
  305. mapproxy/test/system/fixture/util_wms_capabilities111.xml +130 -0
  306. mapproxy/test/system/fixture/util_wms_capabilities130.xml +100 -0
  307. mapproxy/test/system/fixture/util_wms_capabilities_service_exception.xml +5 -0
  308. mapproxy/test/system/fixture/watermark.yaml +50 -0
  309. mapproxy/test/system/fixture/wms_srs_extent.yaml +39 -0
  310. mapproxy/test/system/fixture/wms_versions.yaml +38 -0
  311. mapproxy/test/system/fixture/wmts.yaml +134 -0
  312. mapproxy/test/system/fixture/wmts_dimensions.yaml +57 -0
  313. mapproxy/test/system/fixture/xslt_featureinfo.yaml +54 -0
  314. mapproxy/test/system/fixture/xslt_featureinfo_input.yaml +51 -0
  315. mapproxy/test/system/test_arcgis.py +156 -0
  316. mapproxy/test/system/test_auth.py +1133 -0
  317. mapproxy/test/system/test_behind_proxy.py +75 -0
  318. mapproxy/test/system/test_bulk_meta_tiles.py +106 -0
  319. mapproxy/test/system/test_cache_azureblob.py +127 -0
  320. mapproxy/test/system/test_cache_band_merge.py +103 -0
  321. mapproxy/test/system/test_cache_coverage.py +168 -0
  322. mapproxy/test/system/test_cache_geopackage.py +144 -0
  323. mapproxy/test/system/test_cache_grid_names.py +89 -0
  324. mapproxy/test/system/test_cache_mbtiles.py +85 -0
  325. mapproxy/test/system/test_cache_s3.py +115 -0
  326. mapproxy/test/system/test_cache_source.py +146 -0
  327. mapproxy/test/system/test_combined_sources.py +335 -0
  328. mapproxy/test/system/test_coverage.py +140 -0
  329. mapproxy/test/system/test_decorate_img.py +214 -0
  330. mapproxy/test/system/test_demo.py +56 -0
  331. mapproxy/test/system/test_demo_with_extra_service.py +57 -0
  332. mapproxy/test/system/test_dimensions.py +279 -0
  333. mapproxy/test/system/test_disable_storage.py +42 -0
  334. mapproxy/test/system/test_formats.py +219 -0
  335. mapproxy/test/system/test_inspire_vs.py +173 -0
  336. mapproxy/test/system/test_kml.py +264 -0
  337. mapproxy/test/system/test_layergroups.py +160 -0
  338. mapproxy/test/system/test_legendgraphic.py +308 -0
  339. mapproxy/test/system/test_mapnik.py +162 -0
  340. mapproxy/test/system/test_mapserver.py +83 -0
  341. mapproxy/test/system/test_mixed_mode_format.py +201 -0
  342. mapproxy/test/system/test_multi_cache_layers.py +169 -0
  343. mapproxy/test/system/test_multiapp.py +92 -0
  344. mapproxy/test/system/test_refresh.py +206 -0
  345. mapproxy/test/system/test_renderd_client.py +304 -0
  346. mapproxy/test/system/test_response_headers.py +54 -0
  347. mapproxy/test/system/test_scalehints.py +140 -0
  348. mapproxy/test/system/test_seed.py +425 -0
  349. mapproxy/test/system/test_seed_only.py +93 -0
  350. mapproxy/test/system/test_sld.py +120 -0
  351. mapproxy/test/system/test_source_errors.py +377 -0
  352. mapproxy/test/system/test_tilesource_minmax_res.py +54 -0
  353. mapproxy/test/system/test_tms.py +277 -0
  354. mapproxy/test/system/test_tms_origin.py +46 -0
  355. mapproxy/test/system/test_util_conf.py +434 -0
  356. mapproxy/test/system/test_util_export.py +210 -0
  357. mapproxy/test/system/test_util_grids.py +88 -0
  358. mapproxy/test/system/test_util_wms_capabilities.py +182 -0
  359. mapproxy/test/system/test_watermark.py +91 -0
  360. mapproxy/test/system/test_wms.py +1616 -0
  361. mapproxy/test/system/test_wms_srs_extent.py +165 -0
  362. mapproxy/test/system/test_wms_version.py +85 -0
  363. mapproxy/test/system/test_wmsc.py +116 -0
  364. mapproxy/test/system/test_wmts.py +334 -0
  365. mapproxy/test/system/test_wmts_dimensions.py +206 -0
  366. mapproxy/test/system/test_wmts_restful.py +198 -0
  367. mapproxy/test/system/test_xslt_featureinfo.py +423 -0
  368. mapproxy/test/test_http_helper.py +217 -0
  369. mapproxy/test/unit/__init__.py +0 -0
  370. mapproxy/test/unit/epsg +2 -0
  371. mapproxy/test/unit/polygons/polygons.dbf +0 -0
  372. mapproxy/test/unit/polygons/polygons.shp +0 -0
  373. mapproxy/test/unit/polygons/polygons.shx +0 -0
  374. mapproxy/test/unit/test_async.py +242 -0
  375. mapproxy/test/unit/test_auth.py +430 -0
  376. mapproxy/test/unit/test_cache.py +1356 -0
  377. mapproxy/test/unit/test_cache_azureblob.py +97 -0
  378. mapproxy/test/unit/test_cache_compact.py +324 -0
  379. mapproxy/test/unit/test_cache_couchdb.py +118 -0
  380. mapproxy/test/unit/test_cache_geopackage.py +256 -0
  381. mapproxy/test/unit/test_cache_redis.py +123 -0
  382. mapproxy/test/unit/test_cache_riak.py +80 -0
  383. mapproxy/test/unit/test_cache_s3.py +93 -0
  384. mapproxy/test/unit/test_cache_tile.py +477 -0
  385. mapproxy/test/unit/test_client.py +488 -0
  386. mapproxy/test/unit/test_client_arcgis.py +74 -0
  387. mapproxy/test/unit/test_client_cgi.py +140 -0
  388. mapproxy/test/unit/test_collections.py +116 -0
  389. mapproxy/test/unit/test_concat_legends.py +37 -0
  390. mapproxy/test/unit/test_conf_loader.py +1267 -0
  391. mapproxy/test/unit/test_conf_validator.py +427 -0
  392. mapproxy/test/unit/test_config.py +118 -0
  393. mapproxy/test/unit/test_decorate_img.py +185 -0
  394. mapproxy/test/unit/test_exceptions.py +270 -0
  395. mapproxy/test/unit/test_featureinfo.py +313 -0
  396. mapproxy/test/unit/test_file_lock_load.py +49 -0
  397. mapproxy/test/unit/test_geom.py +512 -0
  398. mapproxy/test/unit/test_grid.py +1279 -0
  399. mapproxy/test/unit/test_image.py +1051 -0
  400. mapproxy/test/unit/test_image_mask.py +181 -0
  401. mapproxy/test/unit/test_image_messages.py +209 -0
  402. mapproxy/test/unit/test_image_options.py +160 -0
  403. mapproxy/test/unit/test_isodate.py +118 -0
  404. mapproxy/test/unit/test_multiapp.py +163 -0
  405. mapproxy/test/unit/test_ogr_reader.py +51 -0
  406. mapproxy/test/unit/test_request.py +745 -0
  407. mapproxy/test/unit/test_request_wmts.py +178 -0
  408. mapproxy/test/unit/test_response.py +78 -0
  409. mapproxy/test/unit/test_seed.py +365 -0
  410. mapproxy/test/unit/test_seed_cachelock.py +91 -0
  411. mapproxy/test/unit/test_srs.py +215 -0
  412. mapproxy/test/unit/test_tiled_source.py +122 -0
  413. mapproxy/test/unit/test_tilefilter.py +31 -0
  414. mapproxy/test/unit/test_times.py +25 -0
  415. mapproxy/test/unit/test_timeutils.py +50 -0
  416. mapproxy/test/unit/test_util_conf_utils.py +75 -0
  417. mapproxy/test/unit/test_utils.py +476 -0
  418. mapproxy/test/unit/test_wms_capabilities.py +44 -0
  419. mapproxy/test/unit/test_wms_layer.py +113 -0
  420. mapproxy/test/unit/test_yaml.py +68 -0
  421. mapproxy/tilefilter.py +61 -0
  422. mapproxy/util/__init__.py +0 -0
  423. mapproxy/util/async_.py +229 -0
  424. mapproxy/util/collections.py +134 -0
  425. mapproxy/util/coverage.py +337 -0
  426. mapproxy/util/ext/__init__.py +14 -0
  427. mapproxy/util/ext/dictspec/__init__.py +1 -0
  428. mapproxy/util/ext/dictspec/spec.py +131 -0
  429. mapproxy/util/ext/dictspec/test/__init__.py +0 -0
  430. mapproxy/util/ext/dictspec/test/test_validator.py +278 -0
  431. mapproxy/util/ext/dictspec/validator.py +194 -0
  432. mapproxy/util/ext/local.py +198 -0
  433. mapproxy/util/ext/lockfile.py +140 -0
  434. mapproxy/util/ext/odict.py +321 -0
  435. mapproxy/util/ext/serving.py +491 -0
  436. mapproxy/util/ext/tempita/__init__.py +1093 -0
  437. mapproxy/util/ext/tempita/_looper.py +163 -0
  438. mapproxy/util/ext/tempita/string_utils.py +24 -0
  439. mapproxy/util/ext/wmsparse/__init__.py +3 -0
  440. mapproxy/util/ext/wmsparse/duration.py +600 -0
  441. mapproxy/util/ext/wmsparse/parse.py +307 -0
  442. mapproxy/util/ext/wmsparse/test/__init__.py +0 -0
  443. mapproxy/util/ext/wmsparse/test/test_parse.py +111 -0
  444. mapproxy/util/ext/wmsparse/test/test_util.py +23 -0
  445. mapproxy/util/ext/wmsparse/test/wms-example-111.xml +90 -0
  446. mapproxy/util/ext/wmsparse/test/wms-example-130.xml +120 -0
  447. mapproxy/util/ext/wmsparse/test/wms-large-111.xml +2114 -0
  448. mapproxy/util/ext/wmsparse/test/wms_nasa_cap.xml +386 -0
  449. mapproxy/util/ext/wmsparse/util.py +189 -0
  450. mapproxy/util/fs.py +164 -0
  451. mapproxy/util/geom.py +307 -0
  452. mapproxy/util/lib.py +117 -0
  453. mapproxy/util/lock.py +171 -0
  454. mapproxy/util/ogr.py +247 -0
  455. mapproxy/util/py.py +75 -0
  456. mapproxy/util/times.py +78 -0
  457. mapproxy/util/yaml.py +58 -0
  458. mapproxy/version.py +33 -0
  459. mapproxy/wsgiapp.py +167 -0
@@ -0,0 +1,488 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2010-2017 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+
17
+ import os
18
+ import sys
19
+ import time
20
+
21
+ import pytest
22
+
23
+ from mapproxy.client.http import HTTPClient, HTTPClientError
24
+ from mapproxy.client.tile import TileClient, TileURLTemplate
25
+ from mapproxy.client.wms import WMSClient, WMSInfoClient
26
+ from mapproxy.grid import tile_grid
27
+ from mapproxy.layer import MapQuery, InfoQuery
28
+ from mapproxy.request.wms import (
29
+ WMS111MapRequest,
30
+ WMS100MapRequest,
31
+ WMS130MapRequest,
32
+ WMS111FeatureInfoRequest,
33
+ )
34
+ from mapproxy.source import SourceError
35
+ from mapproxy.srs import SRS, SupportedSRS
36
+ from mapproxy.test.helper import assert_re, TempFile
37
+ from mapproxy.test.http import mock_httpd, query_eq, assert_query_eq, wms_query_eq
38
+ from mapproxy.test.unit.test_cache import MockHTTPClient
39
+
40
+
41
+ TESTSERVER_ADDRESS = ('127.0.0.1', 56413)
42
+ TESTSERVER_URL = 'http://%s:%s' % TESTSERVER_ADDRESS
43
+
44
+
45
+ class TestHTTPClient(object):
46
+ def setup_method(self):
47
+ self.client = HTTPClient()
48
+
49
+ def test_post(self):
50
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/service?foo=bar', 'method': 'POST'},
51
+ {'status': '200', 'body': b''})]):
52
+ self.client.open(TESTSERVER_URL + '/service', data=b"foo=bar")
53
+
54
+ @pytest.mark.skipif(sys.version_info < (3,), reason='HEAD request not supported by BaseHTTPRequestHandler in Py 2')
55
+ def test_head(self):
56
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/service', 'method': 'HEAD'},
57
+ {'status': '200'})]):
58
+ self.client.open(TESTSERVER_URL + '/service', method='HEAD')
59
+
60
+ def test_internal_error_response(self):
61
+ try:
62
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/'},
63
+ {'status': '500', 'body': b''})]):
64
+ self.client.open(TESTSERVER_URL + '/')
65
+ except HTTPClientError as e:
66
+ assert_re(e.args[0], r'HTTP Error ".*": 500')
67
+ else:
68
+ assert False, 'expected HTTPClientError'
69
+
70
+ def test_invalid_url_type(self):
71
+ try:
72
+ self.client.open('htp://example.org')
73
+ except HTTPClientError as e:
74
+ assert_re(e.args[0], r'No response .* "htp://example.*": unknown url type')
75
+ else:
76
+ assert False, 'expected HTTPClientError'
77
+
78
+ def test_invalid_url(self):
79
+ try:
80
+ self.client.open('this is not a url')
81
+ except HTTPClientError as e:
82
+ assert_re(e.args[0], r'URL not correct "this is not.*": unknown url type')
83
+ else:
84
+ assert False, 'expected HTTPClientError'
85
+
86
+ def test_unknown_host(self):
87
+ try:
88
+ self.client.open('http://thishostshouldnotexist000136really42.org')
89
+ except HTTPClientError as e:
90
+ assert_re(e.args[0], r'No response .* "http://thishost.*": .*')
91
+ else:
92
+ assert False, 'expected HTTPClientError'
93
+
94
+ def test_no_connect(self):
95
+ try:
96
+ self.client.open('http://localhost:53871')
97
+ except HTTPClientError as e:
98
+ assert_re(e.args[0], r'No response .* "http://localhost.*": Connection refused')
99
+ else:
100
+ assert False, 'expected HTTPClientError'
101
+
102
+ def test_internal_error_hide_error_details(self):
103
+ try:
104
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/'},
105
+ {'status': '500', 'body': b''})]):
106
+ HTTPClient(hide_error_details=True).open(TESTSERVER_URL + '/')
107
+ except HTTPClientError as e:
108
+ assert_re(e.args[0], r'HTTP Error \(see logs for URL and reason\).')
109
+ else:
110
+ assert False, 'expected HTTPClientError'
111
+
112
+ @pytest.mark.online
113
+ def test_https_untrusted_root(self):
114
+ self.client = HTTPClient('https://untrusted-root.badssl.com/')
115
+ try:
116
+ self.client.open('https://untrusted-root.badssl.com/')
117
+ except HTTPClientError as e:
118
+ assert_re(e.args[0], r'Could not verify connection to URL')
119
+
120
+ @pytest.mark.online
121
+ def test_https_insecure(self):
122
+ self.client = HTTPClient(
123
+ 'https://untrusted-root.badssl.com/', insecure=True)
124
+ self.client.open('https://untrusted-root.badssl.com/')
125
+
126
+ @pytest.mark.online
127
+ def test_https_valid_ca_cert_file(self):
128
+ # verify with fixed ca_certs file
129
+ cert_file = '/etc/ssl/certs/ca-certificates.crt'
130
+ if os.path.exists(cert_file):
131
+ self.client = HTTPClient('https://www.google.com/', ssl_ca_certs=cert_file)
132
+ self.client.open('https://www.google.com/')
133
+ else:
134
+ with TempFile() as tmp:
135
+ with open(tmp, 'wb') as f:
136
+ f.write(GOOGLE_ROOT_CERT)
137
+ self.client = HTTPClient('https://www.google.com/', ssl_ca_certs=tmp)
138
+ self.client.open('https://www.google.com/')
139
+
140
+ @pytest.mark.online
141
+ def test_https_valid_default_cert(self):
142
+ self.client = HTTPClient('https://www.google.com/')
143
+ self.client.open('https://www.google.com/')
144
+
145
+ @pytest.mark.online
146
+ def test_https_invalid_cert(self):
147
+ # load 'wrong' root cert
148
+ with TempFile() as tmp:
149
+ with open(tmp, 'wb') as f:
150
+ f.write(GOOGLE_ROOT_CERT)
151
+ self.client = HTTPClient(
152
+ 'https://untrusted-root.badssl.com/', ssl_ca_certs=tmp)
153
+ try:
154
+ self.client.open('https://untrusted-root.badssl.com/')
155
+ except HTTPClientError as e:
156
+ assert_re(e.args[0], r'Could not verify connection to URL')
157
+
158
+ def test_timeouts(self):
159
+ test_req = ({'path': '/', 'req_assert_function': lambda x: time.sleep(0.9) or True},
160
+ {'body': b'nothing'})
161
+
162
+ client1 = HTTPClient(timeout=0.1)
163
+ client2 = HTTPClient(timeout=0.5)
164
+ with mock_httpd(TESTSERVER_ADDRESS, [test_req]):
165
+ try:
166
+ start = time.time()
167
+ client1.open(TESTSERVER_URL + '/')
168
+ except HTTPClientError as ex:
169
+ assert 'timed out' in ex.args[0]
170
+ else:
171
+ assert False, 'HTTPClientError expected'
172
+ duration1 = time.time() - start
173
+
174
+ with mock_httpd(TESTSERVER_ADDRESS, [test_req]):
175
+ try:
176
+ start = time.time()
177
+ client2.open(TESTSERVER_URL + '/')
178
+ except HTTPClientError as ex:
179
+ assert 'timed out' in ex.args[0]
180
+ else:
181
+ assert False, 'HTTPClientError expected'
182
+ duration2 = time.time() - start
183
+
184
+ # check individual timeouts
185
+ assert 0.1 <= duration1 < 0.5, duration1
186
+ assert 0.5 <= duration2 < 0.9, duration2
187
+
188
+ def test_manage_cookies_off(self):
189
+ """
190
+ Test the behavior when manage_cookies is off (the default). Cookies shouldn't be sent
191
+ """
192
+ self.client = HTTPClient()
193
+
194
+ def assert_no_cookie(req_handler):
195
+ return 'Cookie' not in req_handler.headers
196
+
197
+ test_requests = [
198
+ (
199
+ {'path': '/', 'req_assert_function': assert_no_cookie},
200
+ {'body': b'nothing', 'headers': {'Set-Cookie': "testcookie=42"}}
201
+ ),
202
+ (
203
+ {'path': '/', 'req_assert_function': assert_no_cookie},
204
+ {'body': b'nothing'}
205
+ )
206
+ ]
207
+ with mock_httpd(TESTSERVER_ADDRESS, test_requests):
208
+ self.client.open(TESTSERVER_URL + '/')
209
+ self.client.open(TESTSERVER_URL + '/')
210
+
211
+ def test_manage_cookies_on(self):
212
+ """
213
+ Test behavior of manage_cookies=True. Once the remote server sends a cookie back, it should
214
+ be included in future requests
215
+ """
216
+ self.client = HTTPClient(manage_cookies=True)
217
+
218
+ def assert_no_cookie(req_handler):
219
+ return 'Cookie' not in req_handler.headers
220
+
221
+ def assert_cookie(req_handler):
222
+ assert 'Cookie' in req_handler.headers
223
+ cookie_name, cookie_val = req_handler.headers['Cookie'].split(';')[0].split('=')
224
+ assert cookie_name == 'testcookie'
225
+ assert cookie_val == '42'
226
+ return True
227
+
228
+ test_requests = [
229
+ (
230
+ {'path': '/', 'req_assert_function': assert_no_cookie},
231
+ {'body': b'nothing', 'headers': {'Set-Cookie': "testcookie=42"}}
232
+ ),
233
+ (
234
+ {'path': '/', 'req_assert_function': assert_cookie},
235
+ {'body': b'nothing'}
236
+ )
237
+ ]
238
+ with mock_httpd(TESTSERVER_ADDRESS, test_requests):
239
+ self.client.open(TESTSERVER_URL + '/')
240
+ self.client.open(TESTSERVER_URL + '/')
241
+
242
+
243
+ # root certificates for google.com, if no ca-certificates.cert
244
+ # file is found
245
+ GOOGLE_ROOT_CERT = b"""
246
+ -----BEGIN CERTIFICATE-----
247
+ MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
248
+ MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
249
+ YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
250
+ EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
251
+ R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
252
+ 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
253
+ fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
254
+ iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
255
+ 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
256
+ bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
257
+ MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
258
+ ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
259
+ uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
260
+ Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
261
+ tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
262
+ PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
263
+ hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
264
+ 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
265
+ -----END CERTIFICATE-----
266
+ -----BEGIN CERTIFICATE-----
267
+ MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
268
+ A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
269
+ Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
270
+ MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
271
+ A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
272
+ hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
273
+ v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
274
+ eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
275
+ tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
276
+ C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
277
+ zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
278
+ mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
279
+ V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
280
+ bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
281
+ 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
282
+ J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
283
+ 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
284
+ ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
285
+ AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
286
+ TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
287
+ -----END CERTIFICATE-----
288
+ -----BEGIN CERTIFICATE-----
289
+ MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
290
+ UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
291
+ dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
292
+ MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
293
+ dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
294
+ AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
295
+ BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
296
+ cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
297
+ AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
298
+ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
299
+ aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
300
+ ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
301
+ IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
302
+ MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
303
+ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
304
+ 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
305
+ 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
306
+ -----END CERTIFICATE-----
307
+ """
308
+
309
+
310
+ class TestTileClient(object):
311
+ def test_tc_path(self):
312
+ template = TileURLTemplate(TESTSERVER_URL + '/%(tc_path)s.png')
313
+ client = TileClient(template)
314
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/09/000/000/005/000/000/013.png'},
315
+ {'body': b'tile',
316
+ 'headers': {'content-type': 'image/png'}})]):
317
+ resp = client.get_tile((5, 13, 9)).source.read()
318
+ assert resp == b'tile'
319
+
320
+ def test_quadkey(self):
321
+ template = TileURLTemplate(TESTSERVER_URL + '/key=%(quadkey)s&format=%(format)s')
322
+ client = TileClient(template)
323
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/key=000002303&format=png'},
324
+ {'body': b'tile',
325
+ 'headers': {'content-type': 'image/png'}})]):
326
+ resp = client.get_tile((5, 13, 9)).source.read()
327
+ assert resp == b'tile'
328
+
329
+ def test_xyz(self):
330
+ template = TileURLTemplate(TESTSERVER_URL + '/x=%(x)s&y=%(y)s&z=%(z)s&format=%(format)s')
331
+ client = TileClient(template)
332
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/x=5&y=13&z=9&format=png'},
333
+ {'body': b'tile',
334
+ 'headers': {'content-type': 'image/png'}})]):
335
+ resp = client.get_tile((5, 13, 9)).source.read()
336
+ assert resp == b'tile'
337
+
338
+ def test_arcgiscache_path(self):
339
+ template = TileURLTemplate(TESTSERVER_URL + '/%(arcgiscache_path)s.png')
340
+ client = TileClient(template)
341
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/L09/R0000000d/C00000005.png'},
342
+ {'body': b'tile',
343
+ 'headers': {'content-type': 'image/png'}})]):
344
+ resp = client.get_tile((5, 13, 9)).source.read()
345
+ assert resp == b'tile'
346
+
347
+ def test_bbox(self):
348
+ grid = tile_grid(4326)
349
+ template = TileURLTemplate(TESTSERVER_URL + '/service?BBOX=%(bbox)s')
350
+ client = TileClient(template, grid=grid)
351
+ with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/service?BBOX=-180.00000000,0.00000000,-90.00000000,90.00000000'}, # noqa
352
+ {'body': b'tile',
353
+ 'headers': {'content-type': 'image/png'}})]):
354
+ resp = client.get_tile((0, 1, 2)).source.read()
355
+ assert resp == b'tile'
356
+
357
+
358
+ class TestWMSClient(object):
359
+ def test_no_image(self, caplog):
360
+ try:
361
+ with mock_httpd(TESTSERVER_ADDRESS, [({
362
+ 'path': '/service?map=foo&layers=foo&transparent=true&bbox=-200000,-200000,200000,200000&width=512&height=512&srs=EPSG%3A900913&format=image%2Fpng&request=GetMap&version=1.1.1&service=WMS&styles='}, # noqa
363
+ {'status': '200', 'body': b'x' * 1000, 'headers': {'content-type': 'application/foo'}, })]):
364
+ req = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=foo',
365
+ param={'layers': 'foo', 'transparent': 'true'})
366
+ query = MapQuery((-200000, -200000, 200000, 200000), (512, 512), SRS(900913), 'png')
367
+ WMSClient(req).retrieve(query, 'png')
368
+ except SourceError:
369
+ assert len(caplog.record_tuples) == 1
370
+ assert ("'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' [output truncated]" # noqa
371
+ in caplog.record_tuples[0][2])
372
+ else:
373
+ assert False, 'expected no image returned error'
374
+
375
+
376
+ class TestCombinedWMSClient(object):
377
+ def setup_method(self):
378
+ self.http = MockHTTPClient()
379
+
380
+ def test_combine(self):
381
+ req1 = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=foo',
382
+ param={'layers': 'foo', 'transparent': 'true'})
383
+ wms1 = WMSClient(req1, http_client=self.http)
384
+ req2 = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=foo',
385
+ param={'layers': 'bar', 'transparent': 'true'})
386
+ wms2 = WMSClient(req2, http_client=self.http)
387
+
388
+ req = MapQuery((-200000, -200000, 200000, 200000), (512, 512), SRS(900913), 'png')
389
+
390
+ combined = wms1.combined_client(wms2, req)
391
+ assert combined.request_template.params.layers == ['foo', 'bar']
392
+ assert combined.request_template.url == TESTSERVER_URL + '/service?map=foo'
393
+
394
+ def test_combine_different_url(self):
395
+ req1 = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=bar',
396
+ param={'layers': 'foo', 'transparent': 'true'})
397
+ wms1 = WMSClient(req1, http_client=self.http)
398
+ req2 = WMS111MapRequest(url=TESTSERVER_URL + '/service?map=foo',
399
+ param={'layers': 'bar', 'transparent': 'true'})
400
+ wms2 = WMSClient(req2, http_client=self.http)
401
+
402
+ req = MapQuery((-200000, -200000, 200000, 200000), (512, 512), SRS(900913), 'png')
403
+
404
+ combined = wms1.combined_client(wms2, req)
405
+ assert combined is None
406
+
407
+
408
+ class TestWMSInfoClient(object):
409
+ def test_transform_fi_request_supported_srs(self):
410
+ req = WMS111FeatureInfoRequest(url=TESTSERVER_URL + '/service?map=foo', param={'layers': 'foo'})
411
+ http = MockHTTPClient()
412
+ wms = WMSInfoClient(req, http_client=http, supported_srs=SupportedSRS([SRS(25832)]))
413
+ fi_req = InfoQuery((8, 50, 9, 51), (512, 512),
414
+ SRS(4326), (128, 64), 'text/plain')
415
+
416
+ wms.get_info(fi_req)
417
+
418
+ assert wms_query_eq(http.requested[0],
419
+ TESTSERVER_URL+'/service?map=foo&LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng'
420
+ '&REQUEST=GetFeatureInfo&SRS=EPSG%3A25832&info_format=text/plain'
421
+ '&query_layers=foo'
422
+ '&VERSION=1.1.1&WIDTH=512&HEIGHT=797&STYLES=&x=135&y=101'
423
+ '&BBOX=428333.552496,5538630.70275,500000.0,5650300.78652'), http.requested[0]
424
+
425
+ def test_transform_fi_request(self):
426
+ req = WMS111FeatureInfoRequest(
427
+ url=TESTSERVER_URL + '/service?map=foo', param={'layers': 'foo', 'srs': 'EPSG:25832'})
428
+ http = MockHTTPClient()
429
+ wms = WMSInfoClient(req, http_client=http)
430
+ fi_req = InfoQuery((8, 50, 9, 51), (512, 512),
431
+ SRS(4326), (128, 64), 'text/plain')
432
+
433
+ wms.get_info(fi_req)
434
+
435
+ assert wms_query_eq(http.requested[0],
436
+ TESTSERVER_URL+'/service?map=foo&LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng'
437
+ '&REQUEST=GetFeatureInfo&SRS=EPSG%3A25832&info_format=text/plain'
438
+ '&query_layers=foo'
439
+ '&VERSION=1.1.1&WIDTH=512&HEIGHT=797&STYLES=&x=135&y=101'
440
+ '&BBOX=428333.552496,5538630.70275,500000.0,5650300.78652'), http.requested[0]
441
+
442
+
443
+ class TestWMSMapRequest100(object):
444
+ def setup_method(self):
445
+ self.r = WMS100MapRequest(param=dict(layers='foo', version='1.1.1', request='GetMap'))
446
+ self.r.params = self.r.adapt_params_to_version()
447
+
448
+ def test_version(self):
449
+ assert self.r.params['WMTVER'] == '1.0.0'
450
+ assert 'VERSION' not in self.r.params
451
+
452
+ def test_service(self):
453
+ assert 'SERVICE' not in self.r.params
454
+
455
+ def test_request(self):
456
+ assert self.r.params['request'] == 'map'
457
+
458
+ def test_str(self):
459
+ assert_query_eq(str(self.r.params), 'layers=foo&styles=&request=map&wmtver=1.0.0')
460
+
461
+
462
+ class TestWMSMapRequest130(object):
463
+ def setup_method(self):
464
+ self.r = WMS130MapRequest(param=dict(layers='foo', WMTVER='1.0.0'))
465
+ self.r.params = self.r.adapt_params_to_version()
466
+
467
+ def test_version(self):
468
+ assert self.r.params['version'] == '1.3.0'
469
+ assert 'WMTVER' not in self.r.params
470
+
471
+ def test_service(self):
472
+ assert self.r.params['service'] == 'WMS'
473
+
474
+ def test_request(self):
475
+ assert self.r.params['request'] == 'GetMap'
476
+
477
+ def test_str(self):
478
+ query_eq(str(self.r.params), 'layers=foo&styles=&service=WMS&request=GetMap&version=1.3.0')
479
+
480
+
481
+ class TestWMSMapRequest111(object):
482
+ def setup_method(self):
483
+ self.r = WMS111MapRequest(param=dict(layers='foo', WMTVER='1.0.0'))
484
+ self.r.params = self.r.adapt_params_to_version()
485
+
486
+ def test_version(self):
487
+ assert self.r.params['version'] == '1.1.1'
488
+ assert 'WMTVER' not in self.r.params
@@ -0,0 +1,74 @@
1
+ # This file is part of the MapProxy project.
2
+ # Copyright (C) 2010 Omniscale <http://omniscale.de>
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ from io import BytesIO
17
+
18
+ from mapproxy.client.arcgis import ArcGISInfoClient
19
+ from mapproxy.layer import InfoQuery
20
+ from mapproxy.request.arcgis import ArcGISIdentifyRequest
21
+ from mapproxy.srs import SRS, SupportedSRS
22
+ from mapproxy.test.http import assert_query_eq
23
+
24
+
25
+ TESTSERVER_ADDRESS = ('127.0.0.1', 56413)
26
+ TESTSERVER_URL = 'http://%s:%s' % TESTSERVER_ADDRESS
27
+
28
+
29
+ class MockHTTPClient(object):
30
+ def __init__(self):
31
+ self.requested = []
32
+
33
+ def open(self, url, data=None):
34
+ self.requested.append(url)
35
+ result = BytesIO(b'{}')
36
+ result.seek(0)
37
+ result.headers = {}
38
+ return result
39
+
40
+
41
+ class TestArcGISInfoClient(object):
42
+ def test_fi_request(self):
43
+ req = ArcGISIdentifyRequest(url=TESTSERVER_URL + '/MapServer/export?map=foo', param={'layers': 'foo'})
44
+ http = MockHTTPClient()
45
+ wms = ArcGISInfoClient(req, http_client=http, supported_srs=SupportedSRS([SRS(4326)]))
46
+ fi_req = InfoQuery((8, 50, 9, 51), (512, 512),
47
+ SRS(4326), (128, 64), 'text/plain')
48
+
49
+ wms.get_info(fi_req)
50
+
51
+ assert_query_eq(http.requested[0],
52
+ TESTSERVER_URL+'/MapServer/identify?map=foo'
53
+ '&imageDisplay=512,512,96&sr=4326&f=json'
54
+ '&layers=foo&tolerance=5&returnGeometry=false'
55
+ '&geometryType=esriGeometryPoint&geometry=8.250000,50.875000'
56
+ '&mapExtent=8,50,9,51',
57
+ fuzzy_number_compare=True)
58
+
59
+ def test_transform_fi_request_supported_srs(self):
60
+ req = ArcGISIdentifyRequest(url=TESTSERVER_URL + '/MapServer/export?map=foo', param={'layers': 'foo'})
61
+ http = MockHTTPClient()
62
+ wms = ArcGISInfoClient(req, http_client=http, supported_srs=SupportedSRS([SRS(25832)]))
63
+ fi_req = InfoQuery((8, 50, 9, 51), (512, 512),
64
+ SRS(4326), (128, 64), 'text/plain')
65
+
66
+ wms.get_info(fi_req)
67
+
68
+ assert_query_eq(http.requested[0],
69
+ TESTSERVER_URL+'/MapServer/identify?map=foo'
70
+ '&imageDisplay=512,797,96&sr=25832&f=json'
71
+ '&layers=foo&tolerance=5&returnGeometry=false'
72
+ '&geometryType=esriGeometryPoint&geometry=447229.979084,5636149.370634'
73
+ '&mapExtent=428333.552496,5538630.70275,500000.0,5650300.78652',
74
+ fuzzy_number_compare=True)