Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
a0c4f005
Commit
a0c4f005
authored
7 years ago
by
Nick Thomas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use relative URLs when linking to uploaded files
parent
299e04e3
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
126 additions
and
202 deletions
+126
-202
app/models/concerns/cache_markdown_field.rb
app/models/concerns/cache_markdown_field.rb
+1
-1
changelogs/unreleased/38893-banzai-upload-filter-relative-urls.yml
...s/unreleased/38893-banzai-upload-filter-relative-urls.yml
+5
-0
lib/banzai/filter/relative_link_filter.rb
lib/banzai/filter/relative_link_filter.rb
+39
-7
lib/banzai/filter/upload_link_filter.rb
lib/banzai/filter/upload_link_filter.rb
+0
-60
lib/banzai/pipeline/gfm_pipeline.rb
lib/banzai/pipeline/gfm_pipeline.rb
+0
-1
spec/lib/banzai/filter/relative_link_filter_spec.rb
spec/lib/banzai/filter/relative_link_filter_spec.rb
+81
-0
spec/lib/banzai/filter/upload_link_filter_spec.rb
spec/lib/banzai/filter/upload_link_filter_spec.rb
+0
-133
No files found.
app/models/concerns/cache_markdown_field.rb
View file @
a0c4f005
...
@@ -11,7 +11,7 @@ module CacheMarkdownField
...
@@ -11,7 +11,7 @@ module CacheMarkdownField
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
# Increment this number every time the renderer changes its output
# Increment this number every time the renderer changes its output
CACHE_VERSION
=
2
CACHE_VERSION
=
3
# changes to these attributes cause the cache to be invalidates
# changes to these attributes cause the cache to be invalidates
INVALIDATED_BY
=
%w[author project]
.
freeze
INVALIDATED_BY
=
%w[author project]
.
freeze
...
...
This diff is collapsed.
Click to expand it.
changelogs/unreleased/38893-banzai-upload-filter-relative-urls.yml
0 → 100644
View file @
a0c4f005
---
title
:
Use relative URLs when linking to uploaded files
merge_request
:
15751
author
:
type
:
other
This diff is collapsed.
Click to expand it.
lib/banzai/filter/relative_link_filter.rb
View file @
a0c4f005
...
@@ -2,19 +2,21 @@ require 'uri'
...
@@ -2,19 +2,21 @@ require 'uri'
module
Banzai
module
Banzai
module
Filter
module
Filter
# HTML filter that "fixes" relative links to files in a repository.
# HTML filter that "fixes" relative links to
uploads or
files in a repository.
#
#
# Context options:
# Context options:
# :commit
# :commit
# :group
# :project
# :project
# :project_wiki
# :project_wiki
# :ref
# :ref
# :requested_path
# :requested_path
class
RelativeLinkFilter
<
HTML
::
Pipeline
::
Filter
class
RelativeLinkFilter
<
HTML
::
Pipeline
::
Filter
def
call
include
Gitlab
::
Utils
::
StrongMemoize
return
doc
unless
linkable_files?
def
call
@uri_types
=
{}
@uri_types
=
{}
clear_memoization
(
:linkable_files
)
doc
.
search
(
'a:not(.gfm)'
).
each
do
|
el
|
doc
.
search
(
'a:not(.gfm)'
).
each
do
|
el
|
process_link_attr
el
.
attribute
(
'href'
)
process_link_attr
el
.
attribute
(
'href'
)
...
@@ -31,13 +33,35 @@ module Banzai
...
@@ -31,13 +33,35 @@ module Banzai
protected
protected
def
linkable_files?
def
linkable_files?
context
[
:project_wiki
].
nil?
&&
repository
.
try
(
:exists?
)
&&
!
repository
.
empty?
strong_memoize
(
:linkable_files
)
do
context
[
:project_wiki
].
nil?
&&
repository
.
try
(
:exists?
)
&&
!
repository
.
empty?
end
end
end
def
process_link_attr
(
html_attr
)
def
process_link_attr
(
html_attr
)
return
if
html_attr
.
blank?
return
if
html_attr
.
blank?
return
if
html_attr
.
value
.
start_with?
(
'//'
)
return
if
html_attr
.
value
.
start_with?
(
'//'
)
if
html_attr
.
value
.
start_with?
(
'/uploads/'
)
process_link_to_upload_attr
(
html_attr
)
elsif
linkable_files?
process_link_to_repository_attr
(
html_attr
)
end
end
def
process_link_to_upload_attr
(
html_attr
)
uri_parts
=
[
html_attr
.
value
]
if
group
uri_parts
.
unshift
(
relative_url_root
,
'groups'
,
group
.
full_path
,
'-'
)
elsif
project
uri_parts
.
unshift
(
relative_url_root
,
project
.
full_path
)
end
html_attr
.
value
=
File
.
join
(
*
uri_parts
)
end
def
process_link_to_repository_attr
(
html_attr
)
uri
=
URI
(
html_attr
.
value
)
uri
=
URI
(
html_attr
.
value
)
if
uri
.
relative?
&&
uri
.
path
.
present?
if
uri
.
relative?
&&
uri
.
path
.
present?
html_attr
.
value
=
rebuild_relative_uri
(
uri
).
to_s
html_attr
.
value
=
rebuild_relative_uri
(
uri
).
to_s
...
@@ -51,7 +75,7 @@ module Banzai
...
@@ -51,7 +75,7 @@ module Banzai
uri
.
path
=
[
uri
.
path
=
[
relative_url_root
,
relative_url_root
,
context
[
:project
]
.
full_path
,
project
.
full_path
,
uri_type
(
file_path
),
uri_type
(
file_path
),
Addressable
::
URI
.
escape
(
ref
),
Addressable
::
URI
.
escape
(
ref
),
Addressable
::
URI
.
escape
(
file_path
)
Addressable
::
URI
.
escape
(
file_path
)
...
@@ -123,11 +147,19 @@ module Banzai
...
@@ -123,11 +147,19 @@ module Banzai
end
end
def
ref
def
ref
context
[
:ref
]
||
context
[
:project
].
default_branch
context
[
:ref
]
||
project
.
default_branch
end
def
group
context
[
:group
]
end
def
project
context
[
:project
]
end
end
def
repository
def
repository
@repository
||=
context
[
:project
].
try
(
:repository
)
@repository
||=
project
&
.
repository
end
end
end
end
end
end
...
...
This diff is collapsed.
Click to expand it.
lib/banzai/filter/upload_link_filter.rb
deleted
100644 → 0
View file @
299e04e3
require
'uri'
module
Banzai
module
Filter
# HTML filter that "fixes" relative upload links to files.
# Context options:
# :project (required) - Current project
#
class
UploadLinkFilter
<
HTML
::
Pipeline
::
Filter
def
call
return
doc
unless
project
||
group
doc
.
xpath
(
'descendant-or-self::a[starts-with(@href, "/uploads/")]'
).
each
do
|
el
|
process_link_attr
el
.
attribute
(
'href'
)
end
doc
.
xpath
(
'descendant-or-self::img[starts-with(@src, "/uploads/")]'
).
each
do
|
el
|
process_link_attr
el
.
attribute
(
'src'
)
end
doc
end
protected
def
process_link_attr
(
html_attr
)
html_attr
.
value
=
build_url
(
html_attr
.
value
).
to_s
end
def
build_url
(
uri
)
base_path
=
Gitlab
.
config
.
gitlab
.
url
if
group
urls
=
Gitlab
::
Routing
.
url_helpers
# we need to get last 2 parts of the uri which are secret and filename
uri_parts
=
uri
.
split
(
File
::
SEPARATOR
)
file_path
=
urls
.
show_group_uploads_path
(
group
,
uri_parts
[
-
2
],
uri_parts
[
-
1
])
File
.
join
(
base_path
,
file_path
)
else
File
.
join
(
base_path
,
project
.
full_path
,
uri
)
end
end
def
project
context
[
:project
]
end
def
group
context
[
:group
]
end
# Ensure that a :project key exists in context
#
# Note that while the key might exist, its value could be nil!
def
validate
needs
:project
end
end
end
end
This diff is collapsed.
Click to expand it.
lib/banzai/pipeline/gfm_pipeline.rb
View file @
a0c4f005
...
@@ -15,7 +15,6 @@ module Banzai
...
@@ -15,7 +15,6 @@ module Banzai
Filter
::
MathFilter
,
Filter
::
MathFilter
,
Filter
::
MermaidFilter
,
Filter
::
MermaidFilter
,
Filter
::
UploadLinkFilter
,
Filter
::
VideoLinkFilter
,
Filter
::
VideoLinkFilter
,
Filter
::
ImageLazyLoadFilter
,
Filter
::
ImageLazyLoadFilter
,
Filter
::
ImageLinkFilter
,
Filter
::
ImageLinkFilter
,
...
...
This diff is collapsed.
Click to expand it.
spec/lib/banzai/filter/relative_link_filter_spec.rb
View file @
a0c4f005
...
@@ -5,6 +5,7 @@ describe Banzai::Filter::RelativeLinkFilter do
...
@@ -5,6 +5,7 @@ describe Banzai::Filter::RelativeLinkFilter do
contexts
.
reverse_merge!
({
contexts
.
reverse_merge!
({
commit:
commit
,
commit:
commit
,
project:
project
,
project:
project
,
group:
group
,
project_wiki:
project_wiki
,
project_wiki:
project_wiki
,
ref:
ref
,
ref:
ref
,
requested_path:
requested_path
requested_path:
requested_path
...
@@ -25,7 +26,12 @@ describe Banzai::Filter::RelativeLinkFilter do
...
@@ -25,7 +26,12 @@ describe Banzai::Filter::RelativeLinkFilter do
%(<a href="#{path}">#{path}</a>)
%(<a href="#{path}">#{path}</a>)
end
end
def
nested
(
element
)
%(<div>#{element}</div>)
end
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:group
)
{
nil
}
let
(
:project_path
)
{
project
.
full_path
}
let
(
:project_path
)
{
project
.
full_path
}
let
(
:ref
)
{
'markdown'
}
let
(
:ref
)
{
'markdown'
}
let
(
:commit
)
{
project
.
commit
(
ref
)
}
let
(
:commit
)
{
project
.
commit
(
ref
)
}
...
@@ -223,4 +229,79 @@ describe Banzai::Filter::RelativeLinkFilter do
...
@@ -223,4 +229,79 @@ describe Banzai::Filter::RelativeLinkFilter do
let
(
:commit
)
{
nil
}
# force filter to use ref instead of commit
let
(
:commit
)
{
nil
}
# force filter to use ref instead of commit
include_examples
:valid_repository
include_examples
:valid_repository
end
end
context
'with a /upload/ URL'
do
# not needed
let
(
:commit
)
{
nil
}
let
(
:ref
)
{
nil
}
let
(
:requested_path
)
{
nil
}
context
'to a project upload'
do
it
'rebuilds relative URL for a link'
do
doc
=
filter
(
link
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
))
expect
(
doc
.
at_css
(
'a'
)[
'href'
])
.
to
eq
"/
#{
project
.
full_path
}
/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc
=
filter
(
nested
(
link
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
)))
expect
(
doc
.
at_css
(
'a'
)[
'href'
])
.
to
eq
"/
#{
project
.
full_path
}
/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it
'rebuilds relative URL for an image'
do
doc
=
filter
(
image
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
))
expect
(
doc
.
at_css
(
'img'
)[
'src'
])
.
to
eq
"/
#{
project
.
full_path
}
/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc
=
filter
(
nested
(
image
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
)))
expect
(
doc
.
at_css
(
'img'
)[
'src'
])
.
to
eq
"/
#{
project
.
full_path
}
/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it
'does not modify absolute URL'
do
doc
=
filter
(
link
(
'http://example.com'
))
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
'http://example.com'
end
it
'supports Unicode filenames'
do
path
=
'/uploads/한글.png'
escaped
=
Addressable
::
URI
.
escape
(
path
)
# Stub these methods so the file doesn't actually need to be in the repo
allow_any_instance_of
(
described_class
)
.
to
receive
(
:file_exists?
).
and_return
(
true
)
allow_any_instance_of
(
described_class
)
.
to
receive
(
:image?
).
with
(
path
).
and_return
(
true
)
doc
=
filter
(
image
(
escaped
))
expect
(
doc
.
at_css
(
'img'
)[
'src'
]).
to
match
"/
#{
project
.
full_path
}
/uploads/%ED%95%9C%EA%B8%80.png"
end
end
context
'to a group upload'
do
let
(
:upload_link
)
{
link
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
)
}
let
(
:group
)
{
create
(
:group
)
}
let
(
:project
)
{
nil
}
let
(
:relative_path
)
{
"/groups/
#{
group
.
full_path
}
/-/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
}
it
'rewrites the link correctly'
do
doc
=
filter
(
upload_link
)
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
(
relative_path
)
end
it
'rewrites the link correctly for subgroup'
do
group
.
update!
(
parent:
create
(
:group
))
doc
=
filter
(
upload_link
)
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
(
relative_path
)
end
it
'does not modify absolute URL'
do
doc
=
filter
(
link
(
'http://example.com'
))
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
'http://example.com'
end
end
end
end
end
This diff is collapsed.
Click to expand it.
spec/lib/banzai/filter/upload_link_filter_spec.rb
deleted
100644 → 0
View file @
299e04e3
require
'spec_helper'
describe
Banzai
::
Filter
::
UploadLinkFilter
do
def
filter
(
doc
,
contexts
=
{})
contexts
.
reverse_merge!
({
project:
project
})
raw_filter
(
doc
,
contexts
)
end
def
raw_filter
(
doc
,
contexts
=
{})
described_class
.
call
(
doc
,
contexts
)
end
def
image
(
path
)
%(<img src="#{path}" />)
end
def
link
(
path
)
%(<a href="#{path}">#{path}</a>)
end
def
nested_image
(
path
)
%(<div><img src="#{path}" /></div>)
end
def
nested_link
(
path
)
%(<div><a href="#{path}">#{path}</a></div>)
end
let
(
:project
)
{
create
(
:project
)
}
shared_examples
:preserve_unchanged
do
it
'does not modify any relative URL in anchor'
do
doc
=
filter
(
link
(
'README.md'
))
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
'README.md'
end
it
'does not modify any relative URL in image'
do
doc
=
filter
(
image
(
'files/images/logo-black.png'
))
expect
(
doc
.
at_css
(
'img'
)[
'src'
]).
to
eq
'files/images/logo-black.png'
end
end
it
'does not raise an exception on invalid URIs'
do
act
=
link
(
"://foo"
)
expect
{
filter
(
act
)
}.
not_to
raise_error
end
context
'with a valid repository'
do
it
'rebuilds relative URL for a link'
do
doc
=
filter
(
link
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
))
expect
(
doc
.
at_css
(
'a'
)[
'href'
])
.
to
eq
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
project
.
full_path
}
/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc
=
filter
(
nested_link
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
))
expect
(
doc
.
at_css
(
'a'
)[
'href'
])
.
to
eq
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
project
.
full_path
}
/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it
'rebuilds relative URL for an image'
do
doc
=
filter
(
image
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
))
expect
(
doc
.
at_css
(
'img'
)[
'src'
])
.
to
eq
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
project
.
full_path
}
/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc
=
filter
(
nested_image
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
))
expect
(
doc
.
at_css
(
'img'
)[
'src'
])
.
to
eq
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
project
.
full_path
}
/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it
'does not modify absolute URL'
do
doc
=
filter
(
link
(
'http://example.com'
))
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
'http://example.com'
end
it
'supports Unicode filenames'
do
path
=
'/uploads/한글.png'
escaped
=
Addressable
::
URI
.
escape
(
path
)
# Stub these methods so the file doesn't actually need to be in the repo
allow_any_instance_of
(
described_class
)
.
to
receive
(
:file_exists?
).
and_return
(
true
)
allow_any_instance_of
(
described_class
)
.
to
receive
(
:image?
).
with
(
path
).
and_return
(
true
)
doc
=
filter
(
image
(
escaped
))
expect
(
doc
.
at_css
(
'img'
)[
'src'
]).
to
match
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
project
.
full_path
}
/uploads/%ED%95%9C%EA%B8%80.png"
end
end
context
'in group context'
do
let
(
:upload_link
)
{
link
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
)
}
let
(
:group
)
{
create
(
:group
)
}
let
(
:filter_context
)
{
{
project:
nil
,
group:
group
}
}
let
(
:relative_path
)
{
"groups/
#{
group
.
full_path
}
/-/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
}
it
'rewrites the link correctly'
do
doc
=
raw_filter
(
upload_link
,
filter_context
)
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
(
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
relative_path
}
"
)
end
it
'rewrites the link correctly for subgroup'
do
subgroup
=
create
(
:group
,
parent:
group
)
relative_path
=
"groups/
#{
subgroup
.
full_path
}
/-/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc
=
raw_filter
(
upload_link
,
{
project:
nil
,
group:
subgroup
})
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
(
"
#{
Gitlab
.
config
.
gitlab
.
url
}
/
#{
relative_path
}
"
)
end
it
'does not modify absolute URL'
do
doc
=
filter
(
link
(
'http://example.com'
),
filter_context
)
expect
(
doc
.
at_css
(
'a'
)[
'href'
]).
to
eq
'http://example.com'
end
end
context
'when project or group context does not exist'
do
let
(
:upload_link
)
{
link
(
'/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'
)
}
it
'does not raise error'
do
expect
{
raw_filter
(
upload_link
,
project:
nil
)
}.
not_to
raise_error
end
it
'does not rewrite link'
do
doc
=
raw_filter
(
upload_link
,
project:
nil
)
expect
(
doc
.
to_html
).
to
eq
upload_link
end
end
end
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment