@@ -1063,6 +1063,204 @@ module(basename(__filename), function () {
10631063 } ) ;
10641064 } ) ;
10651065 } ) ;
1066+
1067+ module ( 'binary file POST request' , function ( _hooks ) {
1068+ module ( 'public writable realm' , function ( hooks ) {
1069+ setupPermissionedRealmAtURL ( hooks , realmURL , {
1070+ permissions : {
1071+ '*' : [ 'read' , 'write' ] ,
1072+ } ,
1073+ onRealmSetup,
1074+ } ) ;
1075+
1076+ let { getMessagesSince } = setupMatrixRoom ( hooks , getRealmSetup ) ;
1077+
1078+ test ( 'serves a binary file POST request' , async function ( assert ) {
1079+ let bytes = new Uint8Array ( [
1080+ 0x89 , 0x50 , 0x4e , 0x47 , 0x0d , 0x0a , 0x1a , 0x0a , 0xff , 0xfe ,
1081+ ] ) ;
1082+ let response = await request
1083+ . post ( '/test-image.png' )
1084+ . set ( 'Accept' , 'application/octet-stream' )
1085+ . set ( 'Content-Type' , 'application/octet-stream' )
1086+ . send ( Buffer . from ( bytes ) ) ;
1087+
1088+ assert . strictEqual ( response . status , 204 , 'HTTP 204 status' ) ;
1089+ assert . ok (
1090+ response . headers [ 'x-created' ] ,
1091+ 'created date should be set for new binary file' ,
1092+ ) ;
1093+
1094+ let filePath = join (
1095+ dir . name ,
1096+ 'realm_server_1' ,
1097+ 'test' ,
1098+ 'test-image.png' ,
1099+ ) ;
1100+ assert . ok ( existsSync ( filePath ) , 'binary file exists on disk' ) ;
1101+ let fileBytes = readFileSync ( filePath ) ;
1102+ assert . deepEqual (
1103+ new Uint8Array ( fileBytes ) ,
1104+ bytes ,
1105+ 'file bytes match uploaded bytes' ,
1106+ ) ;
1107+ } ) ;
1108+
1109+ test ( 'creates file metadata for binary upload' , async function ( assert ) {
1110+ let bytes = new Uint8Array ( [ 0x00 , 0x01 , 0x02 , 0x03 ] ) ;
1111+ await request
1112+ . post ( '/meta-test.bin' )
1113+ . set ( 'Accept' , 'application/octet-stream' )
1114+ . set ( 'Content-Type' , 'application/octet-stream' )
1115+ . send ( Buffer . from ( bytes ) ) ;
1116+
1117+ let rows = await query ( dbAdapter , [
1118+ 'SELECT content_hash FROM realm_file_meta WHERE realm_url =' ,
1119+ param ( testRealmHref ) ,
1120+ 'AND file_path =' ,
1121+ param ( 'meta-test.bin' ) ,
1122+ ] ) ;
1123+ assert . strictEqual ( rows . length , 1 , 'file meta row exists' ) ;
1124+ assert . ok ( rows [ 0 ] . content_hash , 'content hash is set' ) ;
1125+ } ) ;
1126+
1127+ test ( 'overwrites existing binary file' , async function ( assert ) {
1128+ let bytes1 = new Uint8Array ( [ 0x01 , 0x02 , 0x03 ] ) ;
1129+ let bytes2 = new Uint8Array ( [ 0x04 , 0x05 , 0x06 ] ) ;
1130+
1131+ let response1 = await request
1132+ . post ( '/overwrite-test.bin' )
1133+ . set ( 'Accept' , 'application/octet-stream' )
1134+ . set ( 'Content-Type' , 'application/octet-stream' )
1135+ . send ( Buffer . from ( bytes1 ) ) ;
1136+ assert . strictEqual (
1137+ response1 . status ,
1138+ 204 ,
1139+ 'first upload returns 204' ,
1140+ ) ;
1141+
1142+ let response2 = await request
1143+ . post ( '/overwrite-test.bin' )
1144+ . set ( 'Accept' , 'application/octet-stream' )
1145+ . set ( 'Content-Type' , 'application/octet-stream' )
1146+ . send ( Buffer . from ( bytes2 ) ) ;
1147+ assert . strictEqual (
1148+ response2 . status ,
1149+ 204 ,
1150+ 'second upload returns 204' ,
1151+ ) ;
1152+
1153+ let filePath = join (
1154+ dir . name ,
1155+ 'realm_server_1' ,
1156+ 'test' ,
1157+ 'overwrite-test.bin' ,
1158+ ) ;
1159+ let fileBytes = readFileSync ( filePath ) ;
1160+ assert . deepEqual (
1161+ new Uint8Array ( fileBytes ) ,
1162+ bytes2 ,
1163+ 'file contains second upload bytes' ,
1164+ ) ;
1165+ } ) ;
1166+
1167+ test ( 'broadcasts realm events for binary upload' , async function ( assert ) {
1168+ let realmEventTimestampStart = Date . now ( ) ;
1169+
1170+ await request
1171+ . post ( '/event-test.bin' )
1172+ . set ( 'Accept' , 'application/octet-stream' )
1173+ . set ( 'Content-Type' , 'application/octet-stream' )
1174+ . send ( Buffer . from ( new Uint8Array ( [ 0xca , 0xfe ] ) ) ) ;
1175+
1176+ await expectIncrementalIndexEvent (
1177+ `${ testRealmURL } event-test.bin` ,
1178+ realmEventTimestampStart ,
1179+ {
1180+ assert,
1181+ getMessagesSince,
1182+ realm : testRealmHref ,
1183+ } ,
1184+ ) ;
1185+ } ) ;
1186+ } ) ;
1187+
1188+ module (
1189+ 'public writable realm with size limit for binary' ,
1190+ function ( hooks ) {
1191+ setupPermissionedRealmAtURL ( hooks , realmURL , {
1192+ permissions : {
1193+ '*' : [ 'read' , 'write' ] ,
1194+ } ,
1195+ cardSizeLimitBytes : 512 ,
1196+ onRealmSetup,
1197+ } ) ;
1198+
1199+ test ( 'returns 413 when binary payload exceeds size limit' , async function ( assert ) {
1200+ let oversized = new Uint8Array ( 2048 ) . fill ( 0xff ) ;
1201+ let response = await request
1202+ . post ( '/too-large.bin' )
1203+ . set ( 'Accept' , 'application/octet-stream' )
1204+ . set ( 'Content-Type' , 'application/octet-stream' )
1205+ . send ( Buffer . from ( oversized ) ) ;
1206+
1207+ assert . strictEqual ( response . status , 413 , 'HTTP 413 status' ) ;
1208+ assert . strictEqual (
1209+ response . body . errors [ 0 ] . title ,
1210+ 'Payload Too Large' ,
1211+ 'error title is correct' ,
1212+ ) ;
1213+ } ) ;
1214+ } ,
1215+ ) ;
1216+
1217+ module ( 'permissioned realm for binary' , function ( hooks ) {
1218+ setupPermissionedRealmAtURL ( hooks , realmURL , {
1219+ permissions : {
1220+ john : [ 'read' , 'write' ] ,
1221+ } ,
1222+ onRealmSetup,
1223+ } ) ;
1224+
1225+ test ( '401 without a JWT for binary upload' , async function ( assert ) {
1226+ let response = await request
1227+ . post ( '/secret.bin' )
1228+ . set ( 'Accept' , 'application/octet-stream' )
1229+ . set ( 'Content-Type' , 'application/octet-stream' )
1230+ . send ( Buffer . from ( new Uint8Array ( [ 0x01 ] ) ) ) ;
1231+
1232+ assert . strictEqual ( response . status , 401 , 'HTTP 401 status' ) ;
1233+ } ) ;
1234+
1235+ test ( '403 without permission for binary upload' , async function ( assert ) {
1236+ let response = await request
1237+ . post ( '/secret.bin' )
1238+ . set ( 'Accept' , 'application/octet-stream' )
1239+ . set ( 'Content-Type' , 'application/octet-stream' )
1240+ . send ( Buffer . from ( new Uint8Array ( [ 0x01 ] ) ) )
1241+ . set (
1242+ 'Authorization' ,
1243+ `Bearer ${ createJWT ( testRealm , 'not-john' ) } ` ,
1244+ ) ;
1245+
1246+ assert . strictEqual ( response . status , 403 , 'HTTP 403 status' ) ;
1247+ } ) ;
1248+
1249+ test ( '204 with permission for binary upload' , async function ( assert ) {
1250+ let response = await request
1251+ . post ( '/secret.bin' )
1252+ . set ( 'Accept' , 'application/octet-stream' )
1253+ . set ( 'Content-Type' , 'application/octet-stream' )
1254+ . send ( Buffer . from ( new Uint8Array ( [ 0x01 ] ) ) )
1255+ . set (
1256+ 'Authorization' ,
1257+ `Bearer ${ createJWT ( testRealm , 'john' , [ 'read' , 'write' ] ) } ` ,
1258+ ) ;
1259+
1260+ assert . strictEqual ( response . status , 204 , 'HTTP 204 status' ) ;
1261+ } ) ;
1262+ } ) ;
1263+ } ) ;
10661264 } ) ;
10671265} ) ;
10681266
0 commit comments