Forum OpenACS Development: XML-RPC String limit

Collapse
Posted by Iuri Sampaio on
Hi there,

Is there a limit of chars to pass through xml-rpc?

I'm trying to send a xmlrpc request and the code breaks when the content has more than 99754 characters. Less than that it works fine, but for bigger contents it breaks the code at /packages/xml-rpc/tcl/xmlrpc-procs.tcl, at line 671.

ns_log debug "xmlrpc::invoke REQUEST: $xml"
if {[catch {set doc [xml_parse -persist $xml]} err_msg]} {
ns_log Notice "ERROR SDSAFAFE"
set result [xmlrpc::fault 1 "error parsing request: $err_msg"]

Plus,
Where do I find the content limit imposition within [xml_parse] ?

p.s. OACS and NGINX are properly configured with maximum size limits.

[12/Apr/2017:12:27:04][26465.7fa469234700][-conn:1contact:0-] Notice: Running ad_proc xmlrpc::invoke
[12/Apr/2017:12:27:04][26465.7fa469234700][-conn:1contact:0-] Notice:
[12/Apr/2017:12:27:04][26465.7fa469234700][-conn:1contact:0-] Notice: ERROR SDSAFAFE
[12/Apr/2017:12:27:04][26465.7fa469234700][-conn:1contact:0-] Error: xmlrpc::invoke: error parsing request: error "Unexpected end" at position 0
""
[12/Apr/2017:12:27:04][26465.7fa469234700][-conn:1contact:0-] Notice: checking entry from host_node_map ->
[12/Apr/2017:12:27:04][26465.7fa469234700][-conn:1contact:0-] Warning: ignore untrusted host header field:
[12/Apr/2017:12:27:04][26465.7fa469234700][-conn:1contact:0-] Notice: ignore non-existing or untrusted host header, fall back to 1c.1contact.ch
[12/Apr/2017:12:27:04][26465.7fa469234700][-conn:1contact:0-] Error: can't read "doc": no such variable
while executing
"xml_doc_free $doc"
(procedure "xmlrpc::invoke" line 46)
invoked from within
"xmlrpc::invoke $content"
("uplevel" body line 15)
invoked from within
"uplevel {
# /packages/xml-rpc/www/index.tcl
ad_page_contract {
Accept XML-RPC POST requests and processes them. GET requests are shown
lin..."
(procedure "code::tcl::/var/www/1contact/packages/xml-rpc/www/index" line 2)
invoked from within
"code::tcl::$__adp_stub"
("uplevel" body line 12)
invoked from within
"uplevel {

if { [file exists $__adp_stub.tcl] } {

# ensure that data source preparation procedure exists and is up-to-date
..."
(procedure "adp_prepare" line 2)
invoked from within
"adp_prepare"
invoked from within
"template::adp_parse [file rootname [ad_conn file]] {}"
(procedure "adp_parse_ad_conn_file" line 6)
invoked from within
"$handler"
("uplevel" body line 2)
invoked from within
"uplevel $code"
invoked from within
"ad_try {
$handler
} ad_script_abort val {
# do nothing
}"
invoked from within
"rp_serve_concrete_file [ad_conn file]"
(procedure "::nsf::procs::rp_serve_abstract_file" line 60)
invoked from within
"rp_serve_abstract_file "$root/$extra_url""
("uplevel" body line 2)
invoked from within
"uplevel $code"
invoked from within
"ad_try {
rp_serve_abstract_file "$root/$extra_url"
set tcl_url2file([ad_conn url]) [ad_conn file]
set ..."
called from rp_handler
POST http://1c.1contact.ch/RPC2/? referred by '' peer 127.0.0.1 user_id 0
post-data:

X-Forwarded-For: 201.6.135.96
Host: 127.0.0.1:8000
Connection: close
Content-Length: 100001
Accept-Encoding: gzip
Content-Type: text/xml
User-Agent: Python-xmlrpc/3.5

Collapse
2: Re: XML-RPC String limit (response to 1)
Posted by Gustaf Neumann on
The code you pasted above is from line 648 [1] (parsing the xml text), while you mentioned that it breaks at 671 [2] (invoke method).

Can it be, that the invoked method has problems with the size?
It is really astonishing, that the Content-Length you posted above is 100001. When you check the received $xml, is this correctly terminated (i.e. tags are closed, or is the a ">" at the missing?

[1] https://github.com/openacs/xml-rpc/blob/master/tcl/xml-rpc-procs.tcl#L648
[2] https://github.com/openacs/xml-rpc/blob/master/tcl/xml-rpc-procs.tcl#L670

Collapse
3: Re: XML-RPC String limit (response to 2)
Posted by Iuri Sampaio on
Hi Gustaf,

The invoked method? Do you mean the new ad_proc that I created (i.e. iurix_robot::parse_json or [xmlrpc::invoke] ?

I haven't post the actual content here. It was just an example. Plus, the new method has nothing yet but logs. It only prints the arguments within the file error.log. Furthermore, "<, &, >, etc" special tags are not missing.

Certainly, the xml received has no sintax problems. I split the huge request (i.e. the one with 100000 chars) into two requests of 50000 chars and both worked just fine.

The second argument of the new xmlrpc ad_proc is a json array. See bellow.

ad_proc -public ix_robot.parse_json {
token
jsonfile
} {
It parses the json sent through xmlrpc

} {
ns_log Notice "Running ad_proc ix_robot.parse_json ..."
ns_log Notice "$token"
ns_log Notice "JSON \n $jsonfile"

return "OK"
}

I believe the size limit constraint is related to XMLRPC Lib http://xmlrpc-c.sourceforge.net/doc/libxmlrpc.html, but I haven't learned yet how to handle it yet.

Collapse
4: Re: XML-RPC String limit (response to 3)
Posted by Gustaf Neumann on
By the invoked method i meant the method named $method_name ... the suspicion was just triggered by the line number that you provided.

´What are the last 50 characters of the variable $xml in xmlrpc::invoke in line 648 [1]? To me, the error message "error parsing request: error "Unexpected end" at position 0" looks like a incorrect XML. have you checked, that the python library you are using does not truncate the output?

Was is the connection with libxmlrpc?
-g

PS: I've fixed the exception about the non-existing variable 'doc' [2], but this will not solve your problem.

[1] https://github.com/openacs/xml-rpc/blob/master/tcl/xml-rpc-procs.tcl#L648
[2] http://cvs.openacs.org/browse/OpenACS/openacs-4/packages/xml-rpc/tcl/xml-rpc-procs.tcl?r1=1.8&r2=1.9

Collapse
5: Re: XML-RPC String limit (response to 4)
Posted by Iuri Sampaio on
Gustaf,

xml-rpc-proc.tcl#L648 has been properly updated but the error still remains. To avoid potential syntax errors, as a json file would contain, I isolated the problem. I've written a chunk to generate 100k X's appending to string and send it to RPC2.

The logs point to syntax errors in a TCL file which is well written. Furthermore, if the string has less than 95 thousand chars the requests work just fine.

-] Error: xmlrpc::invoke: error parsing request: error "Unexpected end" at position 0
""
[14/Apr/2017:02:32:06][1460.7ff7f68ea700][-conn:1contact:1-] Notice: error "Entity parsing error" at position 1903
" + '?locale='+l+'&return_url='+return_url;
        top.location.href=url;
    }
--Error-- /script
   script type="text/javascript" src="https://code.jquery.com/jquery-"
[14/Apr/2017:02:32:06][1460.7ff7f70eb700][-conn:1contact:0-] Notice: checking entry 127.0.0.1 from host_node_map  
[14/Apr/2017:02:32:06][1460.7ff7f70eb700][-conn:1contact:0-] Warning: ignore untrusted host header field: '127.0.0.1:8000'
[14/Apr/2017:02:32:06][1460.7ff7f70eb700][-conn:1contact:0-] Notice: ignore non-existing or untrusted host header, fall back to 1c.1contact.ch
[14/Apr/2017:02:32:06][1460.7ff7f70eb700][-conn:1contact:0-] Error: can't read "doc": no such variable
    while executing
"xml_doc_free $doc"
    (procedure "xmlrpc::invoke" line 38)
    invoked from within
"xmlrpc::invoke $content"
    ("uplevel" body line 15)
    invoked from within
"uplevel {
    # /packages/xml-rpc/www/index.tcl
ad_page_contract {
    Accept XML-RPC POST requests and processes them. GET requests are shown
    lin..."
    (procedure "code::tcl::/var/www/1contact/packages/xml-rpc/www/index" line 2)
    invoked from within
"code::tcl::$__adp_stub"
    ("uplevel" body line 12)
    invoked from within
"uplevel {

        if { [file exists $__adp_stub.tcl] } {

            # ensure that data source preparation procedure exists and is up-to-date
      ..."
    (procedure "adp_prepare" line 2)
    invoked from within
"adp_prepare"
    invoked from within
"template::adp_parse [file rootname [ad_conn file]] {}"
    (procedure "adp_parse_ad_conn_file" line 6)
Collapse
6: Re: XML-RPC String limit (response to 5)
Posted by Gustaf Neumann on
i do no understand what you mean by "xml-rpc-proc.tcl#L648 has been properly updated": the committed change to rpc-procs refers to line 681 (see [1]), it will remove cause the exception "can't read doc" (the secondary bug), but the primary bug will stay. To fix the secondary bug, update the xml-rpc package (from cvs or github).

To debug the primary problem: insert after line 684 the statement

ns_log notice "xmlrpc::invoke last chars: '[string range $xml end-30 end]'"
and report the results to convince me, that the XML document with the 100k size is indeed correctly terminated. So far, i am not convinced.

[1] https://github.com/openacs/xml-rpc/blob/master/tcl/xml-rpc-procs.tcl#L681

Collapse
7: Re: XML-RPC String limit (response to 6)
Posted by Iuri Sampaio on
I downloaded and replaced the TCL file https://github.com/openacs/xml-rpc/blob/master/tcl/xml-rpc-procs.tcl. Curiously, my file was different than that one.

I've pasted the results in the previous post. There's no errors within that JS code. Plus, I've removed that chunk of code and the log notice threw another chunk from the same TCL in a different part of the file. It seems that the chunk gets returned in the error.log as a side effect of the parsing execution.

-] Error: xmlrpc::invoke: error parsing request: error "Unexpected end" at position 0
""
[14/Apr/2017:02:32:06][1460.7ff7f68ea700][-conn:1contact:1-] Notice: error "Entity parsing error" at position 1903
" + '?locale='+l+'&return_url='+return_url;
top.location.href=url;
}
--Error-- /script
script type="text/javascript" src="https://code.jquery.com/jquery-";
[14/Apr/2017:02:32:06][1460.7ff7f70eb700][-conn:1contact:0-] Notice: checking entry 127.0.0.1 from host_node_map

Collapse
8: Re: XML-RPC String limit (response to 7)
Posted by Gustaf Neumann on
what is the result of the "nslog notice ..." statement of
https://openacs.org/forums/message-view?message_id=5358474 ?
Collapse
9: Re: XML-RPC String limit (response to 8)
Posted by Iuri Sampaio on
To knock your suspects off see bellow the xml request file of a successful attempt. Then, make X times "100000, to get a body with 100000 X's char and break xmlrpc.

#####
Chrome/40.0.2214.111 Safari/537.36 user_id 698 peer 127.0.0.1
[14/Apr/2017:17:11:58][3231.7fef5a8db700][-conn:1contact:0-] Notice: Running TCL script test_ws.tcl
[14/Apr/2017:17:11:58][3231.7fef5a8db700][-conn:1contact:0-] Warning: ns_httpopen POST http://1c.1contact.ch/RPC2/ d4 30 {?xml version="1.0"?<methodCall><methodName>ix_robot.parseJson</methodName><params><param><value><string>gtregivrwjvoiejviowvwgvwegvwgre</string></value></param><param><value><string>XXXXXXXXX</string></value></param></params></methodCall>} is deprecated. Use 'ns_http' instead!
[14/Apr/2017:17:11:58][3231.7fef5a0da700][-conn:1contact:1-] Notice: Running ad_proc ix_robot.parseJson ...
[14/Apr/2017:17:11:58][3231.7fef5a0da700][-conn:1contact:1-] Notice: gtregivrwjvoiejviowvwgvwegvwgre
[14/Apr/2017:17:11:58][3231.7fef5a0da700][-conn:1contact:1-] Notice: JSON
XXXXXXXXX
[14/Apr/2017:17:11:58][3231.7fef5a8db700][-conn:1contact:0-] Notice:
[14/Apr/2017:17:12:00][3231.7fef5a0da700][-conn:1contact:1-] Notice: CSP violation: {"csp-report":{"document-uri":"http://1c.1contact.ch/","referrer":"","violated-directive":"font-src 'self' data:","effective-directive":"font-src","original-policy"

Furthemore, see the results of ns_log Debug

####
ted. Use 'ns_http' instead!
[14/Apr/2017:17:16:16][3231.7fef5a0da700][-conn:1contact:1-] Notice: BEFORE DEBUG
[14/Apr/2017:17:16:16][3231.7fef5a0da700][-conn:1contact:1-] Error: xmlrpc::invoke: error parsing request: error "Unexpected end" at position 0
####

And the collateral effect of XML RPC parsing

######
[14/Apr/2017:17:16:16][3231.7fef5a8db700][-conn:1contact:0-] Notice: error "Entity parsing error" at position 2006
" + '?locale='+l+'&return_url='+return_url;
top.location.href=url;
}
--Error-- /script
script type="text/javascript" src="https://code.jquery.com/jquery-";
[14/Apr/2017:17:16:16][3231.7fef5a0da700][-conn:1contact:1-] Error: can't read "doc": no such variable
while executing
"xml_doc_free $doc"
(procedure "xmlrpc::invoke" line 39)
invoked from within
"xmlrpc::invoke $content"
("uplevel" body line 15)

Collapse
10: Re: XML-RPC String limit (response to 1)
Posted by Iuri Sampaio on
[14/Apr/2017:17:29:18][3231.7fef5a0da700][-conn:1contact:1-] Notice: Running TCL script test_ws.tcl
[14/Apr/2017:17:29:18][3231.7fef5a8db700][-conn:1contact:0-] Notice: BEFORE DEBUG
[14/Apr/2017:17:29:18][3231.7fef5a0da700][-conn:1contact:1-] Warning: ns_httpopen POST http://1c.1contact.ch/RPC2/ d4 30 {<?xml version="1.0"?><methodCall><methodName>is_robot.parseJson</methodName><params><param><value><string>gtregivrwjvoiejviowvwgvwegvwgre</string></value></param><param><value><string>XXXXXXXXXX</string></value></param></params></methodCall>} is deprecated. Use 'ns_http' instead!
[14/Apr/2017:17:29:18][3231.7fef5a8db700][-conn:1contact:0-] Notice: BEFORE DEBUG
[14/Apr/2017:17:29:18][3231.7fef5a8db700][-conn:1contact:0-] Notice: Running ad_proc ix_robot.parseJson ...
[14/Apr/2017:17:29:18][3231.7fef5a8db700][-conn:1contact:0-] Notice: gtregivrwjvoiejviowvwgvwegvwgre
[14/Apr/2017:17:29:18][3231.7fef5a8db700][-conn:1contact:0-] Notice: JSON 
 XXXXXXXXXX
[14/Apr/2017:17:29:18][3231.7fef5a0da700][-conn:1contact:1-] Notice: 
Collapse
11: Re: XML-RPC String limit (response to 10)
Posted by Gustaf Neumann on
Post the result for a non-working case. For the debug line
ns_log notice "xmlrpc::invoke last chars: '[string range $xml end-30 end]'"
i would expect to see "invoke last chars:" in the log file.
Collapse
12: Re: XML-RPC String limit (response to 11)
Posted by Iuri Sampaio on
I've post it before.

The logs pointed to JavaScript syntax errors within a Tcl file which is well written. I removed that JS chunk and the syntax errors still appears but in a different part of the same file.

Notice: error "Entity parsing error" at position 2006
" + '?locale='+l+'&return_url='+return_url;

Furthermore, as mentioned before if the string has less than 95 thousand chars the requests work just fine with no sintax errors.

####
...
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</string></value></param></params></methodCall>} is deprecated. Use 'ns_http' instead!
[15/Apr/2017:19:19:40][3231.7fef5a0da700][-conn:1contact:1-] Notice: BEFORE DEBUG string range
[15/Apr/2017:19:19:40][3231.7fef5a0da700][-conn:1contact:1-] Notice: xmlrpc::invoke last chars: ''
[15/Apr/2017:19:19:40][3231.7fef5a0da700][-conn:1contact:1-] Error: xmlrpc::invoke: error parsing request: error "Unexpected end" at position 0
""
[15/Apr/2017:19:19:40][3231.7fef5a0da700][-conn:1contact:1-] Notice: checking entry 127.0.0.1 from host_node_map -
[15/Apr/2017:19:19:40][3231.7fef5a0da700][-conn:1contact:1-] Warning: ignore untrusted host header field: '127.0.0.1:8000'
[15/Apr/2017:19:19:40][3231.7fef5a0da700][-conn:1contact:1-] Notice: ignore non-existing or untrusted host header, fall back to 1c.1contact.ch
"xml_doc_free $doc"
(procedure "xmlrpc::invoke" line 40)
invoked from within
"xmlrpc::invoke $content"
("uplevel" body line 15)
invoked from within
"uplevel {
# /packages/xml-rpc/www/index.tcl
ad_page_contract {
Accept XML-RPC POST requests and processes them. GET requests are shown
lin..."
(procedure "code::tcl::/var/www/1contact/packages/xml-rpc/www/index" line 2)
invoked from within
"code::tcl::$__adp_stub"
("uplevel" body line 12)
invoked from within
"uplevel {

if { [file exists $__adp_stub.tcl] } {

# ensure that data source preparation procedure exists and is up-to-date
..."
(procedure "adp_prepare" line 2)
invoked from within
"adp_prepare"
invoked from within
"template::adp_parse [file rootname [ad_conn file]] {}"
(procedure "adp_parse_ad_conn_file" line 6)
invoked from within
"$handler"
("uplevel" body line 2)
invoked from within
"uplevel $code"
invoked from within
"ad_try {
$handler
} ad_script_abort val {
# do nothing
}"
invoked from within
"rp_serve_concrete_file [ad_conn file]"
(procedure "::nsf::procs::rp_serve_abstract_file" line 60)
invoked from within
"rp_serve_abstract_file "$root/$extra_url""
("uplevel" body line 2)
invoked from within
"uplevel $code"
invoked from within
"ad_try {
rp_serve_abstract_file "$root/$extra_url"
set ::tcl_url2file([ad_conn url]) [ad_conn file]
se..."
called from rp_handler
POST http://1c.1contact.ch/RPC2/? referred by '' peer 127.0.0.1 user_id 0
post-data:

X-Forwarded-For: 192.199.241.130
Host: 127.0.0.1:8000
Connection: close
Content-Length: 1000234
Accept: */*
User-Agent: NaviServer-Tcl/4.99
Content-type: text/xml

[15/Apr/2017:19:19:40][3231.7fef5a8db700][-conn:1contact:0-] Notice: error "Entity parsing error" at position 2006
" + '?locale='+l+'&return_url='+return_url;

Collapse
13: Re: XML-RPC String limit (response to 12)
Posted by Gustaf Neumann on
We see now that in the error case, the XML text passed to xmlrpc::invoke is empty (see the two single quotes in Notice: xmlrpc::invoke last chars: ''). It seems, as the xml-rpc package has problems gracefully handling such cases. I've added a test that should handle this test more gracefully to CVS [1].

What we know now is that for whatever reason, an xml-rpc request with 100k size ends up as an empty string in xmlrpc::invoke. This means, that xmlrpc::get_content (called by the www/index.tcl returns empty). I would recommend to try to replace the body of xmlrpc::get_content by the single line (when you use NaviServer):

  return [ns_getcontent -as_file false -binary false]

Let's hope this helps.
-g

[1] http://cvs.openacs.org/browse/OpenACS/openacs-4/packages/xml-rpc/tcl/xml-rpc-procs.tcl?r1=1.9&r2=1.10