22
33
44import aiohttp .web
5- # import asyncio
5+ import asyncio
66
7- from .common import get_auth_instance
7+ from .common import get_auth_instance , get_upload_instance
8+ from .common import parse_multipart_in
89from .download import FileDownloadProxy , ContainerArchiveDownloadProxy
10+ from .replicate import ObjectReplicationProxy
911
1012
1113async def handle_get_object (
@@ -25,8 +27,8 @@ async def handle_get_object(
2527 resp = aiohttp .web .StreamResponse ()
2628
2729 # Create headers
28- resp .headers ["Content-Type" ] = download .get_type ()
29- resp .headers ["Content-Length" ] = str (download .get_size ())
30+ resp .headers ["Content-Type" ] = await download .a_get_type ()
31+ resp .headers ["Content-Length" ] = str (await download .a_get_size ())
3032
3133 await resp .prepare (request )
3234
@@ -36,10 +38,134 @@ async def handle_get_object(
3638 return resp
3739
3840
41+ async def handle_replicate_container (
42+ request : aiohttp .web .Request
43+ ) -> aiohttp .web .Response :
44+ """Handle request to replicating a container from a source."""
45+ auth = get_auth_instance (request )
46+
47+ project = request .match_info ["project" ]
48+ container = request .match_info ["container" ]
49+
50+ source_project = request .query ["from_project" ]
51+ source_container = request .query ["from_container" ]
52+
53+ replicator = ObjectReplicationProxy (
54+ auth ,
55+ request .app ["client" ],
56+ project ,
57+ container ,
58+ source_project ,
59+ source_container
60+ )
61+
62+ asyncio .ensure_future (replicator .a_copy_from_container ())
63+
64+ return aiohttp .web .Response (status = 202 )
65+
66+
67+ async def handle_replicate_object (
68+ request : aiohttp .web .Request
69+ ) -> aiohttp .web .Response :
70+ """Handle a request to replicating an object from a source."""
71+ auth = get_auth_instance (request )
72+
73+ project = request .match_info ["project" ]
74+ container = request .match_info ["container" ]
75+
76+ source_project = request .query ["from_project" ]
77+ source_container = request .query ["from_container" ]
78+ source_object = request .query ["from_object" ]
79+
80+ replicator = ObjectReplicationProxy (
81+ auth ,
82+ request .app ["client" ],
83+ project ,
84+ container ,
85+ source_project ,
86+ source_container
87+ )
88+
89+ asyncio .ensure_future (replicator .a_copy_object (source_object ))
90+
91+ return aiohttp .web .Response (status = 202 )
92+
93+
94+ async def handle_post_object_chunk (
95+ request : aiohttp .web .Request
96+ ) -> aiohttp .web .Response :
97+ """Handle a request for posting an object chunk."""
98+ if "from_object" in request .query .keys ():
99+ return await handle_replicate_object (request )
100+ if "from_container" in request .query .keys ():
101+ return await handle_replicate_container (request )
102+
103+ project = request .match_info ["project" ]
104+ container = request .match_info ["container" ]
105+
106+ query , data = await parse_multipart_in (request )
107+
108+ upload_session = await get_upload_instance (
109+ request ,
110+ project ,
111+ container ,
112+ p_query = query
113+ )
114+
115+ return await upload_session .a_add_chunk (
116+ query ,
117+ data
118+ )
119+
120+
121+ async def handle_get_object_chunk (
122+ request : aiohttp .web .Request
123+ ) -> aiohttp .web .Response :
124+ """Handle a request for checking if a chunk exists."""
125+ get_auth_instance (request )
126+
127+ project = request .match_info ["project" ]
128+ container = request .match_info ["container" ]
129+
130+ try :
131+ # Infuriatingly resumable.js starts counting chunks from 1
132+ # thus, reducing said 1 from the resulting chunk number
133+ chunk_number = int (request .query ["resumableChunkNumber" ]) - 1
134+ except KeyError :
135+ raise aiohttp .web .HTTPBadRequest (reason = "Malformed query string" )
136+
137+ upload_session = await get_upload_instance (
138+ request ,
139+ project ,
140+ container
141+ )
142+
143+ return await upload_session .a_check_segment (
144+ chunk_number
145+ )
146+
147+
148+ async def handle_post_object_options (
149+ request : aiohttp .web .Request
150+ ) -> aiohttp .web .Response :
151+ """Handle options request for posting the object chunk."""
152+ resp = aiohttp .web .Response (
153+ headers = {
154+ "Access-Control-Allow-Methods" : "POST, OPTIONS, GET" ,
155+ "Access-Control-Max-Age" : "84600" ,
156+ }
157+ )
158+
159+ return resp
160+
161+
39162async def handle_get_container (
40163 request : aiohttp .web .Request
41164) -> aiohttp .web .StreamResponse :
42165 """Handle a request for getting container contents as an archive."""
166+ if "resumableChunkNumber" in request .query .keys ():
167+ return await handle_get_object_chunk (request )
168+
43169 auth = get_auth_instance (request )
44170
45171 resp = aiohttp .web .StreamResponse ()
0 commit comments