PHPMailer not setting charset in header correctly - character-encoding

Im using PHPMailer 6.1.8 for sending plain text mails. I want to send them with utf8 encoding but in Thunderbird the received eMails still have the wrong content type in header:
Content-Type: text/plain; charset=iso-8859-1
My PHP code:
function sendMail($subject, $body, $to, $from = 'mail#server1.intranet.lan', array $cc = [], array $bcc = []) {
$mail = new PHPMailer();
$mail->charSet = 'UTF-8';
$mail->setLanguage = 'de';
$mail->isSMTP();
$mail->Host = '****';
$mail->SMTPAuth = true;
$mail->Username = '****';
$mail->Password = '****';
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->setFrom($from);
$mail->addAddress($to);
foreach ($cc as $address) {
$mail->addCC($address);
}
foreach ($bcc as $address) {
$mail->addBCC($address);
}
$mail->Subject = $subject;
$mail->Body = $body;
$mail->send();
}

PHP is case-sensitive for property names, so change this:
$mail->charSet = 'UTF-8';
to
$mail->CharSet = 'UTF-8';
You might consider this as a hint to get a decent IDE, since any good one would have flagged this without you even running the code.

Related

Mirth HTTP POST request with Parameters using Javascript

The following code by #Nick Rupley works well, but, I need also to pass parameters as POST. How do we pass POST parameters?
from java.net.URL
var url = new java.net.URL('http://localhost/myphpscript.php');
var conn = url.openConnection();
var is = conn.getInputStream();
try {
var result = org.apache.commons.io.IOUtils.toString(is, 'UTF-8');
} finally {
is.close();
}
2 Parameters to pass: firstname="John" and lastname="Smith"
Thanks
This will POST with MIME type application/x-www-form-urlencoded. It is using apache httpclient, which is already included with mirth, as it is used internally by the HTTP Sender connector, as well as some other functionality. Other solutions may require you to download jars and add library resources.
Closer is part of Google Guava, which is also already included with mirth.
Check comments where Rhino javascript allows for simplified code compared to direct Java conversion.
It wouldn't be a bad idea to wrap all of this up in a code template function.
var result;
// Using block level Java class imports
with (JavaImporter(
org.apache.commons.io.IOUtils,
org.apache.http.client.methods.HttpPost,
org.apache.http.client.entity.UrlEncodedFormEntity,
org.apache.http.impl.client.HttpClients,
org.apache.http.message.BasicNameValuePair,
com.google.common.io.Closer))
{
var closer = Closer.create();
try {
var httpclient = closer.register(HttpClients.createDefault());
var httpPost = new HttpPost('http://localhost:9919/myphpscript.php');
// javascript array as java List
var postParameters = [
new BasicNameValuePair("firstname", "John"),
new BasicNameValuePair("lastname", "Smith")
];
// Rhino JavaBean access to set property
// Same as httpPost.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8"));
httpPost.entity = new UrlEncodedFormEntity(postParameters, "UTF-8");
var response = closer.register(httpclient.execute(httpPost));
// Rhino JavaBean access to get properties
// Same as var is = response.getEntity().getContent();
var is = closer.register(response.entity.content);
result = IOUtils.toString(is, 'UTF-8');
} finally {
closer.close();
}
}
logger.info(result);
Following is a complete working HTTP POST request solution tested in Mirth 3.9.1
importPackage(Packages.org.apache.http.client);
importPackage(Packages.org.apache.http.client.methods);
importPackage(Packages.org.apache.http.impl.client);
importPackage(Packages.org.apache.http.message);
importPackage(Packages.org.apache.http.client.entity);
importPackage(Packages.org.apache.http.entity);
importPackage(Packages.org.apache.http.util);
var httpclient = HttpClients.createDefault();
var httpPost = new HttpPost("http://localhost/test/");
var httpGet = new HttpGet("http://httpbin.org/get");
// FIll in each of the fields below by entering your values between the ""'s
var authJSON = {
"userName": "username",
"password": "password",
};
var contentStr =JSON.stringify(authJSON);
//logger.info("JSON String: "+contentStr);
httpPost.setEntity(new StringEntity(contentStr,ContentType.APPLICATION_JSON,"UTF-8"));
httpPost.setHeader('Content-Type', 'application/json');
httpPost.setHeader("Accept", "application/json");
// Execute the HTTP POST
var resp;
try {
// Get the response
resp = httpclient.execute(httpPost);
var statusCode = resp.getStatusLine().getStatusCode();
var entity = resp.getEntity();
var responseString = EntityUtils.toString(entity, "UTF-8");
var authHeader = resp.getFirstHeader("Authorization");
// logger.info("Key : " + authHeader.getName()+" ,Value : " + authHeader.getValue());
// Save off the response and status code to Channel Maps for any potential troubleshooting
channelMap.put("responseString", responseString);
channelMap.put("statusCode", statusCode);
// Parse the JSON response
var responseJson = JSON.parse(responseString);
// If an error is returned, manually throw an exception
// Else save the token to a channel map for use later in the processing
if (statusCode >= 300) {
throw(responseString);
} else {
logger.info("Token: "+ authHeader.getValue());
channelMap.put("token", authHeader.getValue());
}
} catch (err) {
logger.debug(err)
throw(err);
} finally {
resp.close();
}
This linke + above answers helped me to come up with a solution
https://help.datica.com/hc/en-us/articles/115005322946-Advanced-Mirth-Functionality
There are plenty of libraries that can help you with URI building in Java. You can find them below. But if you want to stay in Javascript just add your parameters manually than create it.
function addParam(uri, appendQuery) {
if (appendQuery != null) {
uri += "?" + appendQuery;
}
return uri;
}
var newUri = addParam('http://localhost/myphpscript.php', 'firstname="John"');
var url = new java.net.URL(newUri);
Java EE 7
import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();
org.apache.httpcomponents:httpclient:4.5.2
import org.apache.http.client.utils.URIBuilder;
...
return new URIBuilder(url).addParameter(key, value).build();
org.springframework:spring-web:4.2.5.RELEASE
import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();
There are multiple ways to provide http client connection with java. Since your question is specific to java.net.URL I will stick to that.
Basically you can pass parameters as POST, GET, PUT, DELETE using .setRequestMethod this will be used along with new java.net.URL(ur-destination-url).openConnection();
Here is the complete code I've using javascript in Mirth using the same java.net.URL use this it will be helpful. It worked well for me.
do {
try {
// Assuming your writing this in the destination Javascript writer
var data = connectorMessage.getEncodedData();
//Destination URL
destURL = “https://Your-api-that-needs-to-be-connected.com”;
//URL
var url = new java.net.URL(destURL);
var conn = url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
enter code here
conn.setRequestProperty (“Authorization”, globalMap.get(‘UniversalToken’));
conn.setRequestMethod(“DELETE”); // this can be post or put or get or patch
conn.setRequestProperty(“Content-length”, data.length());
conn.setRequestProperty(“Content-type”, “application/json”);
var outStream = conn.getOutputStream();
var outWriter = new java.io.OutputStreamWriter(outStream);
outWriter.write(data);
outWriter.close();
// Get response Code (200, 500 etc.)
var respCode = conn.getResponseCode();
if (respCode != 200) {
// Write error to error folder
var stringData = response.toString() + “\n”;
FileUtil.write(“C:/Outbox/Errors/” + $(“originalFilename”) + “.ERROR_RESPONSE”, false, stringData);
// Return Error to Mirth to move the file to the error folder
return ERROR;
}
errorCond = “false”;
break;
}
catch(err) {
channelMap.put(“RESPONSE”, err);
responseMap.put(“WEBSVC”, ResponseFactory.getErrorResponse(err))
throw(err);
// Can return ERROR, QUEUED, SENT
// This re-queues the message on a fatal error. I”m doing this since any fatal message may be
// caused by HTTPS connect errors etc. The message will be re-queued
return QUEUED; // Re-queue the message
java.lang.Thread.sleep(6000); // 6 seconds * 10
errorCond = “true”;
}
}
while (errorCond == “true”);

Sending emails from MVC application hosted in Azure not working

Ive gone through many posts, but none seem to work.
I have an MVC application hosted in Azure as an app service and sending of mails is not working. It works on my local.
I have my SMTP details stored in my Web.Config:
Web.Config
<appSettings>
<!--To Send Mail-->
<add key="MailServerSMTP" value="mail.appname.com" />
<add key="MailServerSMTP_UserName" value="alerts#appname.com" />
<add key="MailServerSMTP_Password" value="Password" />
</appSettings>
Below is my sending function:
Email sending function
public void SendMessage(string subject, string messageBody, string fromAddress, string toAddress, string ccAddress, string sFileName, string sFileName2)
{
try
{
MailMessage message = new MailMessage();
SmtpClient client = new SmtpClient();
//Thread T1 = new Thread(delegate ()
//{
//Set the sender's address
message.From = new MailAddress(fromAddress);
//Allow multiple "To" addresses to be separated by a semi-colon
if ((toAddress.Trim().Length > 0))
{
foreach (string addr in toAddress.Split(';'))
{
message.To.Add(new MailAddress(addr));
}
}
//Allow multiple "Cc" addresses to be separated by a semi-colon
if ((ccAddress.Trim().Length > 0))
{
foreach (string addr in ccAddress.Split(';'))
{
message.CC.Add(new MailAddress(addr));
}
}
//Set the subject and message body text
if (!string.IsNullOrEmpty(sFileName))
{
Attachment obAttachement = new Attachment(sFileName);
message.Attachments.Add(obAttachement);
}
if (!string.IsNullOrEmpty(sFileName2))
{
Attachment obAttachement = new Attachment(sFileName2);
message.Attachments.Add(obAttachement);
}
message.Subject = subject;
message.Body = messageBody;
message.IsBodyHtml = true;
string path = System.AppDomain.CurrentDomain.BaseDirectory;
path = path.Replace("bin\\Debug\\", "Content\\img");
//if (path.Substring(path.Length - 6) != "Images")
//{
// path = path + "Images";
//}
if (path.GetLast(6) != "Content\\img")
{
path = path + "Content\\img";
}
Attachment ImageAttachment = new Attachment(path + "\\SystemicLogic_Transparent.png");
// Set the ContentId of the attachment, used in body HTML
ImageAttachment.ContentId = "SystemicLogic_Transparent.png";
// Add an image as file attachment
message.Attachments.Add(ImageAttachment);
message.Body = messageBody;
//Set the SMTP server to be used to send the message
//client.Host = "smtp.jumpstartcom.co.za"
string sSMTP_Username = ConfigurationManager.AppSettings["MailServerSMTP_UserName"].ToString();
string sSMTP_Password = ConfigurationManager.AppSettings["MailServerSMTP_Password"].ToString();
string appname = ConfigurationManager.AppSettings["MailServerSMTP"];
client.Credentials = new System.Net.NetworkCredential(sSMTP_Username, sSMTP_Password);
client.Host = appname;
client.Port = 587;
//client.EnableSsl = true;
//Send the e-mail message
//client.SendAsync(message, null);
client.Send(message);
//});
//T1.Start();
}
catch (Exception ex)
{
}
}
I have tried enabling SSL and using port 25. I have tried setting the port to 465 and 587 and emails are not coming through though.
Is there a specific port that needs to be used, or something I am doing wrong ?
Thanks for any help in advance!

Uploading large files to Sharepoint 365

I'm using the CSOM to upload files to a Sharepoint 365 site.
I've logged in succesfully with Claims based authentication using methods found here "http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx"
But using SaveBinaryDirect on the ClientContext fails with a 405 due to cookies being attached to request too late.
Another method of using CSOM to upload files is similar to below. But with SP 365, this limits the file size to about 3 meg.
var newFileFromComputer = new FileCreationInformation
{
Content = fileContents,
Url = Path.GetFileName(sourceUrl)
};
Microsoft.SharePoint.Client.File uploadedFile = customerFolder.Files.Add(newFileFromComputer);
context.Load(uploadedFile);
context.ExecuteQuery();
Is there ANY way to do this using CSOM, SP 365 and file sizes up to say 100 meg?
Indeed while trying to upload a file in SharePoint Online which size exceeds 250MB file limit the following exception will occur:
Response received was -1,
Microsoft.SharePoint.Client.InvalidClientQueryExceptionThe request
message is too big. The server does not allow messages larger than
262144000 bytes.
To circumvent this error chunked file upload methods have been introduced which support uploading files larger than 250 MB. In the provided link there is an sample which demonstrates how to utilize it via SharePoint CSOM API.
Supported versions:
SharePoint Online
SharePoint On-Premise 2016 or above
The following example demonstrates how to utilize chunked file upload methods in SharePoint REST API:
class FileUploader
{
public static void ChunkedFileUpload(string webUrl, ICredentials credentials, string sourcePath, string targetFolderUrl, int chunkSizeBytes, Action<long, long> chunkUploaded)
{
using (var client = new WebClient())
{
client.BaseAddress = webUrl;
client.Credentials = credentials;
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
var formDigest = RequestFormDigest(webUrl, credentials);
client.Headers.Add("X-RequestDigest", formDigest);
//create an empty file first
var fileName = System.IO.Path.GetFileName(sourcePath);
var createFileRequestUrl = string.Format("/_api/web/getfolderbyserverrelativeurl('{0}')/files/add(url='{1}',overwrite=true)", targetFolderUrl, fileName);
client.UploadString(createFileRequestUrl, "POST");
var targetUrl = System.IO.Path.Combine(targetFolderUrl, fileName);
var firstChunk = true;
var uploadId = Guid.NewGuid();
var offset = 0L;
using (var inputStream = System.IO.File.OpenRead(sourcePath))
{
var buffer = new byte[chunkSizeBytes];
int bytesRead;
while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
if (firstChunk)
{
var endpointUrl = string.Format("/_api/web/getfilebyserverrelativeurl('{0}')/startupload(uploadId=guid'{1}')", targetUrl, uploadId);
client.UploadData(endpointUrl, buffer);
firstChunk = false;
}
else if (inputStream.Position == inputStream.Length)
{
var endpointUrl = string.Format("/_api/web/getfilebyserverrelativeurl('{0}')/finishupload(uploadId=guid'{1}',fileOffset={2})", targetUrl, uploadId, offset);
var finalBuffer = new byte[bytesRead];
Array.Copy(buffer, finalBuffer, finalBuffer.Length);
client.UploadData(endpointUrl, finalBuffer);
}
else
{
var endpointUrl = string.Format("/_api/web/getfilebyserverrelativeurl('{0}')/continueupload(uploadId=guid'{1}',fileOffset={2})", targetUrl, uploadId, offset);
client.UploadData(endpointUrl, buffer);
}
offset += bytesRead;
chunkUploaded(offset, inputStream.Length);
}
}
}
}
public static string RequestFormDigest(string webUrl, ICredentials credentials)
{
using (var client = new WebClient())
{
client.BaseAddress = webUrl;
client.Credentials = credentials;
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
client.Headers.Add("Accept", "application/json; odata=verbose");
var endpointUrl = "/_api/contextinfo";
var content = client.UploadString(endpointUrl, "POST");
var data = JObject.Parse(content);
return data["d"]["GetContextWebInformation"]["FormDigestValue"].ToString();
}
}
}
Source code: FileUploader.cs
Usage
var userCredentials = GetCredentials(userName, password);
var sourcePath = #"C:\temp\jellyfish-25-mbps-hd-hevc.mkv"; //local file path
var targetFolderUrl = "/Shared Documents"; //library reltive url
FileUploader.ChunkedFileUpload(webUrl,
userCredentials,
sourcePath,
targetFolderUrl,
1024 * 1024 * 5, //5MB
(offset, size) =>
{
Console.WriteLine("{0:P} completed", (offset / (float)size));
});
References
Always use File Chunking to Upload Files > 250 MB to SharePoint Online
Well, I haven't found a way to do it with the CSOM and that is truly infuriating.
A work around was posted by SEvans at the comments on http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx .
Basically just do an http put and attach the cookie collection from the claims based authentication. SEvans posted workaround is below
Great piece of code Wichtor. As others have noted, SaveBinaryDirect does not work correctly, as the FedAuth cookies never get attached to the HTTP PUT request that the method generates.
Here's my workaround:
// "url" is the full destination path (including filename, i.e. https://mysite.sharepoint.com/Documents/Test.txt)
// "cookie" is the CookieContainer generated from Wichtor's code
// "data" is the byte array containing the files contents (used a FileStream to load)
System.Net.ServicePointManager.Expect100Continue = false;
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
request.Method = "PUT";
request.Accept = "*/*";
request.ContentType = "multipart/form-data; charset=utf-8";
request.CookieContainer = cookie; request.AllowAutoRedirect = false;
request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
request.Headers.Add("Accept-Language", "en-us");
request.Headers.Add("Translate", "F"); request.Headers.Add("Cache-Control", "no-cache"); request.ContentLength = data.Length;
using (Stream req = request.GetRequestStream())
{ req.Write(data, 0, data.Length); }
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream res = response.GetResponseStream();
StreamReader rdr = new StreamReader(res);
string rawResponse = rdr.ReadToEnd();
response.Close();
rdr.Close();

Blackberry: KSoap2 XmlPullParserException expected:END_TAG error

I'm receiving the following error on my Blackberry app:
org.xmlpull.v1.XmlPullParserException:expected"END_TAG</{http://schemas.xmlsoap.org/soap/envelope/}soap:Fault>#3:181 in java.io.InputStreamReader#d88bc808)
I'm using KSoap2 to create the envelope, when I get the response I use the following code to give me the XML, maybe I shouldn't be (this code is obviously incomplete):
String serviceUrl = WS_URL + Globals.theApp.getConnectionString();
String serviceNamespace = "http://www.mysite.com/";
String soapAction = "http://www.mysite.com/postMessage";
SoapObject rpc = new SoapObject(serviceNamespace, "postMessage");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = rpc;
envelope.dotNet = true;
envelope.encodingStyle = SoapSerializationEnvelope.XSD;
envelope.addMapping("http://www.mysite.com/", "Message", new Message().getClass());
PropertyInfo pinfo = new PropertyInfo();
pinfo.name = "myMessage";
pinfo.namespace = serviceNamespace;
pinfo.type = Message.MESSAGE_CLASS;
rpc.addProperty("Message", message);
HttpTransport ht = new HttpTransport(serviceUrl);
ht.debug = true;
String xmlResponse;
try
{
ht.call(soapAction, envelope);
xmlResponse = envelope.getResponse().toString();
SoapObject myResponse = (SoapObject)envelope.getResponse();
xmlResponse = ht.responseDump;
I'm using ht.responseDump to get me the xml string (because before it wasn't sending back anything in XML.) From there I try to parse xmlResponse etc.....
But I get that error, why?? Is ht.responseDump not the best way to go about this? What does ht.debug do?? Why is my xml getting cut off??
Thanks in advance. I really need some help.

Flash/Flex sending XML to Rails App

I'm trying to send some XML to a rails app in Flex. I'm using the URLRequest and URLLoader objects. However, I'm having trouble determining how to send the XML and _method parameter to the rails app using these flash objects. Below is how I'm currently trying to achieve this.
var request:URLRequest = new URLRequest();
request.method = URLRequestMethod.POST;
request.data = new Object();
request.data.xml = Blog.xml.toXMLString();
request.contentType = "text/xml";
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, saveCompleteHandler);
var saveUrl:String = "";
saveUrl = BASE_URL;
if (Blog.isNewBlog)
{
// Set the rails REST method.
request.data._method = "POST";
saveUrl += "blogs.xml";
}
else
{
// Set the rails REST method.
request.data._method = "PUT";
saveUrl += "blogs/" + Blog.id.toString() + ".xml";
}
request.url = saveUrl;
//trace(request.data.toString());
loader.load(request);
However the only data that is getting sent to the server is [Object object]. If some one could let me know where I'm going wrong I'd greatly appreciate it. Thanks.
You probably want to use a URLVariables object for request.data.
var request:URLRequest = new URLRequest();
request.data = new URLVariables();
request.data.xml = Blog.xml.toXMLString();
...
When the data is serialized, I think it will be in the format you're expecting. I'm basing this off of the API description for URLRequest.data.
Old post, but may be useful: besides
request.data.xml = Blog.xml.toXMLString();
you can also do
request.data['xml'] = Blog.xml.toXMLString();

Resources