If you create a MIME.Message that has an array(string) for one of its headers, then you can't cast it to a string:
Unknown program: `/ (({"test1@siriushosting.com","test2@siriushosting.com"}),"\0") /usr/local/lib/pike/modules/MIME.pmod/module.pmod:1059: MIME.Message()-
__lambda_65759_3_line_1058("to")
Adam
On Tue, 11 Apr 2006 13:55:03 -0400 Adam Montague amontague@siriushosting.com wrote:
If you create a MIME.Message that has an array(string) for one of its headers, then you can't cast it to a string:
Unknown program: `/ (({"test1@siriushosting.com","test2@siriushosting.com"}),"\0") /usr/local/lib/pike/modules/MIME.pmod/module.pmod:1059: MIME.Message()-
__lambda_65759_3_line_1058("to")
Adam
The following appears to fix this, but I am not sure why we're doing a / "\0", so I'm not sure this is the right way to fix it. It also looks rather ugly.
--- module.pmod.orig Fri Aug 26 07:49:13 2005 +++ module.pmod Tue Apr 11 16:21:24 2006 @@ -1056,7 +1056,7 @@
return map( indices(headers), lambda(string hname){ - return map(headers[hname]/"\0", + return map(Array.flatten(map(arrayp(headers[hname]) ? headers[hname] : ({headers[hname]}), `/, "\0")), lambda(string header,string hname) { return hname+": "+header; },
--- module.pmod.orig Fri Aug 26 07:49:13 2005 +++ module.pmod Tue Apr 11 16:21:24 2006 @@ -1056,7 +1056,7 @@
return map( indices(headers), lambda(string hname){
return map(headers[hname]/"\0",
return map(Array.flatten(map(arrayp(headers[hname]) ? headers[hname] : ({headers[hname]}), `/, "\0")), lambda(string header,string hname) { return hname+": "+header; },
That looks wrong. If you want to reintroduce support for the array style, do it like this:
- return map(headers[hname]/"\0", + return map((arrayp(headers[hname])? + headers[hname] : headers[hname]/"\0"),
There should never be _both_ styles of multi-headers in the same object.
On Tue, 11 Apr 2006 21:00:01 +0000 (UTC) "Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum" 10353@lyskom.lysator.liu.se wrote:
--- module.pmod.orig Fri Aug 26 07:49:13 2005 +++ module.pmod Tue Apr 11 16:21:24 2006 @@ -1056,7 +1056,7 @@
return map( indices(headers), lambda(string hname){
return map(headers[hname]/"\0",
return map(Array.flatten(map(arrayp(headers[hname]) ? headers[hname] : ({headers[hname]}), `/, "\0")), lambda(string header,string hname) { return hname+": "+header; },
That looks wrong. If you want to reintroduce support for the array style, do it like this:
return map(headers[hname]/"\0",
return map((arrayp(headers[hname])?
headers[hname] : headers[hname]/"\0"),
There should never be _both_ styles of multi-headers in the same object.
Ok, that makes sense now that I know what the \0 business is all about.
I'm curious now, why does giving it an array work, when headers is declared as "mapping(string:string) headers;"?
Adam
I'm curious now, why does giving it an array work, when headers is declared as "mapping(string:string) headers;"?
Due to lack of #pragma strict_types. :-P Since the value which is assigned to it has type mapping(string:string|array(string)), it _might_ be the case that all the values are strings, so the assignment is allowed in non-strict mode.
You should use \0-separated strings to provide multiple values for a header. This is also what you get if you parse a string with multiple values for a header:
Pike v7.6 release 68 running Hilfe v3.5 (Incremental Pike Frontend)
MIME.Message("Received: foo\r\nReceived: bar\r\n\r\nHej")->headers;
(1) Result: ([ /* 1 element */ "received": "foo\0bar" ])
(string)MIME.Message("baz", (["received":"foo\0bar"]));
(2) Result: "Content-Length: 3\r\nReceived: foo\r\nReceived: bar\r\n\r\nbaz"
On Tue, 11 Apr 2006 20:50:01 +0000 (UTC) "Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum" 10353@lyskom.lysator.liu.se wrote:
You should use \0-separated strings to provide multiple values for a header. This is also what you get if you parse a string with multiple values for a header:
Pike v7.6 release 68 running Hilfe v3.5 (Incremental Pike Frontend)
MIME.Message("Received: foo\r\nReceived: bar\r\n\r\nHej")->headers;
(1) Result: ([ /* 1 element */ "received": "foo\0bar" ])
(string)MIME.Message("baz", (["received":"foo\0bar"]));
(2) Result: "Content-Length: 3\r\nReceived: foo\r\nReceived: bar\r\n\r\nbaz"
Ok, in that case the bug is in the create() method. It specifically allows: MIME.Message("baz", (["received":({"foo","bar"})]));
It also seems like an array of strings makes more sense than a single NULL delimited string. Should we change the constructor to convert arrays into NULL delimited strings, or vice versa?
Adam
I think we allow arrays to be used inside the objects because some applications find that easier to work with, so doing a conversion in the constructor would defeat the purpose of having them in the first place. Remember that ->headers can be accessed by user code.
Sounds like a Roxen-legacy thing. For some reason, way back in the day, it was decided that handling multiple same-named headers would be best done by appending them into a null-terminated string. I guess that behavior was inherited by MIME.Message.
pike-devel@lists.lysator.liu.se