【问题标题】:Gitlab (rails) "raw" file mime type for .svg files is 'text/plain'. Can it be configured to output as 'image/svg+xml'?.svg 文件的 Gitlab(rails)“原始”文件 mime 类型是“文本/纯文本”。是否可以将其配置为输出为“image/svg+xml”?
【发布时间】:2015-07-10 23:59:57
【问题描述】:

我已经在本地服务器上安装了 Gitlab 以进行评估,对我来说一个关键功能是让 svg 文件在 wiki 中显示为图像。如果我将文件拖到 wiki 编辑器中,它就会工作,它会生成一个如下所示的 url:

在 wiki markdown 中:

![my svg diagram](http://server/my-group/my-project/uploads/90cdd5d76a05957ab7cf8854c55a38b8/my-diagram.svg)

页面 html 中的结果:

<img src="http://server/my-group/my-project/uploads/90cdd5d76a05957ab7cf8854c55a38b8/my-diagram.svg" alt="my svg diagram">

为了让它发挥作用,我不得不编辑 /opt/gitlab/embedded/service/gitlab-rails/config/initializers/mime_types.rb 以添加该行:

Mime::Type.register_alias "image/svg+xml", :svg

如果我想将 svg 文件拖到 wiki 中并将其存储在项目的“上传”部分,那就太好了,但是,我真正想做的是显示来自 git 存储库的 svg 图像。 (这样,例如,当 svg 图发生变化时,我不必在 wiki 中寻找它,它只会从 master 分支中获取它)

我发现,例如,这是一个 repo 文件的链接:

http://server/my-group/my-project/raw/master/docsfolder/my-drawing.svg

但是,对于以这种方式引用的 svg 文件,mime 类型似乎是 text/plain,而带有 src 的图像将不会显示。有没有办法让他们image/svg+xml?似乎 mime_types.rb 配置文件不会影响这个“原始”输出。还是有另一种方法可以链接到 repo 文件并获取指定的 mime 类型?

我也尝试过&lt;object type="image/svg+xml" data="...&lt;embed type="image/svg+xml" src=" 甚至 iframe,但这些都不起作用。

注意:它确实适用于来自 repo 的 jpg 图像,但不适用于 svg 图像。

【问题讨论】:

    标签: ruby-on-rails gitlab


    【解决方案1】:

    找到了。似乎内容类型是在 raw_controller.rb 文件中的 ruby​​ 代码中设置的。所以我编辑

    /opt/gitlab/embedded/service/gitlab-rails/app/controllers/projects/raw_controller.rb
    

    改变这个:

      def get_blob_type
        if @blob.text?
          'text/plain; charset=utf-8'
        else
          'application/octet-stream'
        end
      end
    

    到这样的事情:

      def get_blob_type
        extn = File.extname(@blob.name).downcase
        if @blob.text?
          if extn == ".svg"
            'image/svg+xml'
          else 
            'text/plain; charset=utf-8'
          end
        else
          case extn
            when ".jpg", ".jpeg"
              'image/jpeg'
            when ".gif"
              'image/gif'
            when ".png"
              'image/png'
            when ".bmp"
              'image/bmp'
            when ".tiff"
               'image/tiff'
            else
              'application/octet-stream'
          end
        end
      end
    

    然后sudo gitlab-ctrl restart

    现在在我的降价中,如果我这样做:

    ![my-diagram](http://server/my-group/my-project/raw/master/docsfolder/my-drawing.svg)
    

    有效!

    我以前从未使用过 ruby​​,所以也许有更好的方法,但到目前为止对我有用。

    【讨论】:

    • 您好 Chris,我认为未启用此功能的原因是安全性:在 SVG 中,您可以使用 Javascript,它现在代表您的 gitlab 实例交付,因此坏人或女孩可以捕获您的会话。
    • 这很有趣,我不知道你可以将javascript注入svg文件!我确实在我使用的系统上进行了尝试,如上修改,通过在文件中的关闭 svg 标记之前注入&lt;script&gt;alert('hi');&lt;/script&gt;,并将其签入。wiki 仍然显示图像,并且没有执行 javascript。 (IE 和 FF)也许 img 标签不运行脚本?如果我在它自己的页面中查看原始文件,它确实执行了脚本。
    • 只要标记图像符号包含&lt;img&gt; 标记,它就会将svg 视为“静态”svg...如果您以原始模式打开文件,则脚本可能会执行(没有'不要测试它)......但是当我在受控环境(少数已知用户)中使用gitlab时,我们将在这里接受安全问题。很好的解决方案。谢谢!
    • 当 GitLab 单独显示 SVG 图像时,它会对其进行清理以删除 JavaScript(有时显然是其他文本)。但是 Markdown 中的内联图像只是链接到原始 URL,并没有得到处理。我已经更详细地记录了这一点here
    • GitLab 11.x CE(综合版)中的路径为:/opt/gitlab/embedded/service/gitlab-rails/app/helpers/blob_helper.rb
    【解决方案2】:

    101chris 的提案在 7.x 上运行良好,但需要在 gitlab 8.x 上进行一些修改。 这是我在 8.14.4 上测试的更新:

    /opt/gitlab/embedded/service/gitlab-rails/app/helpers/blob_helper.rb:

      def safe_content_type(blob)
        if blob.text?
          case File.extname(blob.name).downcase
          when '.html'
            'text/html'
          when '.css'
            'text/css'
          when '.xml'
            'text/xml'
          when '.js'
            'application/javascript'
          else
            'text/plain; charset=utf-8'
          end
        elsif blob.image?
          blob.content_type
        else
          'application/octet-stream'
        end
      end
    

    【讨论】:

    • 这个代码块似乎在 GitLab 11.7-CE 中消失了。我在任何其他文件中都找不到等效项,所以看起来他们已经对代码进行了相当多的更改。
    【解决方案3】:

    出现在 GitLab 11.7-CE 中需要更新/opt/gitlab/embedded/service/gitlab-rails/app/helpers/workhorse_helper.rb 并更改以下部分:

    def send_git_blob(repository, blob, inline: true)
      headers.store(*Gitlab::Workhorse.send_git_blob(repository, blob))
    
      headers['Content-Disposition'] = inline ? 'inline' : 'attachment'
      workhorse_set_content_type!
    
      render plain: ""
    end
    

    如下(以“.html”为例):

    def send_git_blob(repository, blob, inline: true)
      headers.store(*Gitlab::Workhorse.send_git_blob(repository, blob))
    
      headers['Content-Disposition'] = inline ? 'inline' : 'attachment'
    
      if File.extname(@blob.name).downcase == '.html'
        headers['Content-Type'] = 'text/html'
      else
        workhorse_set_content_type!
      end
    
      render plain: ""
    end
    

    正如其他人所说,出于安全原因,Content-Type 设置为text/plain,因为它可以保护您免受 XSS 攻击。如果您没有使用 GitLab 的受信任的封闭用户集,请不要这样做。

    【讨论】:

      猜你喜欢
      • 2011-12-07
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 2015-08-11
      • 2021-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多