2
2
3
3
4
4
import aiohttp .web
5
- # import asyncio
5
+ import asyncio
6
6
7
- from .common import get_auth_instance
7
+ from .common import get_auth_instance , get_upload_instance
8
+ from .common import parse_multipart_in
8
9
from .download import FileDownloadProxy , ContainerArchiveDownloadProxy
10
+ from .replicate import ObjectReplicationProxy
9
11
10
12
11
13
async def handle_get_object (
@@ -25,8 +27,8 @@ async def handle_get_object(
25
27
resp = aiohttp .web .StreamResponse ()
26
28
27
29
# 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 ())
30
32
31
33
await resp .prepare (request )
32
34
@@ -36,10 +38,134 @@ async def handle_get_object(
36
38
return resp
37
39
38
40
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
+
39
162
async def handle_get_container (
40
163
request : aiohttp .web .Request
41
164
) -> aiohttp .web .StreamResponse :
42
165
"""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
+
43
169
auth = get_auth_instance (request )
44
170
45
171
resp = aiohttp .web .StreamResponse ()
0 commit comments