Skip to content

Commit bcb6ce9

Browse files
committed
Item13696: Convert link fixup code to be a plugin.
1 parent 0f499eb commit bcb6ce9

File tree

12 files changed

+488
-75
lines changed

12 files changed

+488
-75
lines changed

PubLinkFixupPlugin/.gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
*,v
2+
*,pfv
3+
*.gz
4+
/PubLinkFixupPlugin.md5
5+
/PubLinkFixupPlugin.sha1
6+
/PubLinkFixupPlugin.tgz
7+
/PubLinkFixupPlugin.txt
8+
/PubLinkFixupPlugin.zip
9+
/PubLinkFixupPlugin_installer
10+
/PubLinkFixupPlugin_installer.pl

PubLinkFixupPlugin/TIDY

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
%META:TOPICINFO{author="ProjectContributor" date="1442191889" format="1.1" version="1"}%
2+
%META:TOPICPARENT{name="Plugins"}%
3+
<!--
4+
One line description, required for extensions repository catalog.
5+
* Set SHORTDESCRIPTION = %$SHORTDESCRIPTION%
6+
-->
7+
---+!! Empty Plugin
8+
9+
%SHORTDESCRIPTION%
10+
11+
%TOC%
12+
13+
This plugin performs pub link fixup of the generated HTML page. If Foswiki is configured with a
14+
non-utf-8 ={Store}{Encoding}=, then links to /pub files will be generated with the incorrect encoding.
15+
16+
Even on non-utf-8 sites, Foswiki operates fully with UNICODE and utf-8 encoding in the core and on
17+
the web interface. /pub attachment links will be generated assuming the filesnames are utf-8 encoded.
18+
This plugin provides a completePageHandler that finds utf-8 encoded links to /pub attachments and
19+
re-encodes them to the {Store}{Encoding}.
20+
21+
Enable this plugin to perform the link fixup. It can be safely enabled regardless of the ={Store}{Encoding}=.
22+
If the Plugin detects that the ={Store}{Encoding}= is =utf-8=, it quietly disables its =completePageHandler=.
23+
24+
This is __not__ a complete fix to the issue. It is still strongly recommended that sites convert
25+
their Store to utf-8 to avoid these types of encoding issues.
26+
27+
---++ Preferences
28+
29+
This plugin has one expert setting.
30+
* ={Plugins}{PubLinkFixupPlugin}{Debug}=. Enable to record before/after of each rewritten link to the Foswiki debug log.
31+
32+
---++ Installation
33+
%$INSTALL_INSTRUCTIONS%
34+
35+
---++ Info
36+
37+
| Change&nbsp;History: | <!-- versions below in reverse order -->&nbsp; |
38+
| 1.00 (14 Sep 2015): | Initial version |
39+
40+
%META:FORM{name="PackageForm"}%
41+
%META:FIELD{name="Author" title="Author" value="GeorgeClark"}%
42+
%META:FIELD{name="Version" title="Version" value="%$VERSION%"}%
43+
%META:FIELD{name="Release" title="Release" value="%$RELEASE%"}%
44+
%META:FIELD{name="Copyright" value="%$CREATEDYEAR%, GeorgeClark, All Rights Reserved"}%
45+
%META:FIELD{name="License" value="GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]])"}%
46+
%META:FIELD{name="Repository" value="https://github.com/foswiki/%$ROOTMODULE%"}%
47+
%META:FIELD{name="Home" value="http://foswiki.org/Extensions/%$ROOTMODULE%"}%
48+
%META:FIELD{name="Support" value="http://foswiki.org/Support/%$ROOTMODULE%"}%
49+
%META:FIELD{name="Repository" title="Repository" value="https://github.com/foswiki/distro"}%
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# See bottom of file for license and copyright information
2+
package Foswiki::Configure::Checkers::Plugins::PubLinkFixupPlugin::Enabled;
3+
4+
use warnings;
5+
use strict;
6+
7+
use Foswiki::Configure::Checker ();
8+
our @ISA = qw( Foswiki::Configure::Checker );
9+
10+
sub check {
11+
my $this = shift;
12+
my $warnings;
13+
14+
if ( $Foswiki::cfg{Store}{Encoding}
15+
&& $Foswiki::cfg{Store}{Encoding} ne 'utf-8' )
16+
{
17+
if ( !$Foswiki::cfg{Plugins}{PubLinkFixupPlugin}{Enabled} ) {
18+
$warnings .= $this->WARN(<<'HERE');
19+
The PubLinkFixupPlugin should be enabled when running a non-default ={Store}{Encoding}=.
20+
Your Store is configured for ($Foswiki::cfg{Store}{Encoding}). This extension will
21+
re-encode =/pub/ links so that non-ASCII attachments can be accessed.
22+
HERE
23+
}
24+
}
25+
26+
return $warnings;
27+
}
28+
29+
1;
30+
__END__
31+
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
32+
33+
Copyright (C) 2008-2015 Foswiki Contributors. Foswiki Contributors
34+
are listed in the AUTHORS file in the root of this distribution.
35+
NOTE: Please extend that file, not this notice.
36+
37+
This program is free software; you can redistribute it and/or
38+
modify it under the terms of the GNU General Public License
39+
as published by the Free Software Foundation; either version 2
40+
of the License, or (at your option) any later version. For
41+
more details read LICENSE in the root of this distribution.
42+
43+
This program is distributed in the hope that it will be useful,
44+
but WITHOUT ANY WARRANTY; without even the implied warranty of
45+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
46+
47+
As per the GPL, removal of this notice is prohibited.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# See bottom of file for default license and copyright information
2+
3+
=begin TML
4+
5+
---+ package Foswiki::Plugins::PubLinkFixupPlugin
6+
7+
This plugin performs pub link fixup of the generated HTML page. If Foswiki is configured with a
8+
non-utf-8 ={Store}{Encoding}=, then links to /pub files will be generated with the incorrect encoding.
9+
10+
Even on non-utf-8 sites, Foswiki operates fully with UNICODE and utf-8 encoding in the core and on
11+
the web interface. /pub attachment links will be generated assuming the filesnames are utf-8 encoded.
12+
This plugin provides a completePageHandler that finds utf-8 encoded links to /pub attachments and
13+
re-encodes them to the {Store}{Encoding}.
14+
15+
This is __not__ a complete fix to the issue. It is still strongly recommended that sites convert
16+
their Store to utf-8 to avoid these types of encoding issues.
17+
18+
=cut
19+
20+
# change the package name!!!
21+
package Foswiki::Plugins::PubLinkFixupPlugin;
22+
23+
# Always use strict to enforce variable scoping
24+
use strict;
25+
use warnings;
26+
27+
use Foswiki ();
28+
use Foswiki::Func (); # The plugins API
29+
use Foswiki::Plugins (); # For the API version
30+
use Foswiki::Store ();
31+
32+
our $VERSION = '1.00';
33+
our $RELEASE = '14 Sep 2015';
34+
35+
# One line description of the module
36+
our $SHORTDESCRIPTION =
37+
'For non-utf-8 sites, fix up Pub links to use correct encoding.';
38+
39+
our $NO_PREFS_IN_TOPIC = 1;
40+
41+
=begin TML
42+
43+
---++ initPlugin($topic, $web, $user) -> $boolean
44+
* =$topic= - the name of the topic in the current CGI query
45+
* =$web= - the name of the web in the current CGI query
46+
* =$user= - the login name of the user
47+
* =$installWeb= - the name of the web the plugin topic is in
48+
(usually the same as =$Foswiki::cfg{SystemWebName}=)
49+
50+
=cut
51+
52+
sub initPlugin {
53+
my ( $topic, $web, $user, $installWeb ) = @_;
54+
55+
# check for Plugins.pm versions
56+
if ( $Foswiki::Plugins::VERSION < 2.3 ) {
57+
Foswiki::Func::writeWarning( 'Version mismatch between ',
58+
__PACKAGE__, ' and Plugins.pm' );
59+
return 0;
60+
}
61+
62+
# If site is running utf-8 store, then this plugin is not needed.
63+
# Just undefine the completePageHandler.
64+
unless ( $Foswiki::cfg{Store}{Encoding}
65+
&& $Foswiki::cfg{Store}{Encoding} ne 'utf-8' )
66+
{
67+
undef *completePageHandler;
68+
Foswiki::Func::writeDebug(
69+
'PubLinkFixupPlugin disabled - utf-8 store detected')
70+
if ( $Foswiki::cfg{Plugins}{PubLinkFixupPlugin}{Debug} );
71+
}
72+
73+
# Plugin correctly initialized
74+
return 1;
75+
}
76+
77+
=begin TML
78+
79+
---++ completePageHandler($html, $httpHeaders)
80+
81+
This handler is called on the ingredients of every page that is
82+
output by the standard CGI scripts. It is designed primarily for use by
83+
cache and security plugins.
84+
* =$html= - the body of the page (normally &lt;html>..$lt;/html>)
85+
* =$httpHeaders= - the HTTP headers. Note that the headers do not contain
86+
a =Content-length=. That will be computed and added immediately before
87+
the page is actually written. This is a string, which must end in \n\n.
88+
89+
*Since:* Foswiki::Plugins::VERSION 2.0
90+
91+
=cut
92+
93+
sub completePageHandler {
94+
95+
# my( $html, $httpHeaders ) = @_;
96+
97+
if ( $Foswiki::cfg{Store}{Encoding}
98+
&& $Foswiki::cfg{Store}{Encoding} ne 'utf-8' )
99+
{
100+
$_[0] =~
101+
s#(<(?:a|link) .*?href=(["'])(?:$Foswiki::cfg{DefaultUrlHost})?($Foswiki::cfg{PubUrlPath}/?.*?)\2.*?/?>)#_reEncodePubLink($1, $3)#ge;
102+
$_[0] =~
103+
s#(<(?:audio|iframe|img|script|source|track|video) .*?src=(["'])(?:$Foswiki::cfg{DefaultUrlHost})?($Foswiki::cfg{PubUrlPath}/?.*?)\2.*?/?>)#_reEncodePubLink($1, $3)#ge;
104+
$_[0] =~
105+
s#(<object .*?data=(["'])(?:$Foswiki::cfg{DefaultUrlHost})?($Foswiki::cfg{PubUrlPath}/?.*?)\2.*?/?>)#_reEncodePubLink($1, $3)#ge;
106+
}
107+
}
108+
109+
=begin TML
110+
---++ private _reEncodePubLink( $wholeLink, $url )
111+
112+
This routine is called for each pub link found in the complete page.
113+
It takes the href/src location from the link, re-encodes it into the
114+
{Store}{Encoding} and then replaces it back into the whole link.
115+
116+
=cut
117+
118+
sub _reEncodePubLink {
119+
my ( $wholeLink, $url ) = @_;
120+
121+
my $origLink = $wholeLink; # For debug printing
122+
123+
# Extract just the path component, truncating any querystring
124+
my $qPos = index( $url, '?' );
125+
if ( $qPos >= 0 ) {
126+
$url = substr( $url, 0, $qPos );
127+
}
128+
129+
# Decode the path back to utf-8
130+
my $decoded = Foswiki::urlDecode($url);
131+
132+
# something didn't work right, undo the decode and keep going
133+
if ( index( $decoded, chr(0xFFFD) ) > 0 ) {
134+
Foswiki::Func::writeDebug("Warning: Decode failed for ($decoded)")
135+
if ( $Foswiki::cfg{Plugins}{PubLinkFixupPlugin}{Debug} );
136+
$decoded = $url;
137+
}
138+
139+
# if ascii, just return unmodified
140+
return $wholeLink if $decoded !~ m/[^[:ascii:]]+/;
141+
142+
# Extract out the file system path for further checking
143+
( my $storePath ) = $decoded =~ m/^$Foswiki::cfg{PubUrlPath}(\/.*)$/;
144+
return $wholeLink unless $storePath; #Nothing to check?
145+
146+
# If file exists with utf-8 encoding, do nothing
147+
my $tmpPath = "$Foswiki::cfg{PubDir}$storePath";
148+
return $wholeLink
149+
if ( -e Encode::encode( 'utf-8', $tmpPath, Encode::FB_WARN ) );
150+
151+
# re-encode the decoded URL into the {Store}{Encoding}
152+
my $text = Foswiki::Store::encode($decoded);
153+
154+
($storePath) = $text =~ m/^$Foswiki::cfg{PubUrlPath}(\/.*)$/;
155+
return $wholeLink unless $storePath; #Nothing to check?
156+
157+
# if the file doesn't exist, then either oddball encoding, or
158+
# maybe a real broken link. Just return unchanged.
159+
return $wholeLink unless ( -e $Foswiki::cfg{PubDir} . $storePath );
160+
161+
# Entity-encode non-ASCII high character and other restricted characters.
162+
$text =~ s{([^0-9a-zA-Z-_.:~!*#/])}{sprintf('%%%02x',ord($1))}ge;
163+
164+
# Replace the urlpath in the link.
165+
$wholeLink =~ s/\Q$url\E/$text/;
166+
167+
if ( $origLink ne $wholeLink
168+
&& $Foswiki::cfg{Plugins}{PubLinkFixupPlugin}{Debug} )
169+
{
170+
Foswiki::Func::writeDebug( <<DETAILS );
171+
PubLinkFixupPlugin -
172+
REWRITING: $origLink
173+
TO: $wholeLink
174+
DETAILS
175+
176+
return $wholeLink;
177+
178+
}
179+
}
180+
181+
1;
182+
183+
__END__
184+
Foswiki - The Free and Open Source Wiki, http://foswiki.org/
185+
186+
Copyright (C) 2008-2013 Foswiki Contributors. Foswiki Contributors
187+
are listed in the AUTHORS file in the root of this distribution.
188+
NOTE: Please extend that file, not this notice.
189+
190+
This program is free software; you can redistribute it and/or
191+
modify it under the terms of the GNU General Public License
192+
as published by the Free Software Foundation; either version 2
193+
of the License, or (at your option) any later version. For
194+
more details read LICENSE in the root of this distribution.
195+
196+
This program is distributed in the hope that it will be useful,
197+
but WITHOUT ANY WARRANTY; without even the implied warranty of
198+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
199+
200+
As per the GPL, removal of this notice is prohibited.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# ---+ Extensions
2+
# ---++ PubLinkFixupPlugin
3+
# **BOOLEAN EXPERT**
4+
# Write the details of any rewritten links to the
5+
# debug log.
6+
$Foswiki::cfg{Plugins}{PubLinkFixupPlugin}{Debug} = 0;
7+
8+
1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
!noci
2+
data/System/PubLinkFixupPlugin.txt 0644
3+
lib/Foswiki/Plugins/PubLinkFixupPlugin.pm 0644
4+
lib/Foswiki/Plugins/PubLinkFixupPlugin/Config.spec 0644
5+
lib/Foswiki/Configure/Checkers/Plugins/PubLinkFixupPlugin/Enabled.pm 0644

0 commit comments

Comments
 (0)