Page MenuHomePhabricator

MW 1.35.0 "Error contacting the Parsoid/RESTBase server: http-bad-status" on a private wiki
Open, Needs TriagePublicBUG REPORT

Description

VisualEditor does not work in private wikis.

Steps to Reproduce:

  1. Include the following in LocalSettings.php:
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['read'] = false;
  1. Open an existing page, and click the "Edit" link.

Actual Results:

The VisualEditor editor loads, but then we get an error, "Error contacting the Parsoid/RESTBase server: http-bad-status".

Expected Results:

VisualEditor works as expected.

Notes

When creating a new page, the editor loads fine, but if you hit "Save" you get the same error message.

If you change the lines in step 1 to be "true", VisualEditor works as expected.

Relevant discussion/others having the same issue or similar:

Event Timeline

ppelberg added a subscriber: ppelberg.

hi @Technoabyss – thank you for filing this issue. We think the issue you are experiencing can be resolved by following the instructions documented on this help page. [i]

Please let us know if after reading that you still have questions.


i. https://www.mediawiki.org/wiki/Extension:VisualEditor#Linking_with_Parsoid_in_private_wikis

@ppelberg
To be honest, I'm not sure what these instructions are telling me to do? My wiki is served over HTTPS, so I imagine I shouldn't set up forwarding cookies. Do I need to serve my wiki over http and forward my cookies for VisualEditor to work?

For posterity, this is the current revision of the VisualEditor extension page: https://www.mediawiki.org/w/index.php?title=Extension:VisualEditor&oldid=4220814

I've closed the Talk page now that there is a working workaround for this issue, where you turn off the read/edit restrictions for connections coming from the server Mediawiki is installed on.

The same issue is happening to me with a wiki configured as

$wgGroupPermissions['*']['read'] = true;
$wgGroupPermissions['*']['edit'] = false;

but, more importantly, the bug persists even if I change permissions to

$wgGroupPermissions['*']['read'] = true;
$wgGroupPermissions['*']['edit'] = true;

and the workaround doesn't work for me either.

  1. Install a private personal mediawiki 1.35 on a ubuntu 20.04 laptop without short url.
  2. Install semantic mediawiki with composer
  3. disable the ufw firewall

Visual editor doesn't work out of the box in a private personal mediawiki.

I tried each of the following tricks one by one in LocalSettings.php. I restart the apache2 service after using each trick. I didn't try any two tricks at the same time. Visual editor doesn't work in all cases. I get the error: Error contacting the Parsoid/RESTBase server: http-bad-status

  • Set $wgVirtualRestConfig['modules']['parsoid']['forwardCookies'] = true;
  • Set $wgGroupPermissions['user']['writeapi'] = true;
  • Use the follow trick with the <ip> as localhost or 127.0.0.1
if ( $_SERVER['REMOTE_ADDR'] == 'localhost ) {
        $wgGroupPermissions['*']['read'] = true;
        $wgGroupPermissions['*']['edit'] = true;
}

If the wiki is readable by everyone, visual editor works. But I want to have a private wiki for myself.

$wgGroupPermissions['*']['read'] = true;
$wgGroupPermissions['*']['edit'] = false;

Same problem here, no workaround did the trick for me.

Setting up Mediawiki with Visual Editor is the most frustrating thing i have ever done websitewise...

I'm facing a related issue using MediaWiki 1.36.1.

The API request to the VisualEditor API succeeds, however, the alert message indicates that curl couldn't connect to the server (it just did?).

Error message:

Screenshot 2021-07-07 at 08.01.53@2x.png (428×700 px, 45 KB)

CLI request:

$ curl http://localhost:8080/api.php?action=visualeditor&format=json&paction=parse&page=Main_Page&uselang=en&formatversion=2&oldid=1 | jq
{
    "error": {
        "code": "apierror-visualeditor-docserver-http-error",
        "info": "Error contacting the Parsoid/RESTBase server: (curl error: 7) Couldn't connect to server",
        "docref": "See http://localhost:8080/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes."
    }
}

Tweaks to $wgGroupPermissions settings, as mentioned above, have no effect.

I think one of the more frustrating aspects of this are that the documentation is very little help here. The Parsoid documentation is very hard to follow and often provides contradictory and/or outdated advice.

I have the same issue with MediaWiki 1.36.1. I edited my LocalSettings.php with variations of the following discussed workarounds and none worked:

wfLoadExtension( 'VisualEditor' );

$wgVirtualRestConfig['modules']['parsoid']['forwardCookies'] = true;
$wgGroupPermissions['user']['writeapi'] = true;

if ( $_SERVER['REMOTE_ADDR'] == '127.0.0.1' ) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
    $wgGroupPermissions['*']['writeapi'] = true;
}

This seems to be a really frustrating bug for anyone who wishes to run MediaWiki in private mode.

I'm being bitten by this bug on a wiki that permits anonymous reads and forbids anonymous writes. None of the suggested workarounds work for me.

To be specific, I tried enabling read, write & writeapi permissions for both "*" and "user" when $_SERVER['REMOTE_ADDR'] equals my server's IP address or 127.0.0.1. No combination prevented the problem.

The error I get is HTTP 415.

I have the same issue on MediaWiki 1.36.1.

Here is the workaround that I am using that works for me:

if ( isset( $_SERVER['REMOTE_ADDR'] ) &&
     in_array( $_SERVER['REMOTE_ADDR'], [ $_SERVER['SERVER_ADDR'], '127.0.0.1' ] ) ) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
}

This workaround allows unauthenticated access to the Wiki and API from the local machine.

I am using Nginx (not Apache) in case that is relevant.

The workaround should be secure because although an attacker can spoof the source IP address of IP packets easily, it difficult to establish a TCP connection with a spoofed IP address (unless the attacker can control the network routing). Furthermore, in this case we are checking whether the packet came from the local machine. The system firewall should have the ingress filter configured to reject packets that have the source IP address set to the loopback address (127.0.0.1) or an IP address within the internal network (such as the IP address of the server itself).

@AndrewDBate: Your workaround unfortunately does not work for me with MediaWiki 1.35.3. I still get this error from VisualEditor on save:

Something went wrong
Error contacting the Parsoid/RESTBase server (HTTP 415)
[Dismiss]

I'm using Apache 2.4.41 on Ubuntu 20.04.3 LTS.

Interestingly, I run the same codebase on a test server with SSL turned off. The http site works fine with VisualEditor, but the production site (https) has the error.

@maiden_taiwan Are the production and testing servers identical, other than one is http and the other is https? Do both use Apache? Are you using IPv6? Or are you using IPv4 only?

Perhaps you can try to debug what is going on by logging the value of $_SERVER['REMOTE_ADDR'] to the debug log.

For example, add the line $wgDebugLogFile = "/tmp/mediawiki-debug.log"; to your LocalSettings.php file, and then just before where you would have put the workaround that I posted, add the line wfDebug("#### REMOTE_ADDR" . $_SERVER['REMOTE_ADDR']). Then open a browser and use the VisualEditor to reproduce the error message you posted. Then grep the file /tmp/mediawiki-debug.log for the relevant lines starting with #### REMOTE_ADDR and see if there are any unexpected values of $_SERVER['REMOTE_ADDR'] (because my workaround only applies when the value of $_SERVER['REMOTE_ADDR'] is either the value of $_SERVER['SERVER_ADDR'] or 127.0.0.1).

Sorry that I cannot help further, but that is where I would start.

Thanks @AndrewDBate! I did exactly as you said, and both $_SERVER['REMOTE_ADDR']) and $_SERVER['SERVER_ADDR']) are the empty string.

However, if I hit a plain PHP page that runs phpinfo() they have proper values.

@maiden_taiwan So in the table of everything in the $_SERVER array near the bottom of the output of phpinfo() is it showing non-empty strings for $_SERVER['REMOTE_ADDR'] and $_SERVER['SERVER_ADDR']?

As a double check, I would also try echoing the values of $_SERVER['REMOTE_ADDR'] and $_SERVER['SERVER_ADDR'] from a plain PHP page (not a MediaWiki page nor the generated phpinfo()). I would just create a file test.php with contents <?php echo "Value of REMOTE_ADDR is " . $_SERVER['REMOTE_ADDR'] . "."; ?> and check the output (and similarly for $_SERVER['SERVER_ADDR']).

If you get a non-empty value of $_SERVER['REMOTE_ADDR'] when echoed from a plain PHP page, then it must be something with MediaWiki that is messed up. Otherwise, if you still get the empty string, then it must be the Apache/PHP config that is messed up (because the output of phpinfo() would then be reporting an incorrect value of $_SERVER['REMOTE_ADDR']).

Sorry I can't be of more help because I use Nginx myself.

Thanks @AndrewDBate for your debugging help! Yes, in the big table output by this script:

<?php
phpinfo();

the values of $_SERVER['REMOTE_ADDR'] and $_SERVER['SERVER_ADDR'] are NON-empty. They are precisely the IP addresses one would expect: my home PC and the MediaWiki server, respectively.

This test script produces exactly the same results:

<?php
echo "Value of REMOTE_ADDR is " . $_SERVER['REMOTE_ADDR'] . ".";
echo "Value of SERVER_ADDR is " . $_SERVER['SERVER_ADDR'] . ".";

It is only MediaWiki that prints empty strings for these values (to the debug log file, from LocalSettings.php).

I will say that the behavior of $wgDebugLogFile was extremely intermittent. Sometimes MediaWiki would write to it, and sometimes MediaWiki wouldn't even create the output file. My guess was caching was the culprit. I kept restarting Apache and memcached and sometimes would get debug output after that.

@maiden_taiwan That really is strange.

It is probably not related, but do you have IPv6 addresses or only IPv4 addresses?

I haven't myself noticed problems with the MediaWiki debug log, but as an alternative (IIRC) you can enable PHP logging to file by adding the following line to LocalSettings.php:
ini_set( 'error_log', '/tmp/php-error.log' );

And then write messages to the log with:
error_log( "Your message here." );

This is the plain PHP error logging function.

That might serve as a more reliable alternative to the debug log if you are having issues with that at the moment. Maybe check the values of $_SERVER['REMOTE_ADDR'] and $_SERVER['SERVER_ADDR'] again that way? It might also be worth putting the logging at the very top of the LocalSettings.php file in case something is happening in between to mess up the values of $_SERVER['REMOTE_ADDR'] and $_SERVER['SERVER_ADDR'] (however, no code should ever be modifying values of $_SERVER, but just to be paranoid its best to not assume anything).

Thanks @AndrewDBate. I suspect the issues with the MediaWiki debug log were due to heavy caching -- I'd modify LocalSettings to enable debugging but MediaWiki wouldn't pick up that fact and wouldn't reread it.

@maiden_taiwan Okay, good to know. Please do update this ticket if you ever figure out why $_SERVER['REMOTE_ADDR'] is empty in your LocalSettings.php but not when printed from plain PHP files.

I don't have an explanation but I do have a better analysis.

$_SERVER['REMOTE_ADDR'] is blank in LocalSettings when printed with wfDebug as you suggested. However, it has a completely normal value when printed to the web page with echo at the exact same spot in LocalSettings.

@maiden_taiwan Okay, that's strange. The first step would then be to get $_SERVER['REMOTE_ADDR'] to print to a log with the correct value so that we can determine the value of $_SERVER['REMOTE_ADDR'] when a call is made to the REST API from the local machine (we cannot use echo for that because there is no page being loaded).

Maybe try the plain PHP logging I suggested above and see if that prints the value of $_SERVER['REMOTE_ADDR'] correctly?

Once we know the value of $_SERVER['REMOTE_ADDR'] when a call is made to the REST API from the local machine, all we need to do is update my original patch to work with that value of $_SERVER['REMOTE_ADDR'].

It would be good to know why logging with wfDebug is behaving differently though.

Is this fixed yet? In a later version of MW maybe?

@Technoabyss Unfortunately not. I am running MediaWiki 1.36.1 and still need the workaround I posted.

Ooo, this might explain the weird wfDebug behavior. From https://www.mediawiki.org/wiki/Manual:How_to_debug#Logging:

"Writing log files to the /tmp directory may not generate any log file at all, even if the /tmp directory is supposed to be writable by anyone. This could happen if your system is using one of the systemd features that create a virtual /tmp directory for that process. If that's the case, configure your log file to be written into a different directory, like /var/log/mediawiki"

I'll have to try writing the Mediawiki log to a different directory.

I agree it is worth trying a directory other than /tmp to save the log file.

However, from your previous replied I understood that you were getting some output to the log, not no output. But it is still worth trying.

However, I would still suggesting trying an alternative means of logging which I suggested preiovusly:

It is probably not related, but do you have IPv6 addresses or only IPv4 addresses?

I haven't myself noticed problems with the MediaWiki debug log, but as an alternative (IIRC) you can enable PHP logging to file by adding the following line to LocalSettings.php:
ini_set( 'error_log', '/tmp/php-error.log' );

And then write messages to the log with:
error_log( "Your message here." );

This is the plain PHP error logging function.

The workaround to set $wgGroupPermissions based on the REMOTE_ADDR is not acceptable to me for security reasons.

I was under the impression that it should work without this, because the default configuration is to set forwardCookies if not everyone is allowed to read every page. After debugging the problem, I found that installing php-curl fixes the issue and I am now able to use VisualEditor in my private wiki without having to look at the REMOTE_ADDR of the client.

Details:
The MultiHttpClient code switches between Curl and Guzzle depending on whether the Curl extension is installed or not. The GuzzleHttpRequest code does not honour the Cookie header set by ParsoidVirtualRESTService, which is used (when forwardCookies is enabled) to authenticate with the client's session. The Curl HTTP request client does use the cookie, so it works with that.

@M4rkusd89: Thanks for the suggestion. php-curl is already installed on my server, so your fix may be necessary for VisualEditor but it's not sufficient to solve the problem.

I'd like to add a comment that I had this issue today on the private Wiki site I am writing. Because I was getting the "Error creating thumbnail: Unable to save thumbnail to destination" issue, I saw a site that says to add a "$wgTmpDirectory" to the LocalSettings.php.

I created a temp directory under my /wikimedia/images folder, and added the line to the localsettings: $wgTmpDirectory = "/wikimedia/images/temp";

As soon as I tried to edit another page, I started getting the Parsoid error. Commenting that same line back out allows me to edit without the Parsoid error (but I still get the thumbnail error.)

The workaround did not fix it for me.

Here's the relevant code from my LocalSettings.php

wfLoadExtension( 'VisualEditor' );
wfLoadExtension( 'Parsoid', 'vendor/wikimedia/parsoid/extension.json' );
$wgGroupPermissions['user']['writeapi'] = true;
$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgDefaultUserOptions['visualeditor-editor'] = "visualeditor";
$wgVirtualRestConfig['modules']['parsoid']['forwardCookies'] = true;
if ( $_SERVER['REMOTE_ADDR'] == 'XXX' ) {
  $wgGroupPermissions['*']['read'] = true;
  $wgGroupPermissions['*']['edit'] = true;
  $wgGroupPermissions['*']['writeapi'] = true;
}

Where XXX is my server IP address.

This didn't fix it for me... any idea what I did wrong??

This is the at-the-end-of-LocalSettings.php workaround that worked for me:

# To be added at the very bottom of /opt/meza/src/roles/mediawiki/templates/LocalSettings.php.j2 to allow VE to work in 35.x when meza_auth_type is "viewer-read" and apache is 100% localhost behind an SSL terminator/load-balancer/proxy front-end (like haproxy)

# Define and calculate "remote_ip_test" based on hierarchy of what we know about the requestor's origin from the request header
# Result: "remote_ip_test" is 127.0.0.1 if-and-only-if it is truly an internal server-side request
if     (!empty($_SERVER['HTTP_CLIENT_IP']))       { $remote_ip_test = $_SERVER['HTTP_CLIENT_IP']; }
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $remote_ip_test = $_SERVER['HTTP_X_FORWARDED_FOR']; }
elseif (isset($_SERVER['REMOTE_ADDR'] ) )         { $remote_ip_test = $_SERVER['REMOTE_ADDR']; }

# If the request is truly an internal server-side request, then open the wiki up for full access
if (isset($remote_ip_test) && $remote_ip_test == '127.0.0.1') {
  $wgGroupPermissions['*']['read'] = true;
  $wgGroupPermissions['*']['edit'] = true;
  $wgGroupPermissions['*']['writeapi'] = true;
}

@AndrewDBate: I finally had a chance to try your error-logging alternative:

ini_set( 'error_log', '/var/log/mediawiki/php-error.log' );
// ...
error_log( "Your message here." );

It produced 100% reliable error logging. (Thank you!!) I found that when VisualEditor is sending requests to parsoid, $_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR'] (the actual IP of my server). Nevertheless, even when I use this condition to open up anonymous writes, like this:

error_log('REMOTE_ADDR=' . $_SERVER['REMOTE_ADDR']);
error_log('SERVER_ADDR=' . $_SERVER['SERVER_ADDR']);
if ( $_SERVER['REMOTE_ADDR'] == $_SERVER['SERVER_ADDR'] ) {
    error_log('yup');
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
    $wgGroupPermissions['*']['writeapi'] = true;
}

VisualEditor still fails to save edits, displaying the dialog "Error contacting the Parsoid/RESTBase server (HTTP 415)."

A-ha... if I make my private wiki use http instead of https (by changing the Apache configuration), VisualEditor can save pages without error, without needing any of the workarounds in this ticket.

Does this provide any clues for what to fix to make it work with https?

@UGOBOSS777 From what you have commented, what you have put in your LocalSettings.php file is not the same as the workaround I suggested. Please try the workaround as I originally commented:, i.e. replace the lines:

if ( $_SERVER['REMOTE_ADDR'] == 'XXX' ) {
  $wgGroupPermissions['*']['read'] = true;
  $wgGroupPermissions['*']['edit'] = true;
  $wgGroupPermissions['*']['writeapi'] = true;
}

with those in my earlier comment:

if ( isset( $_SERVER['REMOTE_ADDR'] ) &&
     in_array( $_SERVER['REMOTE_ADDR'], [ $_SERVER['SERVER_ADDR'], '127.0.0.1' ] ) ) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
}

If you could report back with whether that worked or not, so that it can help others struggling with this, that would be great. Thanks!

@maiden_taiwan I honestly don't know... Maybe there is something wrong with your TLS certificate config? Are you using Let's Encrypt or something else?

Perhaps to debug this you could try to use curl to check whether you can query the Rest API from the server itself? Because if you can query the Rest API from the server itself then Visual Editor should work.

Perhaps try to curl to the Rest API when you have http turned off to check it works, and then again with https turned on to check that it still works?

Sorry I can't be of any more help... but that is where I would start if it were me.

Thanks @AndrewDBate. I really appreciate all of your advice.

I'd love to test the REST API manually with curl, but since Parsoid is now built into the MediaWiki codebase (instead of being a separately running Linux service), I am not sure how to do that. The Parsoid docs now give examples of running their supplied bin/parse.php script, and I've downloaded the Parsoid git repo and run the script successfully, but I don't understand if by using parse.php in this way, I'm actually talking to the same instance of Parsoid as my MediaWiki site.

Do you know a simple "hello world" command I could run with curl to demonstrate that MediaWiki's parsoid instance is working? With the bin/parse.php command, it's:

echo foo | php parse.php

Ah, found some REST docs. @AndrewDBate, does this successful GET request prove that Parsoid is running on the given server?

https://sevenandahalflessons.com/w/rest.php/v1/page/Glossary/html

It works with curl when run directly on the server as well.

I think that because it is a private wiki, then if you can GET a page without additional authorization then that should be enough to prove that VisualEditor has the required access. (But I am not an expert. Maybe someone else could confirm this?)

You could try the GET with and without the these lines to check the effect of adding them to the config:

if ( isset( $_SERVER['REMOTE_ADDR'] ) &&
     in_array( $_SERVER['REMOTE_ADDR'], [ $_SERVER['SERVER_ADDR'], '127.0.0.1' ] ) ) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
}

The idea of the workaround is to only allow the GET/POST/PUT without authorization when the request is made from the server itself.

You might also find this page somewhat useful: https://www.mediawiki.org/wiki/API:REST_API

@UGOBOSS777 From what you have commented, what you have put in your LocalSettings.php file is not the same as the workaround I suggested. Please try the workaround as I originally commented:, i.e. replace the lines:

if ( $_SERVER['REMOTE_ADDR'] == 'XXX' ) {
  $wgGroupPermissions['*']['read'] = true;
  $wgGroupPermissions['*']['edit'] = true;
  $wgGroupPermissions['*']['writeapi'] = true;
}

with those in my earlier comment:

if ( isset( $_SERVER['REMOTE_ADDR'] ) &&
     in_array( $_SERVER['REMOTE_ADDR'], [ $_SERVER['SERVER_ADDR'], '127.0.0.1' ] ) ) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
}

If you could report back with whether that worked or not, so that it can help others struggling with this, that would be great. Thanks!

Hello,

I've made the corrections as proposed.

Here's the bottom of my LocalSettings.php:

wfLoadExtension( 'VisualEditor' );
wfLoadExtension( 'Parsoid', 'vendor/wikimedia/parsoid/extension.json' );
$wgGroupPermissions['user']['writeapi'] = true;

$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgDefaultUserOptions['visualeditor-editor'] = "visualeditor";

$wgVirtualRestConfig['modules']['parsoid']['forwardCookies'] = true;

if ( isset( $_SERVER['REMOTE_ADDR'] ) &&
     in_array( $_SERVER['REMOTE_ADDR'], [ $_SERVER['SERVER_ADDR'], '127.0.0.1' ] ) ) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
}

Tested and I'm still getting the same Parsoid/RESTBase (HTTP 404).

Tested and I'm still getting the same Parsoid/RESTBase (HTTP 404).

A 404 error is a very different error, and means it doesn't find the resource. Something is pointing to the wrong URL

Tested and I'm still getting the same Parsoid/RESTBase (HTTP 404).

A 404 error is a very different error, and means it doesn't find the resource. Something is pointing to the wrong URL

Well then I really don't understand what's going on.

I just installed MediaWiki plain vanilla and the only config I did was the following:

$wgVirtualRestConfig['modules']['parsoid']['forwardCookies'] = true;

wfLoadExtension( 'VisualEditor' );
wfLoadExtension( 'Parsoid', 'vendor/wikimedia/parsoid/extension.json' );
$wgGroupPermissions['user']['writeapi'] = true;

$wgDefaultUserOptions['visualeditor-enable'] = 1;
$wgDefaultUserOptions['visualeditor-editor'] = "visualeditor";

if ( isset( $_SERVER['REMOTE_ADDR'] ) &&
     in_array( $_SERVER['REMOTE_ADDR'], [ $_SERVER['SERVER_ADDR'], '127.0.0.1' ] ) ) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
}

# UGO CLOUTIER : Pour permettre l'usage des citations dans l'éditeur visuel
wfLoadExtension( 'Scribunto' );
$wgScribuntoDefaultEngine = 'luastandalone';
wfLoadExtension( 'ParserFunctions' );
wfLoadExtension( 'Cite' );
wfLoadExtension( 'TemplateData' );

The only "URL" I can see is

'vendor/wikimedia/parsoid/extension.json'

And it is correct.

OK, I just went through an extensive debugging session for this problem (Error contacting the Parsoid/RESTBase server (HTTP 415) on save operations). I created a MediaWiki 1.37.1 test site with a minimal LocalSettings.php file plus VisualEditor. There are no $wgGroupPermissions statements at all, so wiki permissions should not be an issue -- the test site is wide open for anonymous editing.

As far as I can tell, this Parsoid problem arises not because of permissions, but because of VisualEditor running on a secure (SSL) site. If I run the site with https, VisualEditor cannot save: Error contacting the Parsoid/RESTBase server (HTTP 415). If I switch the wiki to non-secure http, VisualEditor immediately works fine!

My browser says the SSL cert is valid (from LetsEncrypt). You can view it at https://how-emotions-are-made.com. (This isn't my testing site. My testing site is a copy of this site, stripped down.)

Now obviously, VisualEditor works on some secure sites, such as Wikipedia. So I'm guessing something is missing or misconfigured. All relevant config files are below. Does anyone see a problem?

Here is the entire LocalSettings.php file (sanitized):

<?php
if ( !defined( 'MEDIAWIKI' ) ) {
        exit;
}

$wgScriptPath = "/w";
$wgScriptExtension = ".php";
$wgStylePath = "$wgScriptPath/skins";
$wgServer = '//mywiki.com';
$wgSitename = "Test Site";
$wgArticlePath = "/notes/$1";

## Database settings
$wgDBtype = "mysql";
$wgDBserver = "localhost";
$wgDBname = "wikidb";
$wgDBuser = "wikiuser";
$wgDBpassword = "password here";
$wgDBprefix = "wp_";
$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=binary";
$wgDBmysql5 = true;

# Secret keys
$wgSecretKey = "1234567890123456789012345678900987654321123123123123123123123123";
$wgUpgradeKey = "1234567890987654";

# VisualEditor
$wgDefaultSkin = "vector";
wfLoadSkin('Vector');
wfLoadExtensions(array(
    'VisualEditor',
));

Here is the Apache configuration for HTTPS:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName mywiki.com
    ServerAdmin admin@blazemonger.com

    # Index file and Document Root (where the public files are located)
    DirectoryIndex index.html index.php
    DocumentRoot /var/www/mywiki.com/public_html
    # Log file locations
    LogLevel warn
    ErrorLog  /var/www/mywiki.com/log/error.log
    CustomLog /var/www/mywiki.com/log/access.log combined

    # Root redirect
    RedirectMatch ^/$ http://mywiki.com/w

    ServerAlias www.mywiki.com
    ServerAlias *.mywiki.com
    ServerAlias mywiki.net
    ServerAlias *.mywiki.net

    SSLCertificateFile /etc/letsencrypt/live/mywiki.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/mywiki.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

<Directory "/var/www/mywiki.com/public_html">
    AllowOverride None
    RewriteEngine On
    RewriteRule ^/?notes(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]
    RewriteRule ^/*$ %{DOCUMENT_ROOT}/w/index.php [L]
</Directory>

<Directory "/var/www/mywiki.com/public_html/w/images">
    # Ignore .htaccess files
    AllowOverride None

    # Serve HTML as plaintext, don't execute SHTML
    AddType text/plain .html .htm .shtml .php .phtml .php5

    # Don't run arbitrary PHP code.
    php_admin_flag engine off
</Directory>

Here is the Apache configuration for HTTP:

<VirtualHost *:80>
    ServerName mywiki.com
    ServerAdmin admin@blazemonger.com

    # Index file and Document Root (where the public files are located)
    DirectoryIndex index.html index.php
    DocumentRoot /var/www/mywiki.com/public_html
    # Log file locations
    LogLevel warn
    ErrorLog  /var/www/mywiki.com/log/error.log
    CustomLog /var/www/mywiki.com/log/access.log combined

    ServerAlias www.mywiki.com
    ServerAlias *.mywiki.com
    ServerAlias mywiki.net
    ServerAlias *.mywiki.net

    # Root redirect
    RedirectMatch ^/$ http://mywiki.com/w
</VirtualHost>

<Directory "/var/www/mywiki.com/public_html">
    AllowOverride None
    RewriteEngine On
    RewriteRule ^/?notes(/.*)?$ %{DOCUMENT_ROOT}/w/index.php [L]
    RewriteRule ^/*$ %{DOCUMENT_ROOT}/w/index.php [L]
</Directory>

<Directory "/var/www/mywiki.com/public_html/w/images">
    # Ignore .htaccess files
    AllowOverride None

    # Serve HTML as plaintext, don't execute SHTML
    AddType text/plain .html .htm .shtml .php .phtml .php5

    # Don't run arbitrary PHP code.
    php_admin_flag engine off
</Directory>

I discovered the cause of the problem (documented in the previous comment). Changing this line in LocalSettings.php, which specifies a protocol-relative URL:

$wgServer = '//mywiki.com';

to an explicit HTTPS URL:

$wgServer = 'https://mywiki.com';

caused VisualEditor to work with HTTPS.

I suspect this is a bug, so I will file a separate ticket for it.

That is very impressive @maiden_taiwan!

In my LocalSettings.php I have the line:

$wgServer = 'https://mywiki.com';

i.e. with the https prefix and not using a protocol-relative URL.

This probably explains why my configuration works correctly.

However, I noticed that your LocalSettings.php does not include the workaround I posted above. Was it not necessary for you to include this? For the avoidance of doubt, the workaround I am referring to is:

if ( isset( $_SERVER['REMOTE_ADDR'] ) &&
     in_array( $_SERVER['REMOTE_ADDR'], [ $_SERVER['SERVER_ADDR'], '127.0.0.1' ] ) ) {
    $wgGroupPermissions['*']['read'] = true;
    $wgGroupPermissions['*']['edit'] = true;
}

If I remove these lines from my LocalSettings.php then I get the error "Error contacting the Parsoid/RESTBase server: http-bad-status".

One difference between my environment and yours is that I am using Nginx whereas you are using Apache.

@AndrewDBate - yes indeed, my LocalSettings.php did not include any $wgGroupPermissions changes. It is possible that two separate issues are masquerading as one issue:

  • An issue relating to protocol-relative $wgServer values
  • An issue relating to $wgGroupPermissions being required on private wikis

My next task is to make the test wiki private and see if I also need the $wgGroupPermissions workaround or not.

I restricted my test wiki to disallow anonymous edits:

// Forbid editing to all anonymous users
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['viewmywatchlist'] = false;
$wgGroupPermissions['*']['editmywatchlist'] = false;
$wgGroupPermissions['*']['createpage'] = false;

and lo and behold, VisualEditor can still save pages just fine for logged-in users, without @AndrewDBate's workaround.

I can confirm that my four wikis, which were unable to use VisualEditor, are now fixed. :-)

@maiden_taiwan Thank you very much for confirming this. You have confirmed that my suggested workaround is not required when using MediaWiki 1.37.1 and Apache.

I originally tested my workaround with MediaWiki 1.35.0 and Nginx.

There could be a few different things happening here, such as:

  • Possibly something has changed between MediaWiki 1.35.0 and 1.37.1 such that my workaround is no longer required.
  • Possibly something is different between our envrionments (for example, I am using Nginx and you are using Apache).

Time permitting, I would also like to retrace my steps and test my workaround again with MediaWiki 1.35.0 and Nginx to make sure that I did not make a mistake.

I have just determined that my suggested workaround is not required when using MediaWiki 1.36.1 and Nginx.

For me the problem was in the LocalSettings.php file. The URL path of the installation was there with http. I changed it to https. Now it works. Both on MW 1.35 and MW 1.37 .
Like explained here : https://www.mediawiki.org/wiki/Topic:Vv0owe0jhsjjonhb