Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store (optional) content type provided in upload #25

Open
guusdk opened this issue Jul 17, 2020 · 3 comments
Open

Store (optional) content type provided in upload #25

guusdk opened this issue Jul 17, 2020 · 3 comments

Comments

@guusdk
Copy link
Owner

guusdk commented Jul 17, 2020

When a file is being uploaded, an optional content type is provided.

The implementation needs to persist this data for later use, as Java cannot reliably detect the content type of file.

@psefranek
Copy link

Hi Guus,

in relation to this issue, I've investigated the method nl.goodbytes.xmpp.xep0363.repository.getContentType(SecureUniqueId uuid) and I am seeing a few issues here:

Line 142: Files.probeContentType(path): this method will most probably use private static class Files$FileTypeDetectors and its field defaultFileTypeDetector - this "system default" detector most probably delegates to method sun.nio.fs.MimeTypesFileTypeDetector.implProbeContentType(Path path). This method relies on file extension for detection; if there is no file extension, it immediately returns null:

String ext = getExtension(fn.toString());
if (ext.isEmpty())
    return null;  // no extension

Since SecureUniqueId carries no extension, this call never succeeds.


Line 147: URLConnection.guessContentTypeFromName(path): this method uses java.net.FileNameMap which again relies on file name (and its extension). Due to this fact, this call never succeeds too.


Line 137: URLConnection.guessContentTypeFromStream(is): this is the one and only way to get content type from random file name like SecureUniqueId, because this method examines real content (bytes) of provided file. Unfortunately, in current circumstances, this call never succeeds too. In this method, the very first line tests if provided InputStream supports mark operation:

// If we can't read ahead safely, just give up on guessing
if (!is.markSupported())
  return null;

InputStream returned from call to Files.newInputStream(path) (line 135) will most probably be instance of class sun.nio.ch.ChannelInputStream which does not support mark operation.

As a simple fix of this issue I am proposing to use another InputStream - the one that supports the mark operation. To verify my statement, I have changed line 135 from

try ( final InputStream is = Files.newInputStream( path ) ) {

to

try ( final InputStream is = new BufferedInputStream(new FileInputStream( path.toFile() ))) {

I have tested this little change in your code and was able to detect SecureUniqueId files successfully. Could you please commit this little fix and release new version?

Thanks for your time and keep up the good work!
Pavel

@guusdk
Copy link
Owner Author

guusdk commented Jul 27, 2021

Hi Pavel - thanks for your detailed analysis. Would you mind providing a PR with this change?

@psefranek
Copy link

Sure! PR created.

Thanks
Pavel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants