[sr-dev] git:master: xmlrpc(s): option for replacing double lf with crlf
Juha Heinanen
jh at tutpro.com
Wed Sep 23 14:37:49 CEST 2009
Andrei Pelinescu-Onciul writes:
> Added "double_lf_to_crlf" config parameter. When set double LFs in
> the input xmlrpc strings are replaced with CR LF. This is needed
> to work around some xmlrpc buggy clients that don't escape CR
> ('\r' should be escaped to 
 ). When using one of those buggy
> clients, use double LF as an escape for CR LF and turn this
> option on.Turning this option on makes it also more compatible with
> kamailio tools (kamailio mi xmlrpc always converts double LF to CR
> LF).
andrei,
that you very much for adding support for those "buggy clients". if the
clients really are buggy is controversial. xmlrpc spec has this:
What characters are allowed in strings? Non-printable characters? Null
characters? Can a "string" be used to hold an arbitrary chunk of
binary data?
Any characters are allowed in a string except < and &, which are
encoded as < and &. A string can be used to encode binary data.
many client vendors have interpreted this to mean that \r is a perfectly
valid character in xmlrpc string and need not to be escaped.
-- juha
> /* get_* flags: */
> #define GET_X_AUTOCONV 1
> #define GET_X_NOREPLY 2
> +#define GET_X_LFLF2CRLF 4 /* replace "\n\n" with "\r\n" */
>
> /* xml value types */
> enum xmlrpc_val_type{
> @@ -1294,14 +1299,16 @@ static int get_double(double* val, struct xmlrpc_reply* reply,
>
> /** Convert a parameter encoded in XML-RPC to a zero terminated string.
> *
> - * @param val A pointer to an integer variable where the result will be
> - stored.
> + * @param val A pointer to a char* variable where the result will be
> + * stored (the result is dynamically allocated, but it's garbage
> + * collected, so it doesn't have to be freed)
> * @param reply A pointer to XML-RPC reply being constructed (used to indicate
> * conversion errors).
> * @param doc A pointer to the XML-RPC request document.
> * @param value A pointer to the element containing the parameter to be
> * converted within the document.
> * @param flags : GET_X_AUTOCONV - try autoconverting
> + * GET_X_LFLF2CRLF - replace double '\n' with `\r\n'
> * GET_X_NOREPLY - do not reply
> * @return <0 on error, 0 on success
> */
> @@ -1360,6 +1367,18 @@ static int get_string(char** val, struct xmlrpc_reply* reply,
> ret=0;
> switch(type){
> case XML_T_STR:
> + if (flags & GET_X_LFLF2CRLF){
> + p=val_str;
> + while(*p){
> + if (*p=='\n' && *(p+1)=='\n'){
> + *p='\r';
> + p+=2;
> + continue;
> + }
> + p++;
> + }
> + }
> + /* no break */
> case XML_T_DATE: /* no special conversion */
> case XML_T_DOUBLE: /* no special conversion */
> if (add_garbage(JUNK_XMLCHAR, val_str, reply) < 0){
> @@ -1428,7 +1447,8 @@ static int rpc_scan(rpc_ctx_t* ctx, char* fmt, ...)
> va_start(ap, fmt);
> modifiers=0;
> read = 0;
> - f=autoconvert?GET_X_AUTOCONV:0;
> + f=(autoconvert?GET_X_AUTOCONV:0) |
> + (lflf2crlf?GET_X_LFLF2CRLF:0);
> while(*fmt) {
> if (!ctx->act_param) goto error;
> value = ctx->act_param->xmlChildrenNode;
> @@ -1737,8 +1757,11 @@ static int rpc_struct_scan(struct rpc_struct* s, char* fmt, ...)
> char* member_name;
> struct xmlrpc_reply* reply;
> int ret;
> + int f;
>
> read = 0;
> + f=(autoconvert?GET_X_AUTOCONV:0) |
> + (lflf2crlf?GET_X_LFLF2CRLF:0);
> va_start(ap, fmt);
> while(*fmt) {
> member_name = va_arg(ap, char*);
> @@ -1751,23 +1774,23 @@ static int rpc_struct_scan(struct rpc_struct* s, char* fmt, ...)
> case 't': /* Date and time */
> case 'd': /* Integer */
> int_ptr = va_arg(ap, int*);
> - if (get_int(int_ptr, reply, s->doc, value, 0) < 0) goto error;
> + if (get_int(int_ptr, reply, s->doc, value, f) < 0) goto error;
> break;
>
> case 'f': /* double */
> double_ptr = va_arg(ap, double*);
> - if (get_double(double_ptr, reply, s->doc, value, 0) < 0)
> + if (get_double(double_ptr, reply, s->doc, value, f) < 0)
> goto error;
> break;
>
> case 's': /* zero terminated string */
> char_ptr = va_arg(ap, char**);
> - if (get_string(char_ptr, reply, s->doc, value, 0) < 0) goto error;
> + if (get_string(char_ptr, reply, s->doc, value, f) < 0) goto error;
> break;
>
> case 'S': /* str structure */
> str_ptr = va_arg(ap, str*);
> - if (get_string(&str_ptr->s, reply, s->doc, value, 0) < 0)
> + if (get_string(&str_ptr->s, reply, s->doc, value, f) < 0)
> goto error;
> str_ptr->len = strlen(str_ptr->s);
> break;
>
>
> _______________________________________________
> sr-dev mailing list
> sr-dev at lists.sip-router.org
> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
More information about the sr-dev
mailing list