How does Joplin determine the mime type of a resource?

Background: I'm importing files without extension via Joplin's data API (Joplin 3.0.6 (prod, linux)). Sometimes the file type is guessed correctly, sometimes not. One example for the wrong file type:

test_pdf (3.0 KB)

Using the file with the usual extension (test.pdf) works:

$ curl -F 'data=@test.pdf' -F 'props={"title": "my resource title"}' http://localhost:41184/resources?token=3bc5abcd523e441e8a1f70e1ede2d2d307510cdc3ba2fa3d2c393abaacec9cea4f9d3fad15641659d091faf2689bfe119e09404ac3d1d42c3aaa183a897aff3f
{"id":"10f372e092a94e2a96af5aca02451bfa","title":"my resource title","mime":"application/pdf","filename":"","created_time":1719154488726,"updated_time":1719154488726,"user_created_time":1719154488726,"user_updated_time":1719154488726,"file_extension":"pdf","encryption_cipher_text":"","encryption_applied":0,"encryption_blob_encrypted":0,"size":3028,"is_shared":0,"share_id":"","master_key_id":"","user_data":"","blob_updated_time":1719154488726,"ocr_text":"","ocr_details":"","ocr_status":0,"ocr_error":"","type_":4}

Using the file name without extension doesn't work:

$ curl -F 'data=@test_pdf' -F 'props={"title": "my resource title"}' http://localhost:41184/resources?token=3bc5abcd523e441e8a1f70e1ede2d2d307510cdc3ba2fa3d2c393abaacec9cea4f9d3fad15641659d091faf2689bfe119e09404ac3d1d42c3aaa183a897aff3f
{"id":"029a7a08b55f47499dd7d19105c756ae","title":"my resource title","mime":"application/octet-stream","filename":"","created_time":1719154241934,"updated_time":1719154241934,"user_created_time":1719154241934,"user_updated_time":1719154241934,"file_extension":"","encryption_cipher_text":"","encryption_applied":0,"encryption_blob_encrypted":0,"size":3028,"is_shared":0,"share_id":"","master_key_id":"","user_data":"","blob_updated_time":1719154241934,"ocr_text":"","ocr_details":"","ocr_status":0,"ocr_error":"","type_":4}

The mime type is set to "mime":"application/octet-stream". The pdf won't be displayed in Joplin. I don't want to modify the original filename. So to mitigate this, the type was added to the request (and guessed correctly by puremagic before):

$ curl -F 'data=@test_pdf;type=application/pdf' -F 'props={"title": "my resource title"}' http://localhost:41184/resources?token=3bc5abcd523e441e8a1f70e1ede2d2d307510cdc3ba2fa3d2c393abaacec9cea4f9d3fad15641659d091faf2689bfe119e09404ac3d1d42c3aaa183a897aff3f
{"id":"949756ba32b3467185a7adfe7dc82411","title":"my resource title","mime":"application/octet-stream","filename":"","created_time":1719153753103,"updated_time":1719153753103,"user_created_time":1719153753103,"user_updated_time":1719153753103,"file_extension":"","encryption_cipher_text":"","encryption_applied":0,"encryption_blob_encrypted":0,"size":3028,"is_shared":0,"share_id":"","master_key_id":"","user_data":"","blob_updated_time":1719153753103,"ocr_text":"","ocr_details":"","ocr_status":0,"ocr_error":"","type_":4}

Still "mime":"application/octet-stream" :frowning:

The request looks ok in wireshark:

How can I get Joplin to use the correct mime type?

"mime":"application/octet-stream"

You're setting it to application/octet-stream here, so you need to set it to application/pdf instead and that should work. I don't think the API currently look at the Content-Type header

I didn't set it. That's the response from Joplin. (Probably I just expressed it wrong in the original post.)

Even when trying to set the mime type explicitly to application/pdf, application/octet-stream is returned.

curl -F 'data=@test_pdf' -F 'props={"title": "my resource title", "mime": "application/pdf"}' http://localhost:41184/resources?token=3bc5abcd523e441e8a1f70e1ede2d2d307510cdc3ba2fa3d2c393abaacec9cea4f9d3fad15641659d091faf2689bfe119e09404ac3d1d42c3aaa183a897aff3f
{"id":"c59793d502fb405d8379be649f3216bf","title":"my resource title","mime":"application/octet-stream","filename":"","created_time":1719241631134,"updated_time":1719241631134,"user_created_time":1719241631134,"user_updated_time":1719241631134,"file_extension":"","encryption_cipher_text":"","encryption_applied":0,"encryption_blob_encrypted":0,"size":3028,"is_shared":0,"share_id":"","master_key_id":"","user_data":"","blob_updated_time":1719241631134,"ocr_text":"","ocr_details":"","ocr_status":0,"ocr_error":"","type_":4}

Only when issuing another separate PUT request, the mime type is changed to application/pdf:

$ curl -X PUT --data '{"mime": "application/pdf"}' http://localhost:41184/resources/c59793d502fb405d8379be649f3216bf?token=3bc5abcd523e441e8a1f70e1ede2d2d307510cdc3ba2fa3d2c393abaacec9cea4f9d3fad15641659d091faf2689bfe119e09404ac3d1d42c3aaa183a897aff3f
{"id":"c59793d502fb405d8379be649f3216bf","title":"my resource title","mime":"application/pdf","filename":"","created_time":1719241631134,"updated_time":1719242227966,"user_created_time":1719241631134,"user_updated_time":1719242227966,"file_extension":"","encryption_cipher_text":"","encryption_applied":0,"encryption_blob_encrypted":0,"size":3028,"is_shared":0,"share_id":"","master_key_id":"","user_data":"","blob_updated_time":1719241631134,"ocr_text":"","ocr_details":"","ocr_status":0,"ocr_error":"","type_":4}

Indeed you're right, looks like the API end point doesn't make use of the mime property if it's provided. The code auto-detects images apparently but no other file types.

I guess we should either properly detect all files or support explicitly setting the mime type.

Yes I think that's only workaround at the moment

Unfortunately this doesn't work either at the end:

  1. Creating the resource (with the wrong mime type). A resource named <hash>.bin is in the file system.
  2. Setting the correct mime type with a separate request (for example application/pdf).
  3. Clicking on the resource in Joplin: "File not found: <hash>.pdf"

Ok so it looks like there's no workaround at the moment. I've created two related issues to deal with this:

1 Like