Serving Files in Zend Framework MVC - model-view-controller

What is the best practice when serving files from the Zend Framework MVC? These files have to be served from the MVC as they are protected.
I know you can read in the file and place it into the Response object but this seems like a bad practice as you would be reading the entire file into memory then serving it. Right now I usually do:
header('Content-type: image/jpeg');
fpassthru(fopen($path, 'rb'));
exit;
But this also doesn't seem right as I'm stopping the execution of the script. Any suggestions?

I see nothing wrong with just exit(); What you will need to be careful of is any output buffering layers you may have on (gzip compression, etc). Large files could blow up those buffers pretty quick, so you'll want to close them out and potentially 'chunk' your output with a fopen/fread loop.

I would suggest building a super-simple script for retrieving files based on ticket system like in CMS you generate ticket to DB - filename, unique-hash and than redirect to the super-simple file-retieving script (file.php?hash=asd52ad3as1g5). It will get the hash from query and based on it fetch the real filename and push that to output as you have written using fpassthru. The hash need to be unique and hard to guess...

You could try using the X-Sendfile header. It is supported by lighttpd and newer versions of apache. Basically the webserver will replace the output of the script with the file you specified. The downside being that it is specific to the configuration of the webserver, so you may be on a host that doesn't support it.

Related

Yii2 framework - reduce not used memory (files)

I want to set up new project in Yii 2.0.6 framework, which I will use for simple REST calls only (making requests and getting responses from DB).
I have downloaded the framework from their official site (basic pack from Archive file). Now initially I have empty project that initially take place of ~24MB. I'm not sure if this is a good idea, because every time I will make some request (from mobile devices), it will probably load all these 24MB from the server. Is it how it works?
Is there a way for setting up the Yii 2.0.6 project with minimal size on the disk? I really need everything to be optimized and to load as minimal code as possible.
PHP files will only be rendered in the server side where only required files will be loaded and used and all what your mobile is going to receive are the Json outputs if what you are going to build is a REST api.
To check the size in byte of a json file that your mobile is going to receive, you can use curl as described in Yii2 REST docs and add grep Content-Length to the request :
curl -i -H "Accept:application/json" "http://YOUR_RESOURCES_URL" | grep Content-Length
or you can use the network tab of a navigator dev tools instead :
here the json file's size is 392B and it took 179 ms to receive it from server
Also remember that by default Yii is installed with dev environment settings, there is optimizations to do before publishing the product in order to optimize time responses. check this for more details.
It is also good practice to use a tool like gzip to compress data before sending to mobile as described here : JSON REST Service: Content-Encoding: gzip
Of course not. Yii only load the required classes (and files) on the fly, thanks to the autoloading mechanism.
A few components are preloaded during the bootstrap phase (and you can add or remove some of them in the configuration file). Other classes won't clutter your memory as long as you don't use them.

What's the fastest way to upload an image to a webserver?

I am building an application which will allow users to upload images. Mostly, it will work with mobile browsers with slow internet connections. I was wondering if there are best practices for this. Does doing some encryption and than doing the transfer and decoding on server is a trick to try ? OR something else?
You would want something preferably with resumable uploads. Since your connections is slow you'd need something that can be resumed where you left off. A library i've come across over the many years is Nginx upload module:
http://www.grid.net.ru/nginx/upload.en.html
According to the site:
The module parses request body storing all files being uploaded to a directory specified by upload_store directive. The files are then being stripped from body and altered request is then passed to a location specified by upload_pass directive, thus allowing arbitrary handling of uploaded files. Each of file fields are being replaced by a set of fields specified by upload_set_form_field directive. The content of each uploaded file then could be read from a file specified by $upload_tmp_path variable or the file could be simply moved to ultimate destination. Removal of output files is controlled by directive upload_cleanup. If a request has a method other than POST, the module returns error 405 (Method not allowed). Requests with such methods could be processed in alternative location via error_page directive.

Play! Framework 2.1.3 pdf problems

so I am working on a school project in which we have designed a web application that takes in much user info and creates a pdf then should display that pdf to the user so they can print it off or save it. We are using Play! Framework 2.1.3 as our framework and server and Java for the server side. I create the pdf with Apache's PDFbox library. Every thing works as it should in development mode ie launching it on a localhost with plays run command. the issue is when we put it up to the server and launch with plays start command I it seems to take a snapshot of the directory (or at least the assets/public folder) which is where I am housing the output.pdf file/s (i have attempted to move the file elsewhere but that still seems to result in a 404 error). Initially I believed this to be something with liunx machine we were deploying to which was creating a caching problem and have tried many of the tricks to defeat the browser from caching the pdf
like using javascript to append on a time stamp to the filename,
using this cache-control directive in the play! documentation,
"assets.cache./public/stylesheets/output.pdf"="max-age=0",
then I tried to just save the pdf as a different filename each time and pass back the name of that file and call it directly through the file structure in the HTML
which also works fine with the run command but not the start.
finally I came to the conclusion that when the start command is issued it balls up the files so only the files that are there when the start command is issued can be seen.
I read the documentation here
http://www.playframework.com/documentation/2.1.x/Production
which then I noticed this part
When you run the start command, Play forks a new JVM and runs the
default Netty HTTP server. The standard output stream is redirected to
the Play console, so you can monitor its status.
so it looks like the fact that it forks a new JVM is what is causing my pain.
so my question really is can this be gotten around in some way that a web app can create and display a pdf form? (if I cannot get this to work my only solution
that I can see is that I will have to simulate the form with HTML and fill it out from there) --which I really think is a bad way to do this.
this seems like something that should have a solution but I cannot seem to find or come up with one please help.
i have looked here:
http://www.playframework.com/documentation/2.1.x/JavaStream
the answer may be in there but Im not getting it to work I am pretty novice with this Play! Framework still
You are trying to deliver the generated PDF file to the user by placing it in the assets directory, and putting a link to it in the HTML. This works in development mode because Play finds the assets in the directory. It won't work in production because the project is wrapped up into a jar file when you do play dist, and the contents of the jar file can't be modified by the Play application. (In dev mode, Play has a classpath entry for the directory. In production, the classpath points to the jar file).
You are on the right lines with JavaStream. The way forward is:
Generate the PDF somewhere in your local filesystem (I recommend the temp directory).
Write a new Action in your Application object that opens the file you generated, and serves it instead of a web page.
Check out the Play docs for serving files. This approach also has the advantage that you can specify the filename that the user sees. There is an overloaded function Controller.ok(File file, String filename) for doing this. (When you generate the file, you should give it a unique name, otherwise each request will overwrite the file from a previous request. But you don't want the user to see the unique name).

Is there any tool to generate a labels.rdf file?

Examining the 404 errors for my website I noticed requests for a "labels.rdf" file. After some digging I think I understand what it is and want to create one for my website. But I don't really understand how to generate it. Is there any tool or a generic file that I can use?
Thanks
RDF is not just one format, but a collection - most likely it's expecting RDF/XML.
IMHO the esiest thing to do is create the data you need in a format called Turtle (http://www.w3.org/TeamSubmission/turtle/) - there's lots of tutorials online, then convert it to RDF/XML with a tool, such as rapper (http://librdf.org/raptor/).
You will need to know a bit about the RDF data model though, and what the labels.rdf file is trying to express.

Telerik CDN Support

According to Telerik:
To distribute your web asset group via content delivery network you should use the ContentDeliveryNetworkUrl() method:
<%= Html.Telerik().ScriptRegistrar().Scripts(scripts =>
scripts.AddGroup("CommonScript", group =>
group.Add("~/Scripts/Core.js")
.Add("~/Scripts/Stuff.js")
.Combined(true)
.CacheDurationInDays(365)
.Compress(true)
.ContentDeliveryNetworkUrl("http://mycdn.com/CommonScript.js")
)
I'm confused by this, specifically:
ContentDeliveryNetworkUrl("http://mycdn.com/CommonScript.js")
How does this file get created on the CDN? I assume Core.js and Stuff.js get combined, cached, and compressed then uploaded to my CDN automatically? Or is CommonScript.js another JS file that get's added to the combined script? If so, then the combined script gets served locally still, and not from the CDN?
Telerik say VERY VERY little about how all this work.
Any help is greatly appreciated.
Matt
You need to upload the combined file by yourself. The ContentDeliveryNetworkUrl just tells the script registrar to output that value instead of core.js and stuff.js.

Resources