I was wondering if I can send different type of files to an email as an attachments. I only know how to send a text file using cUrl. Could someone give me some examples of how can I accomplish my goal ?
This is what I have so far :
curl --url "smtps://smtp.gmail.com:465" --mail-from "mail.gaming#gmail.com" --mail-rcpt "mail2#gmail.com" --ssl --user "mail#gmail.com:password" --upload-file "C:\Folder\File.txt"
Thank you for all the effort !
You can use multipart/mixed content to transmit your text body and each of your binary attachments.
Here is a template of file you could use to display a text file and attach 2 binary files :
From: Some Name <sender#gmail.com>
To: Some Name <receiver#gmail.com>
Subject: example of mail
Reply-To: Some Name <sender#gmail.com>
Cc:
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="MULTIPART-MIXED-BOUNDARY"
--MULTIPART-MIXED-BOUNDARY
Content-Type: multipart/alternative; boundary="MULTIPART-ALTERNATIVE-BOUNDARY"
--MULTIPART-ALTERNATIVE-BOUNDARY
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
Content-Disposition: inline
This is an email example. This is text/plain content inside the mail.
--MULTIPART-ALTERNATIVE-BOUNDARY--
--MULTIPART-MIXED-BOUNDARY
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="file.rar"
<HERE BASE64 ENCODED RAR FILE>
--MULTIPART-MIXED-BOUNDARY
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="file.zip"
<HERE BASE64 ENCODED ZIP FILE>
--MULTIPART-MIXED-BOUNDARY--
Note that the binary files are encoded in base64 and are transmitted as attachment.
Here is an example of building this file and send the email with a bash script :
#!/bin/bash
rtmp_url="smtp://smtp.gmail.com:587"
rtmp_from="sender#gmail.com"
rtmp_to="receiver#gmail.com"
rtmp_credentials="sender#gmail.com:secretpassword"
file_upload="data.txt"
echo "From: Some Name <$rtmp_from>
To: Some Name <$rtmp_to>
Subject: example of mail
Reply-To: Some Name <$rtmp_from>
Cc:
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=\"MULTIPART-MIXED-BOUNDARY\"
--MULTIPART-MIXED-BOUNDARY
Content-Type: multipart/alternative; boundary=\"MULTIPART-ALTERNATIVE-BOUNDARY\"
--MULTIPART-ALTERNATIVE-BOUNDARY
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
Content-Disposition: inline
This is an email example. This is text/plain content inside the mail.
--MULTIPART-ALTERNATIVE-BOUNDARY--
--MULTIPART-MIXED-BOUNDARY
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=\"file.rar\"" > "$file_upload"
# convert file.rar to base64 and append to the upload file
cat file.rar | base64 >> "$file_upload"
echo "--MULTIPART-MIXED-BOUNDARY
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=\"file.zip\"" >> "$file_upload"
# convert file.zip to base64 and append to the upload file
cat file.zip | base64 >> "$file_upload"
# end of uploaded file
echo "--MULTIPART-MIXED-BOUNDARY--" >> "$file_upload"
# send email
echo "sending ...."
curl -s "$rtmp_url" \
--mail-from "$rtmp_from" \
--mail-rcpt "$rtmp_to" \
--ssl -u "$rtmp_credentials" \
-T "$file_upload" -k --anyauth
res=$?
if test "$res" != "0"; then
echo "sending failed with: $res"
else
echo "OK"
fi
The received email will have the inline text/plain document and both of attachment document of type application/octet-stream :
Related
I'm trying to have a cgi-bin script given the path to a .docx file add a watermark to indicate it is a copy and present it. I have used Libreoffice to create the docx file. So my starting script just takes in the path and tries to present it to make sure the HTTP header is formed correctly. Good thing I have started out with baby steps as things do not work. When I run it with my Apache2 server, I get an error in the error.log file:
[Mon Jan 23 11:06:45.883760 2023] [cgid:error] [pid 1191] [client 127.0.0.1:42386] malformed header from script 'copydocx': Bad header: PK\x03\x04\x14, referer: http://robert-linux.local/builtsys/
and the file is not presented.
So what am I doing wrong?
Here are my scripts.
copydocx
#!/bin/bash
# -*-sh-*-
# copydocx - Present a .docx file with a copy watermark for a browser with a CGI script
# Arguments
# docx the path to a docx file
# Bring in URL forms arguments. Get from: https://github.com/adriansev/bin-scripts/blob/master /urlgetopt
eval `./urlgetopt -l "${QUERY_STRING}" 2>/dev/null`
# If an error present it and exit
present_error()
{
cat <<EOF
Content-type: text/html
<html><head>
<style>
red {
color: red
}
</style>
</head><body>
echo '<table width=100%><tr><td><form><input type=button value=Back onclick="history.back()"></form></td>
<td valign=top><font size=+2><red>ERROR: copydocx: $*</red></font></td>
</tr></table>
</body></html>
EOF
exit
}
# A terse set of error checks
test "${docx}" = "" && present_error No docx argument.
test ! -f "${docx}" && present_error File not found. "${docx}"
test "${docx##*.}" != "docx" && present_error File "${docx}" does not have a .docx suffix.
test ! -f copydocx.py && present_error File not found. copydocx.py
# Now get a copy of the docx file and present it
python3 copydocx.py
copydoc.py
import cgi
import sys
import os
# python3 script
# copydocx.py - Present a .docx file with a copy watermark for a browser
# Arguments
# docx the path to a docx file
def present_docx(filename):
# This if is so that 'python3 copydocx.py' runs
if filename != "":
statinfo = os.stat(filename)
size = statinfo.st_size
else:
size = 1234
filename = "notexisting.docx"
print("""Content-Type: application/octet-stream
Content-Disposition: attachment; filename="%s"
Content-Transfer-Encoding: binary
Content-Length: %d
""" % (filename, size))
os.system("cat %s" % filename)
form = cgi.FieldStorage()
docx = ""
if "docx" in form:
docx = form["docx"].value
# For now just present input to make sure we can present it at all.
present_docx(docx)
I hoped that this would work.
I am looking for the unix command(s) to calculate md5-content header to be used with IBM Cloud Object Storage API for deletion of multiple objects. I tried echo “request body….” | md5 | base64, however API response is - `
The Content-MD5 you specified was an invalid.
Curl CMD:
curl \
-H "Content-Type: text/plain;charset=utf-8" \
-H "Content-MD5: 75ff06f81643655397a5911ddc195ce8" \
-H "Authorization: $AuthToken" \
"https://<cos-endpoint-name>/<bucket-name>?delete" \
-d 'xml body...'
Error Response:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Error>
<Code>InvalidDigest</Code>
<Message>The Content-MD5 you specified was an invalid.</Message>
<Resource>/ghhsa-bucket-etl-dev/</Resource>
<RequestId>aed25243-22a1-477d-9ab8-b87780625a61</RequestId>
<httpStatusCode>400</httpStatusCode>
</Error>
Appreciate any pointers on this.
The md5 builtin is kinda weak, it's a bit more straightforward using openssl for encryption if possible. Using an example from the docs:
echo -n '<?xml version="1.0" encoding="UTF-8"?><Delete><Object><Key>pasture/cow-one</Key></Object><Object><Key>pasture/cow-two</Key></Object></Delete>' | openssl dgst -md5 -binary | openssl enc -base64
This returns /Gx4aOgplRXMRI2qXXqXiQ== which is what we'd expect.
I am working on salesforce client integration. I want to get access token and i am using
URL : https://login.salesforce.com/services/oauth2/token
Method : Post
Header : Content-Type: application/x-www-form-urlencoded
grant_type=password
client_id=XXXXXXXXXX
client_secret=XXXXXXXXXX
username=XXXXXXXXXX
password=XXXXXXXXXX
Above credential working fine with grant_type=authorization_code but while i switched to grant type password then its gives me
"http/1.1 400 bad request"
{"error":"invalid_client_id","error_description":"client identifier invalid"}
That looks right. Try this with curl:
curl https://login.salesforce.com/services/oauth2/token \
-d "grant_type=password" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "username=YOUR_USERNAME" \
-d "password=YOUR_PASSWORD"
This is what my chunked POST request looks like. I am trying to send chunks of data from an SD card on the arduino to a server through a chunked POST request. Need chunked as it will allow me to send the data which will not all fit into the arduino's memory at once.
POST /upload HTTP/1.1
User-Agent: Arduino
Host: ooboontoo
Accept: */*
Transfer-Encoding: chunked
25
this is the text, of this file, wooo!
1d
more test, of this file
0
However I am getting an error when the server tries parsing the request:
{"25\r\nthis is the text, of this file, wooo!\r\n"=>nil} Invalid
request: Invalid HTTP format, parsing fails.
I tried reading the chunked requests documentation but it appears there are multiple ways of doing the same thing so I am a bit confused on what is the correct way.
Any advice would be appreciated thanks!
EDIT:
here is the bash code I wrote to output the above request to telnet
run with: ./testit.sh | telnet
#! /bin/bash
#testit.sh
#Arduino Telnet HTTP POST tests
header="POST /upload HTTP/1.1\n"
header+="User-Agent: Arduino\n"
header+="Host: localhost 3000\n"
header+="Accept: */*\n"
header+="Transfer-Encoding: chunked\n"
thisfile="this is the text, of this file"
thisfilelen=${#thisfile}
printf -v hexlen '%x' $thisfilelen
thisfile2="more test, of this file"
thisfilelen2=${#thisfile2}
printf -v hexlen2 '%x' $thisfilelen2
end="0"
echo "open localhost 3000"
sleep 2
echo -e $header
echo -e $hexlen
echo -e $thisfile
echo -e $hexlen2
echo -e $thisfile2
echo -e $end
sleep 2
How can I include a file in a curl request form my working directory?
Below I've got a POST request that includes data for "first_name" and for "last_name", but now I need to add in the input for file. Theres examples out there where someone is ONLY sending a file along, but I'm trying to send 1 or more files, and other data.
curl
-H "Content-Type: application/json"
-d '{ first_name: "Donny", last_name: "P", my_file: ???? }'
https://sender.blockspring.com/api/blocks/319bfef4aad7f3477745048a2da3ae6a?api_key=2e0ef0c216078d60630d1321e67b243a
This can be only done with a multipart.
Manually building a multipart may be complex, so curl has a built-in -F option.
curl localhost:8000 -F "my_file=#file.ext" -F "name=daniel;last=P" -v
from man curl
-F, --form
(HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST
data using the Content-Type multipart/form-data according to RFC 2388. This enables uploading of binary files etc.
To
force the 'content' part to be a file, prefix the file name with an # sign. To just get the content part from a file,
prefix the file name with the symbol <. The difference between # and < is then that # makes a file get attached in the
post as a file upload, while the < makes a text field and just get the contents for that text field from a file.