When script is executed with python CGI PDF is feching well. But if i import script in another module unable to fetch pdf.
import cgi
form = cgi.FieldStorage()
import os,io,html,sys
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
data = 'Create a new PDF with Reportlab Swamy® RedteK 4104 DE* ≤ 0.4 ≤ 1.5 *'
packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
strdata = data.encode('utf-8','xmlcharrefreplace')
cat = str(html.unescape(strdata.decode()))
can.drawString(10, 500, cat)
can.showPage()
can.save()
packet.seek(0)
print('Content-type: application/pdf')
print('Content-Disposition: inline; filename="out.pdf"')
print('\n\n')
sys.stdout.flush()
sys.__stdout__.buffer.write(packet.getvalue())
PDF fetched when module when script is initiated directly.
Error when import in another module
Error in apache errorlogs: malformed header from script. Bad header=%PDF-1.3:
Thanks you,
A guess from a non-python guy here:
print('Content-type: application/pdf')
print('Content-Disposition: inline; filename="out.pdf"')
print('\n\n')
looks suspicious: A linebreak is required after each HTTP-header:
print('Content-type: application/pdf')
print('\n')
print('Content-Disposition: inline; filename="out.pdf"')
print('\n\n')
As you say you see "malformed header from script" in the logs: Monitor them. I assume that the version without an extra linebreak just has the Content-Type header with a really weird content type:
Content-type: application/pdfContent-Disposition: inline; filename="out.pdf"
while the browser (and server) could (and should) make use of
Content-type: application/pdf
Content-Disposition: inline; filename="out.pdf"
Related
I need to upload a pdf file through backend API using JMeter. So for that, I passed a multipart API request. To upload the file I am using BeanShell Preprocessor.
FileInputStream in = new FileInputStream("C:\\Users\\XYZ\\Downloads\\PT_003.pdf");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int i; (i = in.read(buffer)) != -1; ) {
bos.write(buffer, 0, i);
}
in.close();
byte[] binarydata = bos.toByteArray();
bos.close();
vars.put("binarydata", new String(binarydata));
Multipart Request Body :
--AaC07x
Content-Type: application/json; charset=utf-8
{
"token":"a6b8J000000055JQPU",
"flow":"Development"
}
--AaC07x
content-disposition: form-data; name="File"; filename="PT_003.pdf"
Content-Type: application/pdf
Content-Transfer-Encoding: bytecode
${binarydata}
--AaC07x--
Header Manager:-
Content-Type multipart/related;boundary="AaC07x"
File uploaded but content in that pdf file is missing means when I tried to open the uploaded pdf file it's blank/corrupted.
So can you please anyone help me to fix that issue??
It looks like your byte array to string conversion is the problem. Moreover as per JMeter 5.5 you cannot simply send a byte array using HTTP Request sampler as given you put everything into "Body Data" tab it will be treated as a String
Since JMeter 3.1 you should avoid using Beanshell, the recommended scripting language is Groovy
If you have problems coming up with a proper request definition you can just record it using HTTP(S) Test Script Recorder, just make sure that your PT_003.pdf is in JMeter's "bin" folder during both recording and replay
I'm trying to upload a pdf file with form-data to a server. The upload works but the file gets corrupted for some reason (I can't open the uploaded version). Here's my code:
post_url = 'https://myposturl'
headers = {
'Content-Type':'multipart/form-data; charset=UTF-8; boundary=MyBoundary'
}
with open('./myfile.pdf', 'rb') as f:
body = f'--MyBoundary\r\nContent-Disposition: form-data; name="file"; filename="myfile.pdf"\r\nContent-Type: application/pdf\r\n\r\n{f.read()}\r\n--MyBoundary--\r\n'
res = s.post(post_url, headers = headers, data = body)
I thought it was coming from the \r\n, I tried a replace('\n', '\r\n') on the f.read() output but it didn't work.
Also, when using https://httpbin.org to check the POST request, I get \\\\r\\\\n for each new line in the pdf binary data. I'm wondering if this is normal, maybe that could help.
Thank you in advance for your suggestions.
With requests it can be done a bit easier.
import requests
post_url = 'https://myposturl'
files = {'file': open('./myfile.pdf', 'rb')}
r = requests.post(post_url, files=files)
More docs.
The reason you get corrupted file is probably because you're setting headers and body manually. requests usually sets theses things implicitly, so you should not break this concept and follow official guides.
I'm trying to use Scrapy-Splash to take a screenshot of a website using the 'render.png' endpoint (in practice I do this in my spider after certain exceptions occur, and I want to view how the site looks for them).
The problem I'm having is that the response appears to not be a valid PNG. A min example in the scrapy shell is:
from scrapy_splash import SplashRequest
url='http://www.waitrose.com'
args={'wait': 2, 'width': 320, 'timeout': 60, 'render_all': 1}
endpoint='render.png'
# I also tried with dont_send_headers=True, dont_process_response=True
sr=SplashRequest(url=url, args=args, endpoint=endpoint)
fetch(sr)
You will need a local splash server running to execute this of course (see here)
The response headers are
{'Content-Type': 'image/png',
'Date': 'Mon, 10 Apr 2017 21:23:48 GMT',
'Server': 'TwistedWeb/16.1.1'}
but the body starts like
In [16]: response.body[:100]
Out[16]: '<html><head></head><body>\xe2\x80\xb0PNG\n\x1a\n\nIHDR\x01#\x04\xc2\xad\x08\x065r\xe2\x80\x9aQ\tpHYs\x0fa\x0fa\x01\xc2\xa8?\xc2\xa7i IDATx\x01\xc3\xac\xc2\xbd\x07\xc5\x93\\\xc3\x97u\xc3\xa6y\xc2\xaa\xc2\xbab\xc3\xa7\xc5\x93\xc3\x91'
and even after trimming the html tags and saving to file, my system says non-valid PNG.
On the other hand if I use the python-requests module like
import requests
base_url = "http://localhost:8050/render.png"
params = {'url': 'http://www.waitrosecellar.com',
'wait': 2,
'width': 320,
'timeout': 60,
'render_all': 1}
response2 = requests.get(base_url, params)
I have no issues. The response content starts like
In [19]: response2.content[:100]
Out[19]: '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01#\x00\x00\x03)\x08\x06\x00\x00\x00u\xf4\xea\x11\x00\x00\x00\tpHYs\x00\x00\x0fa\x00\x00\x0fa\x01\xa8?\xa7i\x00\x00 \x00IDATx\x01\xec\xbd\x07\x9c]\xc7u\xdf\x7f\xb6\x17\xec\xa2\xf7\xba(\x04A\x80`\x17\x8bH\x90\x14\x9bHY\xdd\x92l\xc9\x92\xab\\\x92'
the headers are
In [20]: response2.headers
Out[20]: {'Transfer-Encoding': 'chunked', 'Date': 'Mon, 10 Apr 2017 21:39:17 GMT', 'Content-Type': 'image/png', 'Server': 'TwistedWeb/16.1.1'}
and saving the file produces a valid PNG image, which I can view on my system.
What is going with SplashRequest that is messing up the PNG?
I found exactly the same issue using the screenshot pipline from the scrapy docs too.
EDIT: Interestingly, if I set breakpoints in the middleware process_response, the response.body is at that stage a valid PNG.
Turns out this was some beautifulsoup html parser middleware I had in the chain whose 'process_response' method was messing up the png bytes.
I am trying to create a dynamically created graph as a JPG file that I could use in Alexa Skill standard cards as part of response. The following code creates a JPG image when I run it locally on my computer, when using browser with URL "http://localhost:5000/image.jpg".
from flask import send_file
from flask import Flask
from PIL import Image, ImageDraw
from io import BytesIO
app = Flask(__name__)
app.config['DEBUG'] = True
def serve_pil_image(pil_img):
img_io = BytesIO()
pil_img.save(img_io, 'JPEG', quality=70)
img_io.seek(0)
return send_file(img_io, mimetype='image/jpeg')
#app.route('/image.jpg')
def serve_img():
size = (128,128)
background = (128,128,55)
xy = [(0,0),(10,10),(20,20),(30,12),(50,50),(70,9),(90,70)]
img = Image.new('RGB',size,background)
draw = ImageDraw.Draw(img)
draw.line(xy, fill=128, width=5)
return serve_pil_image(img)
if __name__ == '__main__':
app.run(debug=True)
However, when I deploy the same code to AWS Lambda service using Zappa I am getting the following error message (from CloudWatch logs):
An error occurred during JSON serialization of response: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte
Traceback (most recent call last):
File "/usr/lib64/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/usr/lib64/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib64/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte
Is there some configuration option to fix this problem? I haven't found any so far.
Binary Support is finally here! You should look at it and try again.
If you want to serve binary data (in this case Base64 images) through API Gateway, you need to set the following:
In the Method Response of your method
Set Content-Type as image/jpeg in HTTP 200 Status Response
Header
In the Integration Response of your method
Set Content-Type as 'image/jpeg' in Header Mappings. Mind the quotes!
With the AWS CLI, set contentHandling attribute to CONVERT_TO_BINARYon your Integration Response
Check to entire process in this great step-by step guide: https://stackoverflow.com/a/41434295/720665
(example is for a base64 encoded png image, but the gist of it is the same)
Hello im trying to send a multipart post request and using jython with commons httpclient 4.3.1.
http_client = DefaultHttpClient()
http_post = HttpPost(url)
bin = FileBody(File(file_name), ContentType.APPLICATION_XML)
me = MultipartEntity()
me.addPart('datei', bin)
http_post.setEntity(me)
print "Executing Post Request:", http_post.getRequestLine()
http_response = http_client.execute(http_post)
result_entity = http_response.getEntity()
return EntityUtils.toString(result_entity)
In my opinion the return value should a str with the content, but it is:
"type 'org.apache.http.conn.BasicManagedEntity'"
Where is my mistake?
I do not know the exact answer to your question. And today I have been trying to make a multipart post work from my jython script for a skiuli project I am working on.
Here is how I was able to do it.
First get ez_setup.py from: http://peak.telecommunity.com/dist/ez_setup.py
Then run jython ez_setup.py from the cmd prompt
Second get poster from: http://atlee.ca/software/poster/dist/0.8.1/
Unzip the file
Then run jython setup.py install
Last you can follow this sample code or see more on the atlee site:
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
import urllib2
register_openers()
upload_url = "http://your.website.com/upload-multipart.php"
#this will upload a file and a json object
#in php the file is in $_FILES and the json is in $_POST
params = {'file': open("test.txt", "rb"), 'jsonData': '[{"foo":"bar", "foo1":"bar1"}]'}
datagen, headers = multipart_encode(params)
request = urllib2.Request(upload_url, datagen, headers)
result = urllib2.urlopen(request)
print result.read()
I hope this helps someone out there. This example will also work for post multipart in python.