Procházet zdrojové kódy

More robust regex handling of SPARQL query string to fix fragment URI parsing.

Stefano Cossu před 6 roky
rodič
revize
72692142ec

+ 1 - 3
lakesuperior/model/ldp_rs.py

@@ -46,9 +46,7 @@ class LdpRs(Ldpr):
 
         @param update_str (string) SPARQL-Update staements.
         '''
-        local_update_str = update_str.replace('<>', self.urn.n3()).replace(
-                g.webroot + '/', nsc['fcres']).replace(
-                g.webroot, nsc['fcres'])
+        local_update_str = g.tbox.localize_ext_str(update_str, self.urn)
         delta = self._sparql_delta(local_update_str)
         self._ensure_single_subject_rdf(delta[0] | delta[1])
 

+ 30 - 0
lakesuperior/toolbox.py

@@ -1,5 +1,6 @@
 import logging
 import pickle
+import re
 
 from collections import defaultdict
 from hashlib import sha1
@@ -115,6 +116,35 @@ class Toolbox:
         return gr
 
 
+    def localize_ext_str(self, s, urn):
+        '''
+        Convert global URIs to local in a SPARQL or RDF string.
+
+        Also replace empty URIs (`<>`) with a fixed local URN and take care
+        of fragments and relative URIs.
+
+        This is a 3-pass replacement. First, global URIs whose webroot matches
+        the application ones are replaced with local URNs. Then, relative URIs
+        are converted to absolute using the URN as the base; finally, the
+        root node is appropriately addressed.
+        '''
+        esc_webroot = g.webroot.replace('/', '\\/')
+        #loc_ptn = r'<({}\/?)?(.*?)?(\?.*?)?(#.*?)?>'.format(esc_webroot)
+        loc_ptn1 = r'<{}\/?(.*?)>'.format(esc_webroot)
+        loc_sub1 = '<{}\\1>'.format(nsc['fcres'])
+        s1 = re.sub(loc_ptn1, loc_sub1, s)
+
+        loc_ptn2 = r'<([#?].*?)?>'
+        loc_sub2 = '<{}\\1>'.format(urn)
+        s2 = re.sub(loc_ptn2, loc_sub2, s1)
+
+        loc_ptn3 = r'<{}([#?].*?)?>'.format(nsc['fcres'])
+        loc_sub3 = '<{}\\1>'.format(self.ROOT_NODE_URN)
+        s3 = re.sub(loc_ptn3, loc_sub3, s2)
+
+        return s3
+
+
     def globalize_string(self, s):
         '''Convert URNs into URIs in a string using the application base URI.
 

+ 7 - 2
tests/endpoints/test_ldp.py

@@ -59,8 +59,13 @@ class TestLdp:
         assert self.client.get(path).status_code == 200
 
         put2_resp = self.client.put(path)
+        with open('tests/data/marcel_duchamp_single_subject.ttl', 'rb') as f:
+            put2_resp = self.client.put(
+                    path, data=f, content_type='text/turtle')
         assert put2_resp.status_code == 204
-        assert put2_resp.data == b''
+
+        put2_resp = self.client.put(path)
+        assert put2_resp.status_code == 409
 
 
     def test_put_tree(self, client):
@@ -426,7 +431,7 @@ class TestPrefHeader:
         path = '/ldp/put_pref_header01'
         assert self.client.put(path).status_code == 201
         assert self.client.get(path).status_code == 200
-        assert self.client.put(path).status_code == 204
+        assert self.client.put(path).status_code == 409
         with open('tests/data/rdf_payload_w_srv_mgd_trp.ttl', 'rb') as f:
             rsp_len = self.client.put(
                 path,

+ 41 - 0
tests/test_toolbox.py

@@ -60,3 +60,44 @@ class TestToolbox:
         assert g.tbox.localize_term(g.webroot + '/test/uid') == \
                 g.tbox.localize_term(g.webroot + '/test/uid/') == \
                 nsc['fcres']['test/uid']
+
+
+    def test_localize_ext_str(self):
+        '''
+        Test extended string localization.
+        '''
+        input = '''
+        @prefix bogus: <http://bogs.r.us#>
+        @prefix ex: <{0}/ns#>
+
+        FREE GRATUITOUS {{
+          <#blah> a <{0}/type#A> .
+          <> <urn:ex:p> <xyz> .
+          <#c#r#a#zy> ex:virtue <?blah#e> .
+          <{0}> <{0}/go#lala>
+            <{0}/heythere/gulp> .
+        }} GARB AGE TOKENS {{
+          <{0}/hey?there#hoho> <https://goglyeyes.com#cearch>
+            <{0}#hehe> .
+          <{0}?there#haha> <urn:auth:blok> "Hi I'm a strong" .
+        }}
+        '''.format(g.webroot)
+        exp_output = '''
+        @prefix bogus: <http://bogs.r.us#>
+        @prefix ex: <urn:fcres:ns#>
+
+        FREE GRATUITOUS {
+          <urn:fcres:123#blah> a <urn:fcres:type#A> .
+          <urn:fcres:123> <urn:ex:p> <xyz> .
+          <urn:fcres:123#c#r#a#zy> ex:virtue <urn:fcres:123?blah#e> .
+          <urn:fcsystem:root> <urn:fcres:go#lala>
+            <urn:fcres:heythere/gulp> .
+        } GARB AGE TOKENS {
+          <urn:fcres:hey?there#hoho> <https://goglyeyes.com#cearch>
+            <urn:fcsystem:root#hehe> .
+          <urn:fcsystem:root?there#haha> <urn:auth:blok> "Hi I'm a strong" .
+        }
+        '''
+
+        assert g.tbox.localize_ext_str(
+                input, nsc['fcres']['123']) == exp_output