mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 15:06:26 +08:00
FIX: httpshttps ultra secure URLs
This commit is contained in:
parent
7a1e99dacb
commit
5169bcdb6e
|
@ -35,7 +35,7 @@ class TopicLinkClick < ActiveRecord::Base
|
||||||
cdn_uri = URI.parse(Discourse.asset_host) rescue nil
|
cdn_uri = URI.parse(Discourse.asset_host) rescue nil
|
||||||
if cdn_uri && cdn_uri.hostname == uri.hostname && uri.path.starts_with?(cdn_uri.path)
|
if cdn_uri && cdn_uri.hostname == uri.hostname && uri.path.starts_with?(cdn_uri.path)
|
||||||
is_cdn_link = true
|
is_cdn_link = true
|
||||||
urls << uri.path[(cdn_uri.path.length)..-1]
|
urls << uri.path[cdn_uri.path.length..-1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -43,8 +43,7 @@ class TopicLinkClick < ActiveRecord::Base
|
||||||
cdn_uri = URI.parse(SiteSetting.s3_cdn_url) rescue nil
|
cdn_uri = URI.parse(SiteSetting.s3_cdn_url) rescue nil
|
||||||
if cdn_uri && cdn_uri.hostname == uri.hostname && uri.path.starts_with?(cdn_uri.path)
|
if cdn_uri && cdn_uri.hostname == uri.hostname && uri.path.starts_with?(cdn_uri.path)
|
||||||
is_cdn_link = true
|
is_cdn_link = true
|
||||||
|
path = uri.path[cdn_uri.path.length..-1]
|
||||||
path = uri.path[(cdn_uri.path.length)..-1]
|
|
||||||
urls << path
|
urls << path
|
||||||
urls << "#{Discourse.store.absolute_base_url}#{path}"
|
urls << "#{Discourse.store.absolute_base_url}#{path}"
|
||||||
end
|
end
|
||||||
|
@ -66,7 +65,7 @@ class TopicLinkClick < ActiveRecord::Base
|
||||||
# If no link is found...
|
# If no link is found...
|
||||||
unless link.present?
|
unless link.present?
|
||||||
# ... return the url for relative links or when using the same host
|
# ... return the url for relative links or when using the same host
|
||||||
return url if url =~ /^\// || uri.try(:host) == Discourse.current_hostname
|
return url if url =~ /^\/[^\/]/ || uri.try(:host) == Discourse.current_hostname
|
||||||
|
|
||||||
# If we have it somewhere else on the site, just allow the redirect.
|
# If we have it somewhere else on the site, just allow the redirect.
|
||||||
# This is likely due to a onebox of another topic.
|
# This is likely due to a onebox of another topic.
|
||||||
|
|
|
@ -223,9 +223,9 @@ class Upload < ActiveRecord::Base
|
||||||
def self.get_from_url(url)
|
def self.get_from_url(url)
|
||||||
return if url.blank?
|
return if url.blank?
|
||||||
# we store relative urls, so we need to remove any host/cdn
|
# we store relative urls, so we need to remove any host/cdn
|
||||||
url = url.sub(/^#{Discourse.asset_host}/i, "") if Discourse.asset_host.present?
|
url = url.sub(Discourse.asset_host, "") if Discourse.asset_host.present?
|
||||||
# when using s3, we need to replace with the absolute base url
|
# when using s3, we need to replace with the absolute base url
|
||||||
url = url.sub(/^#{SiteSetting.s3_cdn_url}/i, Discourse.store.absolute_base_url) if SiteSetting.s3_cdn_url.present?
|
url = url.sub(SiteSetting.s3_cdn_url, Discourse.store.absolute_base_url) if SiteSetting.s3_cdn_url.present?
|
||||||
Upload.find_by(url: url)
|
Upload.find_by(url: url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -325,20 +325,20 @@ class CookedPostProcessor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
use_s3_cdn = SiteSetting.s3_cdn_url.present? && SiteSetting.enable_s3_uploads
|
use_s3_cdn = SiteSetting.enable_s3_uploads && SiteSetting.s3_cdn_url.present?
|
||||||
|
|
||||||
%w{href data-download-href}.each do |selector|
|
%w{href data-download-href}.each do |selector|
|
||||||
@doc.css("a[#{selector}]").each do |a|
|
@doc.css("a[#{selector}]").each do |a|
|
||||||
href = a[selector].to_s
|
href = a[selector].to_s
|
||||||
a[selector] = UrlHelper.schemaless UrlHelper.absolute(href) if UrlHelper.is_local(href)
|
a[selector] = UrlHelper.schemaless UrlHelper.absolute(href) if UrlHelper.is_local(href)
|
||||||
a[selector] = a[selector].sub(Discourse.store.absolute_base_url, SiteSetting.s3_cdn_url) if use_s3_cdn
|
a[selector] = Discourse.store.cnd_url(a[selector]) if use_s3_cdn
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc.css("img[src]").each do |img|
|
@doc.css("img[src]").each do |img|
|
||||||
src = img["src"].to_s
|
src = img["src"].to_s
|
||||||
img["src"] = UrlHelper.schemaless UrlHelper.absolute(src) if UrlHelper.is_local(src)
|
img["src"] = UrlHelper.schemaless UrlHelper.absolute(src) if UrlHelper.is_local(src)
|
||||||
img["src"] = img["src"].sub(Discourse.store.absolute_base_url, SiteSetting.s3_cdn_url) if use_s3_cdn
|
img["src"] = Discourse.store.cnd_url(img["src"]) if use_s3_cdn
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ module Discourse
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.disabled_plugin_names
|
def self.disabled_plugin_names
|
||||||
plugins.select {|p| !p.enabled?}.map(&:name)
|
plugins.select { |p| !p.enabled? }.map(&:name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.plugins
|
def self.plugins
|
||||||
|
@ -179,36 +179,18 @@ module Discourse
|
||||||
|
|
||||||
# Get the current base URL for the current site
|
# Get the current base URL for the current site
|
||||||
def self.current_hostname
|
def self.current_hostname
|
||||||
if SiteSetting.force_hostname.present?
|
SiteSetting.force_hostname.presence || RailsMultisite::ConnectionManagement.current_hostname
|
||||||
SiteSetting.force_hostname
|
|
||||||
else
|
|
||||||
RailsMultisite::ConnectionManagement.current_hostname
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.base_uri(default_value = "")
|
def self.base_uri(default_value = "")
|
||||||
if !ActionController::Base.config.relative_url_root.blank?
|
ActionController::Base.config.relative_url_root.presence || default_value
|
||||||
ActionController::Base.config.relative_url_root
|
|
||||||
else
|
|
||||||
default_value
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.base_url_no_prefix
|
def self.base_url_no_prefix
|
||||||
default_port = 80
|
protocol, default_port = SiteSetting.force_https? ? ["https", 443] : ["http", 80]
|
||||||
protocol = "http"
|
url = "#{protocol}://#{current_hostname}"
|
||||||
|
url << ":#{SiteSetting.port}" if SiteSetting.port.to_i > 0 && SiteSetting.port.to_i != default_port
|
||||||
if SiteSetting.force_https?
|
url
|
||||||
protocol = "https"
|
|
||||||
default_port = 443
|
|
||||||
end
|
|
||||||
|
|
||||||
result = "#{protocol}://#{current_hostname}"
|
|
||||||
|
|
||||||
port = SiteSetting.port.present? && SiteSetting.port.to_i > 0 ? SiteSetting.port.to_i : default_port
|
|
||||||
|
|
||||||
result << ":#{SiteSetting.port}" if port != default_port
|
|
||||||
result
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.base_url
|
def self.base_url
|
||||||
|
|
|
@ -33,7 +33,6 @@ module FileStore
|
||||||
end
|
end
|
||||||
|
|
||||||
def cdn_url(url)
|
def cdn_url(url)
|
||||||
url
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def absolute_base_url
|
def absolute_base_url
|
||||||
|
|
|
@ -11,18 +11,16 @@ module FileStore
|
||||||
|
|
||||||
def remove_file(url)
|
def remove_file(url)
|
||||||
return unless is_relative?(url)
|
return unless is_relative?(url)
|
||||||
path = public_dir + url
|
source = "#{public_dir}#{url}"
|
||||||
return if !File.exists?(path)
|
return unless File.exists?(source)
|
||||||
tombstone = public_dir + url.sub("/uploads/", "/uploads/tombstone/")
|
destination = "#{public_dir}#{url.sub("/uploads/", "/uploads/tombstone/")}"
|
||||||
FileUtils.mkdir_p(tombstone_dir)
|
dir = Pathname.new(destination).dirname
|
||||||
FileUtils.move(path, tombstone, force: true)
|
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
||||||
|
FileUtils.move(source, destination, force: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_been_uploaded?(url)
|
def has_been_uploaded?(url)
|
||||||
return false if url.blank?
|
is_relative?(url) || is_local?(url)
|
||||||
return true if is_relative?(url)
|
|
||||||
return true if is_local?(url)
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def absolute_base_url
|
def absolute_base_url
|
||||||
|
@ -50,6 +48,11 @@ module FileStore
|
||||||
"#{relative_base_url}/#{upload.sha1}"
|
"#{relative_base_url}/#{upload.sha1}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cdn_url(url)
|
||||||
|
return url if Discourse.asset_host.blank?
|
||||||
|
url.sub(Discourse.base_url_no_prefix, Discourse.asset_host)
|
||||||
|
end
|
||||||
|
|
||||||
def path_for(upload)
|
def path_for(upload)
|
||||||
url = upload.try(:url)
|
url = upload.try(:url)
|
||||||
"#{public_dir}#{upload.url}" if url && url[0] == "/" && url[1] != "/"
|
"#{public_dir}#{upload.url}" if url && url[0] == "/" && url[1] != "/"
|
||||||
|
@ -64,7 +67,8 @@ module FileStore
|
||||||
end
|
end
|
||||||
|
|
||||||
def copy_file(file, path)
|
def copy_file(file, path)
|
||||||
FileUtils.mkdir_p(Pathname.new(path).dirname)
|
dir = Pathname.new(path).dirname
|
||||||
|
FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
|
||||||
# move the file to the right location
|
# move the file to the right location
|
||||||
# not using mv, cause permissions are no good on move
|
# not using mv, cause permissions are no good on move
|
||||||
File.open(path, "wb") { |f| f.write(file.read) }
|
File.open(path, "wb") { |f| f.write(file.read) }
|
||||||
|
@ -85,7 +89,7 @@ module FileStore
|
||||||
end
|
end
|
||||||
|
|
||||||
def tombstone_dir
|
def tombstone_dir
|
||||||
public_dir + relative_base_url.sub("/uploads/", "/uploads/tombstone/")
|
"#{public_dir}#{relative_base_url.sub("/uploads/", "/uploads/tombstone/")}"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require "uri"
|
||||||
require_dependency "file_store/base_store"
|
require_dependency "file_store/base_store"
|
||||||
require_dependency "file_store/local_store"
|
require_dependency "file_store/local_store"
|
||||||
require_dependency "s3_helper"
|
require_dependency "s3_helper"
|
||||||
|
@ -23,8 +24,8 @@ module FileStore
|
||||||
# - content_type
|
# - content_type
|
||||||
# - cache_locally
|
# - cache_locally
|
||||||
def store_file(file, path, opts={})
|
def store_file(file, path, opts={})
|
||||||
filename = opts[:filename].presence
|
filename = opts[:filename].presence
|
||||||
content_type = opts[:content_type].presence
|
content_type = opts[:content_type].presence
|
||||||
# cache file locally when needed
|
# cache file locally when needed
|
||||||
cache_file(file, File.basename(path)) if opts[:cache_locally]
|
cache_file(file, File.basename(path)) if opts[:cache_locally]
|
||||||
# stored uploaded are public by default
|
# stored uploaded are public by default
|
||||||
|
@ -48,9 +49,13 @@ module FileStore
|
||||||
|
|
||||||
def has_been_uploaded?(url)
|
def has_been_uploaded?(url)
|
||||||
return false if url.blank?
|
return false if url.blank?
|
||||||
return true if url.start_with?(absolute_base_url)
|
|
||||||
return true if SiteSetting.s3_cdn_url.present? && url.start_with?(SiteSetting.s3_cdn_url)
|
base_hostname = URI.parse(absolute_base_url).hostname
|
||||||
false
|
return true if url[base_hostname]
|
||||||
|
|
||||||
|
return false if SiteSetting.s3_cdn_url.blank?
|
||||||
|
cdn_hostname = URI.parse(SiteSetting.s3_cdn_url || "").hostname
|
||||||
|
cdn_hostname.presence && url[cdn_hostname]
|
||||||
end
|
end
|
||||||
|
|
||||||
def absolute_base_url
|
def absolute_base_url
|
||||||
|
@ -72,12 +77,13 @@ module FileStore
|
||||||
|
|
||||||
def path_for(upload)
|
def path_for(upload)
|
||||||
url = upload.try(:url)
|
url = upload.try(:url)
|
||||||
FileStore::LocalStore.new.path_for(upload) if url && url[0] == "/" && url[1] != "/"
|
FileStore::LocalStore.new.path_for(upload) if url && url[/^\/[^\/]/]
|
||||||
end
|
end
|
||||||
|
|
||||||
def cdn_url(url)
|
def cdn_url(url)
|
||||||
return url if SiteSetting.s3_cdn_url.blank?
|
return url if SiteSetting.s3_cdn_url.blank?
|
||||||
url.sub(absolute_base_url, SiteSetting.s3_cdn_url)
|
schema = url[/^(https?:)?\/\//, 1]
|
||||||
|
url.sub("#{schema}#{absolute_base_url}", SiteSetting.s3_cdn_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cache_avatar(avatar, user_id)
|
def cache_avatar(avatar, user_id)
|
||||||
|
@ -91,9 +97,10 @@ module FileStore
|
||||||
end
|
end
|
||||||
|
|
||||||
def s3_bucket
|
def s3_bucket
|
||||||
return @s3_bucket if @s3_bucket
|
@s3_bucket ||= begin
|
||||||
raise Discourse::SiteSettingMissing.new("s3_upload_bucket") if SiteSetting.s3_upload_bucket.blank?
|
raise Discourse::SiteSettingMissing.new("s3_upload_bucket") if SiteSetting.s3_upload_bucket.blank?
|
||||||
@s3_bucket = SiteSetting.s3_upload_bucket.downcase
|
SiteSetting.s3_upload_bucket.downcase
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,18 +37,11 @@ module PrettyText
|
||||||
UrlHelper.schemaless UrlHelper.absolute avatar_template
|
UrlHelper.schemaless UrlHelper.absolute avatar_template
|
||||||
end
|
end
|
||||||
|
|
||||||
def mention_lookup(username)
|
def mention_lookup(name)
|
||||||
return false unless username
|
return false if name.blank?
|
||||||
if Group.exec_sql('SELECT 1 FROM groups WHERE name = ?', username).values.length == 1
|
return "group" if Group.where(name: name).exists?
|
||||||
"group"
|
return "user" if User.where(username_lower: name.downcase).exists?
|
||||||
else
|
nil
|
||||||
username = username.downcase
|
|
||||||
if User.exec_sql('SELECT 1 FROM users WHERE username_lower = ?', username).values.length == 1
|
|
||||||
"user"
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def category_hashtag_lookup(category_slug)
|
def category_hashtag_lookup(category_slug)
|
||||||
|
@ -306,12 +299,7 @@ JS
|
||||||
def self.add_s3_cdn(doc)
|
def self.add_s3_cdn(doc)
|
||||||
doc.css("img").each do |img|
|
doc.css("img").each do |img|
|
||||||
next unless img["src"]
|
next unless img["src"]
|
||||||
if img["src"].include? Discourse.store.absolute_base_url
|
img["src"] = Discourse.store.cdn_url(img["src"])
|
||||||
src = img["src"].sub(Discourse.store.absolute_base_url, SiteSetting.s3_cdn_url)
|
|
||||||
# absolute is // style so we may have added an extra https:// here
|
|
||||||
src = src.sub(/https?:h/, "h")
|
|
||||||
img["src"] = src
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class UrlHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.schemaless(url)
|
def self.schemaless(url)
|
||||||
url.sub(/^http:/, "")
|
url.sub(/^http:/i, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user