@@ -355,13 +355,15 @@ S3Error S3ObjectStore::Object::Init(const std::filesystem::path &p, uid_t uid,
355
355
356
356
// Do the backend operations with the users filesystem id
357
357
ScopedFsId scope (uid, gid, id);
358
- if (XrdPosix_Stat (p.c_str (), &buf) || S_ISDIR (buf. st_mode ) ) {
358
+ if (XrdPosix_Stat (p.c_str (), &buf)) {
359
359
S3::S3Handler::Logger ()->Log (S3::ERROR, " ObjectStore::Object::Init" ,
360
360
" no such object - object-path=%s owner(%u:%u)" ,
361
361
p.c_str (), uid, gid);
362
362
return S3Error::NoSuchKey;
363
363
}
364
364
365
+ // Flag directories
366
+ this ->directory = S_ISDIR (buf.st_mode );
365
367
std::vector<std::string> attrnames;
366
368
std::vector<char > attrlist;
367
369
auto attrlen = XrdPosix_Listxattr (p.c_str (), nullptr , 0 );
@@ -464,16 +466,21 @@ S3Error S3ObjectStore::GetObject(const S3Auth::Bucket &bucket,
464
466
S3Error S3ObjectStore::DeleteObject (const S3Auth::Bucket &bucket,
465
467
const std::string &key) {
466
468
std::string base, obj;
467
-
469
+ ScopedFsId scope (bucket. owner . uid , bucket. owner . gid , bucket. owner . id );
468
470
auto full_path = bucket.path / key;
469
471
S3::S3Handler::Logger ()->Log (S3::DEBUG, " ObjectStore::DeleteObject" ,
470
472
" object-path=%s" , full_path.c_str ());
471
473
472
474
if (XrdPosix_Unlink (full_path.c_str ())) {
473
- S3::S3Handler::Logger ()->Log (S3::ERROR, " ObjectStore::DeleteObject" ,
474
- " failed to delete object-path=%s" ,
475
- full_path.c_str ());
476
- return S3Error::NoSuchKey;
475
+ if (errno == EISDIR) {
476
+ if (XrdPosix_Rmdir (full_path.c_str ())) {
477
+ // TODO: error handling
478
+ S3::S3Handler::Logger ()->Log (S3::ERROR, " ObjectStore::DeleteObject" ,
479
+ " failed to delete object-path=%s" ,
480
+ full_path.c_str ());
481
+ return S3Error::NoSuchKey;
482
+ }
483
+ }
477
484
}
478
485
479
486
do {
@@ -564,7 +571,7 @@ S3Error S3ObjectStore::CopyObject(const S3Auth::Bucket &bucket,
564
571
auto final_path = bucket.path / key;
565
572
566
573
struct stat buf;
567
- if (!XrdPosix_Stat (final_path.c_str (), &buf) && S_ISDIR (buf. st_mode ) ) {
574
+ if (!XrdPosix_Stat (final_path.c_str (), &buf)) {
568
575
S3::S3Handler::Logger ()->Log (
569
576
S3::ERROR, " ObjectStore::CopyObject" ,
570
577
" target:%s is directory => bucket:%s key:%s src=:%s" ,
@@ -576,6 +583,11 @@ S3Error S3ObjectStore::CopyObject(const S3Auth::Bucket &bucket,
576
583
bucket.path / (" ." + key + " ." + std::to_string (std::time (nullptr )) +
577
584
std::to_string (std::rand ()));
578
585
586
+ if (reqheaders.count (" x-amz-metadata-directive" ) && reqheaders.at (" x-amz-metadata-directive" ) == " REPLACE" ) {
587
+ // do the meta-data replacement
588
+ return S3Error::None;
589
+ }
590
+
579
591
auto err = S3Utils::makePath ((char *)final_path.parent_path ().c_str (),
580
592
S_IRWXU | S_IRWXG);
581
593
@@ -1149,6 +1161,26 @@ S3Error S3ObjectStore::PutObject(XrdS3Req &req, const S3Auth::Bucket &bucket,
1149
1161
return S3Error::ObjectExistAsDir;
1150
1162
}
1151
1163
1164
+ // special treatment for 'non-standard' directory creation
1165
+ auto it = headers.find (" content-type" );
1166
+ if (it != headers.end () && it->second == " application/x-directory" ) {
1167
+ // this is a 'virtual 'directory creation request
1168
+ auto err = S3Utils::makePath ((char *)final_path.c_str (),
1169
+ S_IRWXU | S_IRGRP);
1170
+ if (err == ENOTDIR) {
1171
+ S3::S3Handler::Logger ()->Log (S3::ERROR, " ObjectStore::PutObject" ,
1172
+ " object exists in object path - path:%s" ,
1173
+ final_path.c_str ());
1174
+ return S3Error::ObjectExistInObjectPath;
1175
+ } else if (err != 0 ) {
1176
+ S3::S3Handler::Logger ()->Log (S3::ERROR, " ObjectStore::PutObject" ,
1177
+ " internal error makeing parent : path:%s" ,
1178
+ final_path.c_str ());
1179
+ return S3Error::InternalError;
1180
+ }
1181
+ return S3Error::None;
1182
+ }
1183
+
1152
1184
auto tmp_path =
1153
1185
final_path.parent_path () /
1154
1186
(" ." + final_path.filename ().string () + " ." +
@@ -1375,6 +1407,7 @@ ListObjectsInfo S3ObjectStore::ListObjectsCommon(
1375
1407
std::vector<S3Utils::BasicPath> ent;
1376
1408
std::deque<S3Utils::BasicPath> entries;
1377
1409
1410
+ ScopedFsId scope (bucket.owner .uid , bucket.owner .gid , bucket.owner .id );
1378
1411
int n;
1379
1412
// get full listing
1380
1413
if ((n = S3Utils::ScanDir ((fullpath/basedir), basedir, ent)) <= 0 ) {
0 commit comments