Thanks Dan. I've made the changes you suggested. Good call about the date. I'll 
make sure to fix that. (Also, I am wanting it inline, so I removed that). In 
the actual code, I'll have it send the image in a better way like what you 
recommended, but will leave it alone for now since this program is more focused 
around the image. I tried running it again, and am still seeing the behavior. I 
tried removing the \r\n's from the image base64 encoding, but still no dice. I 
verified the image is valid by decoding my base64 encoded string and got back 
the image I was expecting. New code is attached.





---- On Sun, 26 Feb 2017 00:59:51 -0800 Dan Fandrich 
<[email protected]> wrote ----




On Sat, Feb 25, 2017 at 10:48:33PM -0800, Nicholas Chambers wrote:

> Hello all! I'm writing a little thing which involves emailing an image 
after $x

> amount of time. To make sure the code works, I wanted to put it in a 
separate

> program and test it. Currently the code I have is attached as mail.c, and 
the

> image I am trying to send is purple.jpeg. The email sends, and I get it in 
my

> inbox, but the image fails to load. Could someone help me figure out why?

> 

> Cheers,

> Nicholas Chambers

> 

> 

> 



> #include <stdio.h>

> #include <string.h>

> #include <curl/curl.h>

> 

> #define FROM "<[email protected]>"

> #define TO "<[email protected]>"

> 

> static const char *payload_text[] = {

> "To: " TO "\r\n",

> "From: " FROM "\r\n",

> "Subject: SMTPS Example\r\n",

> "Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n",



Naturally, you'll want to set this dynamically, since an old date will get lost

in people's in-boxes and old dates are used by some systems as a spam indicator.



> "User-Agent: My eMail Client\r\n",

> "MIME-Version: 1.0\r\n",

> "Content-Type: multipart/mixed;\r\n",

> " boundary=\"------------030203080101020302070708\"\r\n", 

> "\r\nThis is a multi-part message in MIME format.\r\n",

> "--------------030203080101020302070708\r\n",

> "Content-Type: text/plain; charset=utf-8; format=flowed\r\n",

> "Content-Transfer-Encoding: 7bit\r\n",

> "\r\n", /* empty line to divide headers from body, see RFC5322 */

> "The body of the message starts here.\r\n",

> "\r\n",

> "--------------030203080101020302070708\r\n",

> "Content-Type: text/jpeg; charset=utf-8; format=flowed\r\n",



You want image/jpeg here. And charset and format are meaningless for that type.



> "Content-Disposition: attachment;\r\n",



If you use this, then the image won't be shown inline in most e-mail clients.

Maybe that's what you want and maybe not.



> " filename=\"purple.jpeg\"\r\n",

> "\r\n",

> 
"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIC\r\n",



This header is only needed for the data: URL scheme. It's not a part of

image/jpeg data and needs to be removed.



[...]

> 
"XPUfCNuI+MfCPjKXqB7Q8Z4Z4p4YF9OgqVKlfSEqVKlRlh8J6R8Z6x8Ohj0h4Q8IeEDAEMoEr9J+\r\n",

> "jv1cR5jGMIbhxOJ2nP6f//Z\r\n",

> "--------------030203080101020302070708--\r\n",

> NULL

> };

> 

> struct upload_status {

> int lines_read;

> };

> 

> static size_t payload_source(void *ptr, size_t size, size_t nmemb, void 
*userp)

> {

> struct upload_status *upload_ctx = (struct upload_status *)userp;

> const char *data;

> 

> if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {

> return 0;

> }

> 

> data = payload_text[upload_ctx->lines_read];

> 

> if(data) {

> size_t len = strlen(data);

> memcpy(ptr, data, len);

> upload_ctx->lines_read++;



Sending data line-by-line works, but it's pretty inefficient. You could likely

send the entirety of the message in a single callback. Rather than storing the

message as an array of strings, I'd store it as a single string and send

(size*nmemb) bytes of that string each time until it's all sent.



> 

> return len;

> }

> 

> return 0;

> }

> 

> int main(void)

> {

> CURL *curl;

> CURLcode res = CURLE_OK;

> struct curl_slist *recipients = NULL;

> struct upload_status upload_ctx;

> 

> upload_ctx.lines_read = 0;

> 

> curl = curl_easy_init();

> if(curl) {

> /* This is the URL for your mailserver */ 

> curl_easy_setopt(curl, CURLOPT_URL, "smtp://localhost:25");

> 

> /* Note that this option isn't strictly required, omitting it will result

> * in libcurl sending the MAIL FROM command with empty sender data. All

> * autoresponses should have an empty reverse-path, and should be directed

> * to the address in the reverse-path which triggered them. Otherwise,

> * they could cause an endless loop. See RFC 5321 Section 4.5.5 for more

> * details.

> */ 

> curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM);

> 

> /* Add two recipients, in this particular case they correspond to the

> * To: and Cc: addressees in the header, but they could be any kind of

> * recipient. */ 

> recipients = curl_slist_append(recipients, TO);

> curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);

> 

> /* We're using a callback function to specify the payload (the headers and

> * body of the message). You could just use the CURLOPT_READDATA option to

> * specify a FILE pointer to read from. */ 

> curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);

> curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);

> curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);

> 

> /* Send the message */ 

> res = curl_easy_perform(curl);

> 

> /* Check for errors */ 

> if(res != CURLE_OK)

> fprintf(stderr, "curl_easy_perform() failed: %s\n",

> curl_easy_strerror(res));

> 

> /* Free the list of recipients */ 

> curl_slist_free_all(recipients);

> 

> /* curl won't send the QUIT command until you call cleanup, so you should

> * be able to re-use this connection for additional messages (setting

> * CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling

> * curl_easy_perform() again. It may not be a good idea to keep the

> * connection open for a very long time though (more than a few minutes

> * may result in the server timing out the connection), and you do want to

> * clean up in the end.

> */ 

> curl_easy_cleanup(curl);

> }

> 

> return (int)res;

> }

-------------------------------------------------------------------

Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library

Etiquette: https://curl.haxx.se/mail/etiquette.html






Attachment: mail.c
Description: Binary data

-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

Reply via email to