Hello, I stumbled upon this bug when writing a Python plugin. I think this is a ikiwiki bug, since I do not think my plugin does anything wrong.
Example
I set up an example wiki, containing the setup file and the plugin, on github.
Clone the repository
git clone https://github.com/paternal/ikiwiki-rpcbug.git
Change to the right directory
cd ikiwiki-rpcbug
Add the right ikiwiki directory to PYTHONPATH
export PYTHONPATH="$PYTHONPATH:$(dirname $(dpkg -L ikiwiki | grep proxy))"
Build the wiki
ikiwiki --setup wiki.setup --rebuild
The problem is in page http://localhost/~USERNAME/ikiwiki_bug_rpc/foo/ (for instance, http://localhost/~USERNAME/ikiwiki_bug_rpc is fine.
Problem
Page foo
contains the directive [[!rpcbug ]]
(rpcbug
being the name of the plugin). Calling proxy.rpc("srcfile", "bar")
in the preprocess function seems to mess up the RPC communication between ikiwiki and the plugin, and the result is that the generate foo/index.html
page is a text file containing the return value of the preprocess
call.
What I do not understand is that disabling the format
function (by commenting line 46 of the plugin) solves the problem. Half of an explaination is that I think that when the the proxy.rpc
function is called, the RPC communication is messed up in such a way that the format
function is not called, and the return value of preprocess
is considered to be the whole html code of the resulting page.
I understood that: as the first rpc call messes up the communication, more rpc calls are messed up, but if there is only one rpc call, not that much is broken. -- Louis
I hope someone will understand the problem better than I do, because I have no idea about how to solve this.
Regards,
-- Louis
I used the debug feature provided with
proxy.py
and rebuilt the wiki. I ran this with this version of my minimal bug example.
- The bug happens in function preprocess (in call to srcfile, to be more precise).
- The directive causing the bug is called on page foo.
- Communication between Ikiwiki and the plugin is here.
- The resulting HTML (for page
foo
) looks like:[[!rpcbug Erreur: internal error: foo cannot be found in /home/louis/projets/ikiwiki/rpcbug or underlay]]
Calling srcfile(foo): page
Calling srcfile(README.md): /home/louis/projets/ikiwiki/rpcbug/README.mdMy analysis:
- The call to
srcfile(foo)
fails (because Ikiwiki thinks that pagefoo
does not exist).- Ikiwiki thinks that processing of the directive is finished, whereas the plugin still waits for the answer of Ikiwiki.
- Ikiwiki asks the plugin to render a new directive, but the plugin interprets the request as the return value for its previous request. Thus, the plugin thinks that
srcfile(foo)
ispage
(thispage
being a misinterpretation of the Ikiwiki request).So, I think that this might be an error in the
rpc_call
function of theexternal
plugin: when the called method fails, it should return something (or raise an exception, if this is possible in RPC) to notify the plugin that something went wrong.-- Louis
Update: This can actually be a proxy error. Indeed:
- Ikiwiki sends a
methodCall
message to the plugin (which is a call to thepreprocess
function);- the plugin sends a
methodCall
message to ikiwiki (which is a call to thesrcfile
function);- Ikiwiki answers with a
methodCall
message:
- Ikiwiki answers this because the function call failed, and it is already processing the next directive;
- the plugin thinks that it is its request answer, and misinterprets it.
Thus, I think that the bug is in the
proxy.py
python file. On receiving amethodCall
(instead of amethodResponse
) as an answer to amethodCall
request,proxy.py
should notice the type of request, and call the requested function.I know Python better than I know Perl, so I can try to fix this.
-- Louis
I fixed this bug in a branch on my Ikiwiki clone. Please review
-- Louis