I'm using the Echo Framework's static filehandler for serving uploaded files out of my upload directory.
e := echo.New()
e.Static("/uploads","uploads")
This works fine for smaller video files. I've tested it with a 20MB videofile, which works fine. Larger files, for example a 50MB testfile, do not work. The underlying TCP connection gets closed before the whole file is being served.
Does anyone know if there is a filesize limit or a timer that can be set to prevent this?
you are looking for echo.File(). This method serves, longer files, like yours because the underlying net/http package used in http.FileServer() and echo.File() are the same. You can add something like this
echo.File("route","filepath",middleware).
You can also use the same functionality which is associated with echo.Context by the same name c.File(). Here the function definition is shorter and has an example in echo webpage https://echo.labstack.com/cookbook/file-download.
Related
Glide uses disk caching (both internal and external). The way it stores the file name is encoded in some format. It is possible to get the original file name/file path, where the image is downloaded ?
Glide uses a two-level cache in 3.x: SOURCE and RESULT. The default caching (if you don't specify a .diskCacheStrategy() is RESULT. Currently there's no public way to figure out which file corresponds to a normal Glide load (RESULT cache).
The main article about caching is: https://github.com/bumptech/glide/wiki/Caching-and-Cache-Invalidation
Many have tried to mess with the cache.
The solution is based on your use case and you can choose one of:
.sigunature(): invalidate a single item in cache when signature changes
.downloadOnly(): get the File handle to a SOURCE cache item
.asBytes(): returns JPG/PNG encoded byte[] instead of a Drawable/Bitmap
Glide.get(context).clearDiskCache(): last resort only, removes everything
I have a classic asp site that I am using to download files and to this point the files have been quite small (<5mb). But now we want to use the site for much larger files upwards of 2GB. The code below works but does not prompt for the user to "open/save" until the entire file is loaded into memory. So on a large file the site appears to hang for several minutes before prompting the user. I'd like for the popup to occur right away if possible. Any ideas?
Set HttpReq = Server.CreateObject("MSXML2.ServerXMLHTTP") 'works
HttpReq.open "GET", "http://myaspnetwebapiservice/api/values/1", False
HttpReq.send
Response.BinaryWrite HttpReq.responseBody
Use Range header to request part of the large file. Download one by one part, and merge the response bodies. see Range Requests.
for example:
HttpReq.setRequestHeader "Range","bytes=0-100000"
Or use responseStream property to handle the response.
I have written downloading a file in a simple manner:
#ResourceMapping(value = "content")
public void download(ResourceRequest request, ResourceResponse response) {
//...
SerializableInputStream serializableInputStream = someService.getSerializableInputStream(id_of_some_file);
response.addProperty(HttpHeaders.CACHE_CONTROL, "max-age=3600, must-revalidate");
response.setContentType(contentType);
response.addProperty(HttpHeaders.CONTENT_TYPE, contentType);
response.addProperty(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''"
+ URLEncoder.encode(fileName, "UTF-8"));
OutputStream outputStream = response.getPortletOutputStream();
byte[] parcel = new byte[4096];
while (serializableInputStream.read(parcel) > 0)
outputStream.write(parcel);
outputStream.flush();
serializableInputStream.close();
outputStream.close();
//...
}
The SerializableInputStream is described here - JavaDocs. It allows an InputStream to be serialized and, for instance, passed over remoting.
I read from input and write it to the output, not all bytes at once. But unfortunately the portlet isn't "streaming" the contents - the file (e.g. an image) is sent to the browser only after reading the entire input stream - this is how it looks like. I see the file being read from the database (from live logs), but I don't see any "growing" image on the screen.
What am I doing wrong? Is it possible to really stream a file in Liferay 6.0.6 and Spring Portlet MVC?
Where are you doing this? I fear that you're doing this instead of rendering your portlet's HTML (e.g. render phase). Typically the portlet content is embedded in an HTML page, thus you need the resource phase, which (roughly) behaves like a servlet.
Also, the code you give does not match the actual question you ask: You use a comment //read from input stream (file), write file to os and ask what to do differently in order to not have the full content in memory.
As the comment does not have anything in memory and you could loop through reading from the input file while writing to the output stream: What's the underlying question? Do you have problems with implementing download-streaming in a portal environment or difficulties (i.e. using too much memory) reading from a file while writing to a stream?
Edit: Thanks for clarifying. Have you tried to flush the stream earlier? You can do that whenever you want - e.g. every loop (though that might be a bit too much). Also, keep in mind that the browser as well as the file itself must handle it in a way that you expect: If an image is not encoded "incrementally" a browser might not show it that way.
Have you tried this with huge files as well? It might be that the automatic flushing is just not triggered because your files are too small for it to be triggered...
Also, I think that filename*=UTF-8'' looks strange. Might be valid encoding, but I've never seen this
As part of a Classic ASP Project the user should be able to download a file - which is dynamicly extracted from a zip archive and sent via Response.BinaryWrite() - by simply calling "document.asp?id=[some id here]".
Extracting and sending is not the problem but I need to delete the extracted file after the download finished. I never did any ASP or VBA before and I guess that's why I stuck here.
I tried deleting the file right after Response.WriteBinary() using FileSystemObject.DeleteFile() but this results in a 404-Error on the client-side.
How can I wait till the download finished and then do additional actions?
Edit: This is how my code looks like:
'Unzip a specified file from an archive and put it's path in *document*
set stream = Server.CreateObject("ADODB.Stream")
stream.Open
stream.Type = 1 ' binary
stream.LoadFromFile(document)
Response.BinaryWrite(stream.Read)
'Here I want to delete the *document*
I suspect that the point you are calling the DeleteFile method the file you are trying delete is currently locked by something else, the question is what?
Try including:-
stream.Close()
after your BinaryWrite. Also make sure you've done a similar thing to the component you've used to extract the file. If the component doesn't offer any obviouse "close" methods they trying assigning Nothing to the variables referencing them.
Is it not possible to stream the file into memory, then binary write the stream to the browser, this way the file is never created on the server and there is no need to delete it.
I found a solution: The extracted files are saved in a special directory and everytime a user runs the document.asp it checks this directory for files older than one hour and deletes them.
I think it's the simplest way to manage, but furthermore I would prefer a solution where the document is deleted after downloading.
I was wondering what's the best practise for serving a generated big file in classic asp.
We have an application with "export to excel" function that produces 10MB files. The excels are created by just calling a .asp page that has the Response.ContentType set to excel and has an HTML table for the data.
This gives as problem that it takes 4 minutes before the user sees the "Save as..." dialog.
My current solution is to call an .asp page that creates the excel on the server with AJAX and lets the page return the URL of the generated document. Then I can use javascript to display the on the original page.
Is this easy to do with classic asp (creating files on server with some kind of stream) while keeping security in mind? (URL should make people be able to guess the location of other files)
How would I go about handling deleted the generated files overtime? They have to be deleted periodicly as the data changes in realtime.
Thanks.
edit: I realized now that creating the file on the server will probably also take 4 minutes...
I think you are selecting a complex route, when the solution is simple enough (Though I may be missing some requirements)
If you to generate an excel, just call an asp page that do the following:
Response.clear
Response.AddHeader "content-disposition", "attachment; filename=myexcel.xls"
Response.ContentType = "application/excel"
'//write the content of the file
Response.write "...."
Response.end
This will a start a download process in the browser without needing to generate a extra call, javascript or anything
See this question for more info on the format you will choose to generate the excel.
Edit
Since Thomas update the question and the real problem is that the file take 4 minutes to generate, the solution could be:
Offer the user the send the file by email (if this is a workable solution in you server or hosting).
Generate the file async, and let the user know when the file generation is done (with an ajax call, like SO does when other user have added an answer)
To generate the file on the server
'//You should change for a random name or something that makes sense
FileName = "C:\temp\myexcel.xls"
FileNumber = FreeFile
Open FileName For Append As #FileNumber
'//generate the content
TheRow = "...."
Print #FileNumber, TheRow
Close #FileNumber
To delete the temp files generated
I use Empty Temp Folders a freeware app that I run daily on the server to take care of temp files generated. (Again, it depends on you server or hosting)
About security
Generate the files using random numbers or GUIds for a light protection. If the data is sensitive, you will need to download the file from a ASP page, but I think that you will be in the same problem again...(waiting 4 minutes to download)
Read file using FSO.
Set headers for Excel file-type, name according to file read and for download (attachment)
Flush response after headers are set. The client should display "save as" dialogue.
Output FSO to response. Client will download file and see progress bar.
How do you plan to generate the Excel? I hope you don't plan to call Excel to do that, as it is unsupported, and generally won't work well.
You should check to see if there are COM components to generate Excel that you can call from Classic ASP. Alternatively, add one ASP.NET page for the purpose. I know for a fact that there are compoonents that can be called from ASP.NET pages to do this. Worse come to worst, there's an Excel exporter component from Infragistics that works with their UltraWebGrid control to export. The grid need not be visible in order to accomplish this, but styles in the grid translate to styles in the spreadsheet. They also allow you to manipulate the spreadsheet programmatically.