I am using tcpdf with Cakephp. The PDFs are downloaded good in Linux but when it comes to Mac for Opera and Safari it add .html ectension to it.
I also noticed that even if it downloads as PDF document in FireFox and Google Chrome, the Pop-up to save as reads it as "HTML document" but save as PDF. PLease help me with this.
Try to modify headers, like:
header("Content-Description: File Transfer");
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file_name));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Cache-Control: private", false); // required for certain browsers
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));
Hope it works. :)
It seems like Mac and Safari are more strict when it comes to mime types, and always obeys the content type set in your scripts. So if the Content type is being set to text/html, Safari will expect it to be a HTML document and add the html extension. Firefox and Chrome are using this content-type header to present the file type (HTML document), but does not change the filename so it saves as a PDF.
As you are using CakePHP, it's a good idea to use the built in file response in your Controller:
$this->response->file($path,array('download' => true, 'name' => $filename));
return $this->response;
This will correctly set the headers you need for most files. See here for docs: http://book.cakephp.org/2.0/en/controllers/request-response.html#sending-files
Be warned, CakePHP might not know the mimetype of some files, and will default to text/html. Then you'll get the same problem in Safari. It's a good idea to test and if you see this happening, set the mime types yourself (BEFORE setting the file):
$ext = pathinfo($filename, PATHINFO_EXTENSION);
switch ($ext) {
case 'dotx':
$this->response->type('application/vnd.openxmlformats-officedocument.wordprocessingml.template');
break;
}
$this->response->file($path,array('download' => true, 'name' => $filename));
return $this->response;
I found by adding
$this->response->type('application/pdf');
to the view file and by updating to the latest version of the TCPDF vendor files it resolved the same issue for us (as well as other display issues).
In your controller simply add this
$this->response->header(array('Content-type: application/pdf'));
$this->response->type('pdf');
By adding this same issue is solved to me.
Related
Using selenium-webdriver and capybara in rspec, in a features spec I'm trying to get the HTTP response of a plain text request, namely /robots.txt
But instead of getting the plain text response, I get the text response wrapped in HTML:
expected: "User-agent: *\nDisallow:\n\nSitemap: https://prj.org/sitemap.xml\n"
got: "<html><head><link rel=\"alternate stylesheet\" type=\"text/css\" href=\"resource://content-accessible/plaintext.css\" title=\"Wrap Long Lines\"></head><body><pre>User-agent: *\nDisallow:\n\nSitemap: https://prj.org/sitemap.xml\n</pre></body></html>"
When fetching /robots.txt with curl I get the expected plain text response. So I've been through Firefox options, and I found out I needed to disable plain_text.wrap_long_lines option.
And I cannot succeed to pass the option to geckodriver.
I first tried to pass it to the Options object, like this:
Capybara.register_driver :firefox_headless do |app|
options = ::Selenium::WebDriver::Firefox::Options.new
options.headless!
options.add_preference 'plain_text.wrap_long_lines', false
Capybara::Selenium::Driver.new app, browser: :firefox, options: options
end
Then I tried to pass it to a Profile object.
Capybara.register_driver :firefox_headless do |app|
options = ::Selenium::WebDriver::Firefox::Options.new
options.headless!
profile = Selenium::WebDriver::Firefox::Profile.new
profile['plain_text.wrap_long_lines'] = false
Capybara::Selenium::Driver.new app, browser: :firefox, options: options, profile: profile
end
In both cases, the result is the same. Any idea as per why? Thanks!
Using:
selenium-webdriver 3.14.1
capybara 3.7.2
geckodriver 0.22.0
The issue you're seeing here is that when Firefox opens a text file it automatically wraps it in some boilerplate html in order for the browser to be able to display it. You don't show your test code you're using - but whatever you're doing should boil down to something like
# If using minitest
visit('/robots.txt')
find('body > pre').assert_text("User-agent: *\nDisallow:\n\nSitemap: https://prj.org/sitemap.xml\n", exact: true)
# If using RSpec
visit('/robots.txt')
expect(find('body > pr')).to have_text("User-agent: *\nDisallow:\n\nSitemap: https://prj.org/sitemap.xml\n", exact: true)
I have an Angular 1.5 client, published off of a Node 4,Express 4 server. I do 99% of my manual testing in IE Edge. (The rest is in Mocha, Karma, and before delivery, I hit Firefox.)
We recently added this line to our http server, using helmet:
//Prevent Mime type sniffing/infering
app.use(helmet.noSniff());
PROBLEM: The nosniff option broke all of my thumbnails.
In one of my other Angular modules, which is a controller and view component, I have this line:
...
<img ng-src="/api/thumbnail/{{title}}"/>
...
On my Node/Express server, my /api/thumbnail/:title/ route looks like this:
router.get('/api/thumbnail/:title/',function(req,res){
... get file to read from 'title'
fs.readFile(fileName,function(err,data){
if ( err ) { ... do error handling ... }
else { resp.send(data); }
});
})
Using IE's Network debugger, I noticed that the requests being sent to the server have 'application/octet stream' as the 'Content-Type'. Maybe because I am sending back an 'image/jpeg', so, I asked myself if that's what is causing the nosniff to kill the response?
In my server code, I have a "DEFAULT_THUMBNAIL" which I send back in the event that 'title' produced no viable thumbnail image for me. So, before I do a resp.send(data), I did this:
const mime = require('mime');
...
resp.setHeader('Content-type',mime.lookup(DEFAULT_THUMBNAIL));
And that seemed to fix the nosniff issue.
I have an angularJs app that sends a base64 encoded image (or file) to my rails4 server api that uses paperclip to store attachments. Everything works fine until the content_type_validation paperclip does.
For some reason, paperclip determines the content-type's been spoofed and get the following error message:
[paperclip] Content Type Spoof: Filename 1413325092.jpg (["image/jpeg"]), content type discovered from file command: application/octet-stream; charset=binary. See documentation to allow this combination.
I create the paperclip attachment with the following code:
def self.create_from_base64(base64_string)
decoded_data = Base64.decode64(base64_string)
# create 'file' understandable by Paperclip
data = StringIO.new(decoded_data)
data.class_eval do
attr_accessor :content_type, :original_filename
end
# set file properties
data.content_type = 'application/octet-stream'
data.original_filename = "#{Time.now.to_i}.jpg"
end
I've tried different things but for some reason even when I set data.content_type = 'application/octet-stream', the error is exactly the same, and paperclip it's been spoofed.
Any ideas?
Thanks,
EDIT:
I have the following validation:
validates_attachment_content_type :file, :content_type => [/png\Z/, /jpe?g\Z/, /application\/octet-stream*/]
Basically I have this code which uploads javascripts and other content to Rackspace using Jclouds:
SwiftObject obj = cloudFilesClient.newSwiftObject();
obj.getInfo().setName(name);
obj.getInfo().setContentType(contentType);
obj.setPayload(payloadFile);
cloudFilesClient.putObject(container, obj);
I noticed that Chrome complains about scripts being transferred with text/plain and so set out to investigate. curl -I report instead: Content-Type: application/unknown.
I've Googled a lot and tried to find some clues, and I've tried:
not setting content type at all
setting empty string (found some rumour about that somewhere)
setting to application/javascript (correct)
setting to text/javascript (wrong, but common)
obj.getAllHeaders().put("Content-Type", contentType);
When we used to upload with basic HTTP before, this just worked without setting anything manually at all.
Finally finally managed to figure it out by digging in the source code - this works:
FilePayload payload = new FilePayload(uploadableFile.localPath.toFile());
payload.getContentMetadata().setContentType(uploadableFile.contentType);
obj.setPayload(payload);
In case anyone else is looking for this in the future, posting Q&A.
I have downloaded WebTechNick's PayPal plugin and copied the files
into /app/plugins/paypal_ipn (exactly as per the instructions). I have
amended /app/config/routes.php to include the routes for the plugin
(these are copied straight from the installation instructions).
When I access http//:[mysite]/paypal_ipn I am getting a
missing controller error:
Error: PaypalIpnController could not be found.
Error: Create the class PaypalIpnController below in file: app/
controllers/paypal_ipn_controller.php
I'm baffled as I have followed conventions yet this isn't working. I
have other plugins working as expected.
What am I doing wrong?
thanks
i would not use this route (besides, its optional)
Router::connect('/paypal_ipn/:action/*', array('admin' => 'true', 'plugin' => 'paypal_ipn', 'controller' => 'instant_payment_notifications', 'action' => 'index'));
I want my admin stuff to be in /admin/... not having one rouge plugin doing something else
after removing that you should have the following available
site.com/admin/paypal_ipn/paypal_items (shows index like always)
site.com/admin/paypal_ipn/paypal_items/index
site.com/admin/paypal_ipn/paypal_items/view/$id
site.com/admin/paypal_ipn/paypal_items/add
site.com/admin/paypal_ipn/paypal_items/edit/$id
site.com/admin/paypal_ipn/paypal_items/delete/$id
and
site.com/paypal_ipn/instant_payment_notifications/process (need to post to this one)
and
site.com/admin/paypal_ipn/instant_payment_notifications (shows index like always)
site.com/admin/paypal_ipn/instant_payment_notifications/index
site.com/admin/paypal_ipn/instant_payment_notifications/view/$id
site.com/admin/paypal_ipn/instant_payment_notifications/add
site.com/admin/paypal_ipn/instant_payment_notifications/edit/$id
site.com/admin/paypal_ipn/instant_payment_notifications/delete/$id
This is really old, but the selected answer didn't help solve my problem and this thread is the only one that I was able to find.
The issue is that by default, cakephp (as of 2.5.4) does not enable admin prefixing. If (like me) you're not familiar with routing or prefixing, I suggest reading the below links:
Routing: http://book.cakephp.org/2.0/en/development/routing.html
Prefixing: http://book.cakephp.org/2.0/en/development/routing.html#prefix-routing
But, the quick fix to this (assuming your fine with this plugins admin routing process) is to uncomment the admin prefixing line in your core.php. DO NOT TRY ADDING THIS TO routes.php. It won't work. Rather look around line 152 in /app/Config/core.php and change
//Configure::write('Routing.prefixes', array('admin'));
to
Configure::write('Routing.prefixes', array('admin'));
I assume you have added
var $components = array('PluginName.Example'); (adjust the values)
to your (app_)controller?