This is an image uploaded to imgbb: https://i.ibb.co/Kj9bSGr/cogs.png
You will notice that clicking on it will display it in the browser.
This is an image uploaded to Firebase storage: https://firebasestorage.googleapis.com/v0/b/dorg-model.appspot.com/o/uploads%2Fwheeler.png?alt=media&token=ec11456d-7d83-4f1c-9352-36a6a699b718
When you access its address it just triggers a download.
After the setting the correct CORS policy and looking at available questions on this topic, I'm inclined to think that the reason my Flutter web app is not displaying the image is because of the above behavior.
I would like to get the image stored in Firebase to show up in the browser instead of triggering a download.
This is likely due to the file type application/octet-stream instead of image/png. application/octet-stream is the default value when you upload to Firebase Storage.
How to change to image/png
First, create a metadata object (or add to existing metadata) that has the field contentType
const metadata = {
contentType: 'image/png',
};
Then, upload the file as you would normally, including the metadata as the 3rd argument.
const uploadTask = uploadBytes(storageRef, file, metadata);
You can then use the download URL normally, showing the image instead of downloading it.
Example in Firebase Docs of uploading with metadata
Example in Firebase Docs of adding metadata later
Note: If you use other file formats for images, you can use these MIME types for other image and file formats.
I think that you issue is due to the file's type is application/octet-stream and not image/png
When I issue a GET to the link you posted I see in the response headers:
Content-Type: application/octet-stream
Try changing the type to image/png and see if it solves your problem
Related
I am trying to call /vision/v3.1/read/analyze API with a PDF, but sending Content-Type header as application/pdf or application/octet-stream is giving an InvalidImage error. What should be the header value ? Any code sample that I can refer to ?
The supported Content-Types are application/json- analyze images from URL and application/octet-stream - analyze images from disk. I tried the Read API reference and provided url for a pdf file. Confirmed using Get Read Result and works fine. Check out available code samples in python, tutorial and c#, tutorial.
My Cloud Storage signed download URLs fail after three days. I think I've fixed the problem, so this question might be a solution to others. Ask me in three days whether this solution worked!
Here's the complete error message:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
</Message>
<StringToSign>
GET 1742169600 /languagetwo-cd94d.appspot.com/Audio%2FSpanish%2FLatin_America-Sofia-Female-IBM%2Fagua.mp3
</StringToSign>
</Error>
I googled the error message and saw some discussions that the problem is with Content-Type. I don't specify Content-Type in my code when I upload the files to Storage. When I set contentType in the code when uploading the download URLs fail immediately, with the same error message. That suggests that I'm on the right track.
file.getSignedUrl({
action: 'read',
expires: '03-17-2025',
contentType: 'audio/mp3'
})
The expiration date in the download URLs is March 17, 2025, so that's not the problem.
Google's documentation on Signed URLs says that the syntax is Content_Type. The IETF documentation on content-type says that the syntax is Content-Type. I tried
file.getSignedUrl({
action: 'read',
expires: '03-17-2025',
content_type: 'audio/mp3'
})
and my files download and play. I don't want to wait three days to see if they continue to work, so please let me know if there's something else I need to fix!
Just for grins I tried
file.getSignedUrl({
action: 'read',
expires: '03-17-2025',
content-type: 'audio/mp3'
})
and firebase deploy wouldn't accept the code. The hyphen isn't allowed in keys.
Google's documentation on Signed URLs says
As needed. If you provide a content-type, the client (browser) must provide this HTTP header set to the same value.
As needed isn't the same as Optional.
My .mp3 files and my .webm download URLs are failing, so it doesn't matter what the content of the files are.
Three days later, my download URLs are still working. It looks like
file.getSignedUrl({
action: 'read',
expires: '03-17-2025',
content_type: 'audio/mp3'
})
is the answer.
Flask has a method to return a file: http://flask.pocoo.org/docs/1.0/api/#flask.send_file
There is a parameter called as_attachment with a default of False, and there is a handwaavy statement about it: "For extra security you probably want to send certain files as attachment (HTML for instance)"
How do I know if my use case is "those certain files"? Or alternatively stated, what does this do as opposed to leaving this as False?
You'll find a clue in the same documentation, further down in the parameter list:
as_attachment – set to True if you want to send this file with a Content-Disposition: attachment header.
So when the flag is set, an extra header is added to the response, which controls how the browser will handle the response. From the MDN documenation on Content-Disposition:
In a regular HTTP response, the Content-Disposition response header is a header indicating if the content is expected to be displayed inline in the browser, that is, as a Web page or as part of a Web page, or as an attachment, that is downloaded and saved locally.
Without an explicit Content-Disposition header, a text/html response from your Flask server will be shown as a web page in the browser. If you needed the file to be saved to disk instead (the browser prompting you what to do with the file), then you need to have a Content-Disposition: attachment set.
So when your response content type is likely to be shown in the browser as a web page but you want the user to download it instead, use as_attachment=True. These days, in addition to HTML, you probably want to set that flag for images, PDF files, and XML as well.
I am leveraging ServiceStack's Virtual File System and the code-snippet on the wiki to minify content at startup-time. However, I don't see a way that I can add in custom headers, like those recommended for Cache-Control, etc.
I could possibly use Global Response Filters, but a) I don't think they play with "static" files, and b) that require some gnarly response logic.
How can I add headers to content served by a IVirtualPathProvider in ServiceStack?
Static files are served by the StaticFileHandler. It already adds Cache-Control and LastModified headers and will return a 304 if the file hasn't been modified since it was last requested.
The latest version of InMemoryVirtualPathProvider has been rewritten to maintain consistent behavior with the new S3VirtualPathProvider which now includes the LastModified timestamp for each file which the StaticFileHandler can take advantage of.
This change is available from v4.0.47 that's now available on MyGet.
Adding headers with a Custom StaticFilesHandler ResponseFilter
You can still add your own custom HTTP Response headers by registering a StaticFileHandler.ResponseFilter, e.g:
StaticFileHandler.ResponseFilter = (req,res,file) => {
res.AddHeader(headerName, headerValue);
//res.Close(); Closing the Response will stop further processing
};
I'm using Rails to serve a file to the user like so:
def show
headers['Content-Disposition'] = "attachment; filename=\"SIGNATURE\""
headers['Content-Type'] = "text/plain"
render :text => 'some text file content'
end
My browser (Chrome on OS X) renames SIGNATURE to SIGNATURE.txt when downloading.
I have tried several methods such as setting Content-Type: application/unknown and putting a . after SIGNATURE.
How can I ensure that the browser does not attach an extension to the file name?
This is not specifically a Rails question--it most likely a HTTP header response setting I need.
Try setting the content type to application/octet-stream.