0

So this is weird.

I'm getting a 451 error on an email that's being generated, except that what causes it is the plain text portion of the subject line :s

This subject line gets through fine:

$this->email->subject('New task in "'.$data['property_name'].'"');

This one causes the 451 error:

$this->email->subject('A user has completed their task in "'.$data['property_name'].'"');

For reference, Error 451 is for bare LF's (http://cr.yp.to/docs/smtplf.html). It's normally caused by not declaring the line ending rules in the settings, or using single quotes, i.e. '/r/n/' instead of "/r/n". My settings are correct and emails work fine.

Something notable in the the debugger, is that the longer line appears as so:

Subject: =?utf-8?Q?A_user_has_completed_their_task_in_"TASKNAME
?=
 =?utf-8?Q?"?=

Whereas the working one appears like:

Subject: =?utf-8?Q?New_task_in_"TASKNAME"?=

Is this a CI bug?

Nathan Hornby
  • 1,423
  • 16
  • 32

2 Answers2

0

I think you're mixing up single and double quotes. Try:

$this->email->subject('A user has completed their task in '.$data['property_name']);
Mudshark
  • 3,253
  • 15
  • 20
  • Hi Mudshark - no those double quotes are part of the string, i.e. - New task in "Foo". – Nathan Hornby Dec 17 '13 at 15:04
  • @NathanHornby They may be breaking the encoding of the string within that request. Have you tried removing the quotes to see if it passes without them. – mic Dec 17 '13 at 15:19
  • Hi @micb - even if that's the case it doesn't present a solution, because they need to be there - and why would it only reject them when the text before it is slightly longer? I'll give it a try it just seems like a bit of a non-starter to me. It looks to me that the length of the line is the issue, at least given the difference in output in the debug. At least if that were the problem it'd be a more clearcut bug I suppose. – Nathan Hornby Dec 18 '13 at 10:53
  • Just a thought, could this http://stackoverflow.com/questions/11794698/max-line-length-in-mail be the problem then since the one that is failing is a lot longer than the other and because the quotes are going to a new row they are breaking it? – mic Dec 18 '13 at 14:09
  • Very interesting! That would explain why it's pushing it onto two lines (when you'd expect line columns to be irrelevant). In which case you're likely partly correct - in that it's the quotes causing the problem, not through any syntax issue, but due to the behaviour of the mail parser (I'm guessing SMTP works the same given the output I've seen). I haven't had a chance to test this fully - but it seems that we'll have to be quite careful with subject lines as there are varying length values that need to be included. – Nathan Hornby Dec 19 '13 at 16:16
  • I've just done some more testing and it's quite difficult to recreate, I seem to have to have a length that leaves the quote on its own on the new line! As in if there's a bit of text included with it it seems to handle it OK. Oddness. – Nathan Hornby Dec 19 '13 at 16:31
0

Where are you getting the 451 error from? I'm seeing 451 being reported as a local error in processing.

The Email class breaks down the subject string if it's longer than 76 characters:

109 // Line length must not exceed 76 characters, so we adjust for
110 // a space, 7 extra characters =??Q??=, and the charset that we will add to each line

You can see it in action:

function test()
{
    echo "<pre>";
    print_r($this->_prep_q_encoding('A user had completed their task in "Going to change string to something"'));
}


function _prep_q_encoding($str, $from = FALSE)
{
    $this->crlf= "\n";  
    $this->charset = 'utf-8';
    $str = str_replace(array("\r", "\n"), array('', ''), $str);

    // Line length must not exceed 76 characters, so we adjust for
    // a space, 7 extra characters =??Q??=, and the charset that we will add to each line
    $limit = 75 - 7 - strlen($this->charset);

    // these special characters must be converted too
    $convert = array('_', '=', '?');

    if ($from === TRUE)
    {
        $convert[] = ',';
        $convert[] = ';';
    }

    $output = '';
    $temp = '';

    for ($i = 0, $length = strlen($str); $i < $length; $i++)
    {
        // Grab the next character
        $char = substr($str, $i, 1);
        $ascii = ord($char);

        // convert ALL non-printable ASCII characters and our specials
        if ($ascii < 32 OR $ascii > 126 OR in_array($char, $convert))
        {
            $char = '='.dechex($ascii);
        }

        // handle regular spaces a bit more compactly than =20
        if ($ascii == 32)
        {
            $char = '_';
        }

        // If we're at the character limit, add the line to the output,
        // reset our temp variable, and keep on chuggin'
        if ((strlen($temp) + strlen($char)) >= $limit)
        {
            $output .= $temp.$this->crlf;
            $temp = '';
        }

        // Add the character to our temporary line
        $temp .= $char;
    }

    $str = $output.$temp;

    // wrap each line with the shebang, charset, and transfer encoding
    // the preceding space on successive lines is required for header "folding"
    $str = trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $str));

    return $str;
}

Which outputs

=?utf-8?Q?A_user_had_completed_their_task_in_"Going_to_change_string_to_?=
 =?utf-8?Q?something"?=

I've seen other's have problems with the way email configs are set. Do you have

$config['crlf'] = "\r\n"; //double quotes ("), not single (') 
$config['newline'] = "\r\n";  //double quotes ("), not single (') 

set?

stormdrain
  • 7,915
  • 4
  • 37
  • 76
  • Hi Stormdrain. It looks like your email was sent using mail, and not SMTP, that's likely a significant difference considering that a 451 error is an SMTP error. – Nathan Hornby Dec 18 '13 at 10:51
  • EDIT: Also it's worth noting that the resulting string from the 'property_name' variable is much longer than the 'TASKNAME' example, something like 'Lorem ipsum dolor sit amet pro' would make for a better test string, as I have a feeling the length is important. Thanks for your input! – Nathan Hornby Dec 18 '13 at 10:58
  • My apologies. Yes, length is important. Does the "TASKNAME" string have any special chars (single/double quote, ampersand, etc)? – stormdrain Dec 18 '13 at 12:07
  • Nope, no special characters! That was my first guess too :) – Nathan Hornby Dec 18 '13 at 13:20
  • I updated the "answer". Not sure if helpful. Need some clarification. – stormdrain Dec 18 '13 at 15:13
  • Yup, the settings are set correctly, as you indicated (all other mail works fine) - I covered that in the question :) I think it's definitely the two lines issue, and the fact that a quote mark ends up on its own on a new line seems to cause some issues. I'd still class that as a bug - but it's one we can probably work around (and seems like a bug in the email protocol, more than CI). Incidentally I'm getting the error through the standard debug output for the email class. – Nathan Hornby Dec 19 '13 at 16:21
  • Yup, seems it's caused through a single quote mark ending up on its own line, so we just have to make sure that a variable length string is never that exact length! – Nathan Hornby Dec 19 '13 at 16:33