1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
"""
This example demonstrates how to use a custom global URL opener installed with `urllib.request.install_opener` to block access to URLs.
"""
from __future__ import annotations
import http.client
import logging
import os
import sys
from typing import Optional
from urllib.request import HTTPHandler, OpenerDirector, Request, install_opener
from rdflib import Graph
class SecuredHTTPHandler(HTTPHandler):
"""
A HTTP handler that blocks access to URLs that end with "blocked.jsonld".
"""
def http_open(self, req: Request) -> http.client.HTTPResponse:
"""
Block access to URLs that end with "blocked.jsonld".
Args:
req: The request to open.
Returns:
The response.
Raises:
PermissionError: If the URL ends with "blocked.jsonld".
"""
if req.get_full_url().endswith("blocked.jsonld"):
raise PermissionError("Permission denied for URL")
return super().http_open(req)
def main() -> None:
"""
The main code of the example.
The important steps are:
* Install a custom global URL opener that blocks some URLs.
* Attempt to parse a JSON-LD document that will result in a blocked URL being accessed.
* Verify that the URL opener blocked access to the URL.
"""
logging.basicConfig(
level=os.environ.get("PYTHON_LOGGING_LEVEL", logging.INFO),
stream=sys.stderr,
datefmt="%Y-%m-%dT%H:%M:%S",
format=(
"%(asctime)s.%(msecs)03d %(process)d %(thread)d %(levelno)03d:%(levelname)-8s "
"%(name)-12s %(module)s:%(lineno)s:%(funcName)s %(message)s"
),
)
opener = OpenerDirector()
opener.add_handler(SecuredHTTPHandler())
install_opener(opener)
graph = Graph()
# Attempt to parse a JSON-LD document that will result in the blocked URL
# being accessed.
error: Optional[PermissionError] = None
try:
graph.parse(
data=r"""{
"@context": "http://example.org/blocked.jsonld",
"@id": "example:subject",
"example:predicate": { "@id": "example:object" }
}""",
format="json-ld",
)
except PermissionError as caught:
logging.info("Permission denied: %s", caught)
error = caught
# `Graph.parse` would have resulted in a `PermissionError` being raised from
# the url opener.
assert isinstance(error, PermissionError)
assert error.args[0] == "Permission denied for URL"
if __name__ == "__main__":
main()
|