1919import org .apache .logging .log4j .Logger ;
2020import org .apache .logging .log4j .LogManager ;
2121
22- import com .genexus .CommonUtil ;
22+ import com .genexus .Application ;
2323import com .genexus .util .GXService ;
2424import com .genexus .util .StorageUtils ;
2525import com .genexus .StructSdtMessages_Message ;
@@ -404,6 +404,62 @@ public String copy(String objectUrl, String newName, String tableName, String fi
404404 return getResourceUrl (resourceKey , acl , defaultExpirationMinutes );
405405 }
406406
407+ private String getContentType (String fileName ) {
408+ Path path = Paths .get (fileName );
409+ String defaultContentType = "application/octet-stream" ;
410+
411+ try {
412+ String probedContentType = Files .probeContentType (path );
413+ if (probedContentType == null || probedContentType .equals (defaultContentType ))
414+ return findContentTypeByExtension (fileName );
415+ return probedContentType ;
416+ } catch (IOException ioe ) {
417+ return findContentTypeByExtension (fileName );
418+ }
419+ }
420+
421+ private String findContentTypeByExtension (String fileName ) {
422+ String fileExtension = fileName .substring (fileName .lastIndexOf ("." ) + 1 ).toLowerCase ();
423+ String contentType = contentTypes .get (fileExtension );
424+ return contentType != null ? contentTypes .get (fileExtension ) : "application/octet-stream" ;
425+ }
426+
427+ private static Map <String , String > contentTypes = new HashMap <String , String >() {{
428+ put ("txt" , "text/plain" );
429+ put ("rtx" , "text/richtext" );
430+ put ("htm" , "text/html" );
431+ put ("html" , "text/html" );
432+ put ("xml" , "text/xml" );
433+ put ("aif" , "audio/x-aiff" );
434+ put ("au" , "audio/basic" );
435+ put ("wav" , "audio/wav" );
436+ put ("bmp" , "image/bmp" );
437+ put ("gif" , "image/gif" );
438+ put ("jpe" , "image/jpeg" );
439+ put ("jpeg" , "image/jpeg" );
440+ put ("jpg" , "image/jpeg" );
441+ put ("jfif" , "image/pjpeg" );
442+ put ("tif" , "image/tiff" );
443+ put ("tiff" , "image/tiff" );
444+ put ("png" , "image/x-png" );
445+ put ("3gp" , "video/3gpp" );
446+ put ("3g2" , "video/3gpp2" );
447+ put ("mpg" , "video/mpeg" );
448+ put ("mpeg" , "video/mpeg" );
449+ put ("mov" , "video/quicktime" );
450+ put ("qt" , "video/quicktime" );
451+ put ("avi" , "video/x-msvideo" );
452+ put ("exe" , "application/octet-stream" );
453+ put ("dll" , "application/x-msdownload" );
454+ put ("ps" , "application/postscript" );
455+ put ("pdf" , "application/pdf" );
456+ put ("svg" , "image/svg+xml" );
457+ put ("tgz" , "application/x-compressed" );
458+ put ("zip" , "application/x-zip-compressed" );
459+ put ("gz" , "application/x-gzip" );
460+ put ("json" , "application/json" );
461+ }};
462+
407463 private String buildPath (String ... pathPart ) {
408464 ArrayList <String > pathParts = new ArrayList <>();
409465 for (String part : pathPart ) {
@@ -626,263 +682,6 @@ private String getStorageUriWithoutRegion() {
626682 "https://" + bucket + ".s3.amazonaws.com/" :
627683 ".s3.amazonaws.com//" + bucket + "/" ;
628684 }
629-
630- // With ACL implementation
631-
632- private String uploadWithACL (String localFile , String externalFileName , ResourceAccessControlList acl ) {
633- client .putObject (PutObjectRequest .builder ()
634- .bucket (bucket )
635- .key (externalFileName )
636- .build (),
637- RequestBody .fromFile (Paths .get (localFile )));
638- if (endpointUrl .contains (".amazonaws.com" ))
639- client .putObjectAcl (PutObjectAclRequest .builder ()
640- .bucket (bucket )
641- .key (externalFileName )
642- .acl (internalToAWSACLWithACL (acl ))
643- .build ());
644- return getResourceUrl (externalFileName , acl , defaultExpirationMinutes );
645- }
646-
647- private ObjectCannedACL internalToAWSACLWithACL (ResourceAccessControlList acl ) {
648- if (acl == ResourceAccessControlList .Default )
649- acl = this .defaultAcl ;
650-
651- ObjectCannedACL accessControl = ObjectCannedACL .PRIVATE ;
652- if (acl == ResourceAccessControlList .Private )
653- accessControl = ObjectCannedACL .PRIVATE ;
654- else if (acl == ResourceAccessControlList .PublicRead )
655- accessControl = ObjectCannedACL .PUBLIC_READ ;
656- else if (acl == ResourceAccessControlList .PublicReadWrite )
657- accessControl = ObjectCannedACL .PUBLIC_READ_WRITE ;
658- return accessControl ;
659- }
660-
661- private String uploadWithACL (String externalFileName , InputStream input , ResourceAccessControlList acl ) {
662- try {
663- ByteBuffer byteBuffer = ByteBuffer .wrap (IoUtils .toByteArray (input ));
664- PutObjectRequest .Builder putObjectRequestBuilder = PutObjectRequest .builder ()
665- .bucket (bucket )
666- .key (externalFileName )
667- .contentType (externalFileName .endsWith (".tmp" ) ? "image/jpeg" : null );
668- if (endpointUrl .contains (".amazonaws.com" ))
669- putObjectRequestBuilder = putObjectRequestBuilder .acl (internalToAWSACLWithACL (acl ));
670- PutObjectRequest putObjectRequest = putObjectRequestBuilder .build ();
671-
672- PutObjectResponse response = client .putObject (putObjectRequest , RequestBody .fromByteBuffer (byteBuffer ));
673- if (!response .sdkHttpResponse ().isSuccessful ()) {
674- logger .error ("Error while uploading file: " + response .sdkHttpResponse ().statusText ().orElse ("Unknown error" ));
675- }
676-
677- return getResourceUrl (externalFileName , acl , defaultExpirationMinutes );
678- } catch (IOException ex ) {
679- logger .error ("Error while uploading file to the external provider." , ex );
680- return "" ;
681- }
682- }
683-
684- private String getResourceUrlWithACL (String externalFileName , ResourceAccessControlList acl , int expirationMinutes ) {
685- if (internalToAWSACLWithACL (acl ) == ObjectCannedACL .PRIVATE ) {
686- expirationMinutes = expirationMinutes > 0 ? expirationMinutes : defaultExpirationMinutes ;
687- Instant expiration = Instant .now ().plus (Duration .ofMinutes (expirationMinutes ));
688-
689- GetObjectRequest getObjectRequest = GetObjectRequest .builder ()
690- .bucket (bucket )
691- .key (externalFileName )
692- .build ();
693-
694- PresignedGetObjectRequest presignedGetObjectRequest =
695- presigner .presignGetObject (r -> r .signatureDuration (Duration .between (Instant .now (), expiration ))
696- .getObjectRequest (getObjectRequest ));
697-
698- return presignedGetObjectRequest .url ().toString ();
699- } else {
700- try {
701- int lastIndex = Math .max (externalFileName .lastIndexOf ('/' ), externalFileName .lastIndexOf ('\\' ));
702- String path = externalFileName .substring (0 , lastIndex + 1 );
703- String fileName = externalFileName .substring (lastIndex + 1 );
704- String encodedFileName = URLEncoder .encode (fileName , StandardCharsets .UTF_8 .toString ());
705-
706- String url = String .format (
707- "https://%s.s3.%s.amazonaws.com/%s%s" ,
708- bucket ,
709- clientRegion ,
710- path ,
711- encodedFileName
712- );
713-
714- return url ;
715- } catch (UnsupportedEncodingException uee ) {
716- logger .error ("Failed to encode resource URL for " + externalFileName , uee );
717- return "" ;
718- }
719- }
720- }
721-
722- private String copyWithACL (String objectName , String newName , ResourceAccessControlList acl ) {
723- CopyObjectRequest .Builder requestBuilder = CopyObjectRequest .builder ()
724- .sourceBucket (bucket )
725- .sourceKey (objectName )
726- .destinationBucket (bucket )
727- .destinationKey (newName );
728- if (endpointUrl .contains (".amazonaws.com" ))
729- requestBuilder = requestBuilder .acl (internalToAWSACLWithACL (acl ));
730- CopyObjectRequest request = requestBuilder .build ();
731- client .copyObject (request );
732- return getResourceUrl (newName , acl , defaultExpirationMinutes );
733- }
734-
735- private String copyWithACL (String objectUrl , String newName , String tableName , String fieldName , ResourceAccessControlList acl ) {
736- String resourceFolderName = buildPath (folder , tableName , fieldName );
737- String resourceKey = resourceFolderName + StorageUtils .DELIMITER + newName ;
738-
739- try {
740- objectUrl = new URI (objectUrl ).getPath ();
741- } catch (Exception e ) {
742- logger .error ("Failed to Parse Storage Object URI for Copy operation" , e );
743- }
744-
745- Map <String , String > metadata = new HashMap <>();
746- metadata .put ("Table" , tableName );
747- metadata .put ("Field" , fieldName );
748- metadata .put ("KeyValue" , StorageUtils .encodeNonAsciiCharacters (resourceKey ));
749-
750- GetObjectRequest getObjectRequest = GetObjectRequest .builder ()
751- .bucket (bucket )
752- .key (objectUrl )
753- .build ();
754- ResponseBytes <GetObjectResponse > objectBytes = client .getObjectAsBytes (getObjectRequest );
755-
756- PutObjectRequest .Builder putObjectRequestBuilder = PutObjectRequest .builder ()
757- .bucket (bucket )
758- .key (resourceKey )
759- .metadata (metadata )
760- .contentType (CommonUtil .getContentType (newName ));
761- if (endpointUrl .contains (".amazonaws.com" ))
762- putObjectRequestBuilder = putObjectRequestBuilder .acl (internalToAWSACLWithACL (acl ));
763- PutObjectRequest putObjectRequest = putObjectRequestBuilder .build ();
764- client .putObject (putObjectRequest , RequestBody .fromBytes (objectBytes .asByteArray ()));
765-
766- return getResourceUrl (resourceKey , acl , defaultExpirationMinutes );
767- }
768-
769- // Without ACL implementation
770-
771- private enum BucketPrivacy {PRIVATE , PUBLIC };
772- private final BucketPrivacy ownerEnforcedBucketPrivacy = getPropertyValue (DEFAULT_ACL , DEFAULT_STORAGE_PRIVACY , "" ).contains (bucketOwnerEnforced ) ?
773- (getPropertyValue (DEFAULT_ACL , DEFAULT_STORAGE_PRIVACY , "" ).contains ("private" ) ? BucketPrivacy .PRIVATE : BucketPrivacy .PUBLIC )
774- : null ;
775-
776- private String uploadWithoutACL (String localFile , String externalFileName ) {
777- client .putObject (PutObjectRequest .builder ()
778- .bucket (bucket )
779- .key (externalFileName )
780- .build (),
781- RequestBody .fromFile (Paths .get (localFile )));
782- return getResourceUrlWithoutACL (externalFileName , defaultExpirationMinutes );
783- }
784-
785- private String uploadWithoutACL (String externalFileName , InputStream input ) {
786- try {
787- ByteBuffer byteBuffer = ByteBuffer .wrap (IoUtils .toByteArray (input ));
788- PutObjectRequest .Builder putObjectRequestBuilder = PutObjectRequest .builder ()
789- .bucket (bucket )
790- .key (externalFileName )
791- .contentType (externalFileName .endsWith (".tmp" ) ? "image/jpeg" : null );
792- PutObjectRequest putObjectRequest = putObjectRequestBuilder .build ();
793-
794- PutObjectResponse response = client .putObject (putObjectRequest , RequestBody .fromByteBuffer (byteBuffer ));
795- if (!response .sdkHttpResponse ().isSuccessful ()) {
796- logger .error ("Error while uploading file: " + response .sdkHttpResponse ().statusText ().orElse ("Unknown error" ));
797- }
798-
799- return getResourceUrlWithoutACL (externalFileName , defaultExpirationMinutes );
800- } catch (IOException ex ) {
801- logger .error ("Error while uploading file to the external provider." , ex );
802- return "" ;
803- }
804- }
805-
806- private String getResourceUrlWithoutACL (String externalFileName , int expirationMinutes ) {
807- if (ownerEnforcedBucketPrivacy == BucketPrivacy .PRIVATE ) {
808- expirationMinutes = expirationMinutes > 0 ? expirationMinutes : defaultExpirationMinutes ;
809- Instant expiration = Instant .now ().plus (Duration .ofMinutes (expirationMinutes ));
810-
811- GetObjectRequest getObjectRequest = GetObjectRequest .builder ()
812- .bucket (bucket )
813- .key (externalFileName )
814- .build ();
815-
816- PresignedGetObjectRequest presignedGetObjectRequest =
817- presigner .presignGetObject (r -> r .signatureDuration (Duration .between (Instant .now (), expiration ))
818- .getObjectRequest (getObjectRequest ));
819-
820- return presignedGetObjectRequest .url ().toString ();
821- } else if (ownerEnforcedBucketPrivacy == BucketPrivacy .PUBLIC ){
822- try {
823- int lastIndex = Math .max (externalFileName .lastIndexOf ('/' ), externalFileName .lastIndexOf ('\\' ));
824- String path = externalFileName .substring (0 , lastIndex + 1 );
825- String fileName = externalFileName .substring (lastIndex + 1 );
826- String encodedFileName = URLEncoder .encode (fileName , StandardCharsets .UTF_8 .toString ());
827-
828- String url = String .format (
829- "https://%s.s3.%s.amazonaws.com/%s%s" ,
830- bucket ,
831- clientRegion ,
832- path ,
833- encodedFileName
834- );
835-
836- return url ;
837- } catch (UnsupportedEncodingException uee ) {
838- logger .error ("Failed to encode resource URL for {}" , externalFileName , uee );
839- return "" ;
840- }
841- } else return "" ;
842- }
843-
844- private String copyWithoutACL (String objectName , String newName ) {
845- CopyObjectRequest .Builder requestBuilder = CopyObjectRequest .builder ()
846- .sourceBucket (bucket )
847- .sourceKey (objectName )
848- .destinationBucket (bucket )
849- .destinationKey (newName );
850- CopyObjectRequest request = requestBuilder .build ();
851- client .copyObject (request );
852- return getResourceUrlWithoutACL (newName , defaultExpirationMinutes );
853- }
854-
855- private String copyWithoutACL (String objectUrl , String newName , String tableName , String fieldName ) {
856- String resourceFolderName = buildPath (folder , tableName , fieldName );
857- String resourceKey = resourceFolderName + StorageUtils .DELIMITER + newName ;
858-
859- try {
860- objectUrl = new URI (objectUrl ).getPath ();
861- } catch (Exception e ) {
862- logger .error ("Failed to Parse Storage Object URI for Copy operation" , e );
863- }
864-
865- Map <String , String > metadata = new HashMap <>();
866- metadata .put ("Table" , tableName );
867- metadata .put ("Field" , fieldName );
868- metadata .put ("KeyValue" , StorageUtils .encodeNonAsciiCharacters (resourceKey ));
869-
870- GetObjectRequest getObjectRequest = GetObjectRequest .builder ()
871- .bucket (bucket )
872- .key (objectUrl )
873- .build ();
874- ResponseBytes <GetObjectResponse > objectBytes = client .getObjectAsBytes (getObjectRequest );
875-
876- PutObjectRequest .Builder putObjectRequestBuilder = PutObjectRequest .builder ()
877- .bucket (bucket )
878- .key (resourceKey )
879- .metadata (metadata )
880- .contentType (CommonUtil .getContentType (newName ));
881- PutObjectRequest putObjectRequest = putObjectRequestBuilder .build ();
882- client .putObject (putObjectRequest , RequestBody .fromBytes (objectBytes .asByteArray ()));
883-
884- return getResourceUrlWithoutACL (resourceKey , defaultExpirationMinutes );
885- }
886685}
887686
888687//http://192.168.254.78:9000/java-classes-unittests/text.txt
0 commit comments