Support Unicode characters in filenames, both in source filenames and in the names of proxied paths. Fixes #332.

This commit is contained in:
Ben Hollis 2012-04-01 20:52:22 -07:00
parent 23e0586896
commit dddd409336
9 changed files with 46 additions and 13 deletions

View file

@ -21,6 +21,7 @@ Feature: Dynamic Pages
| target_ignore2.html | | target_ignore2.html |
| target_ignore3.html | | target_ignore3.html |
| target_ignore4.html | | target_ignore4.html |
| .html |
Then the following files should not exist: Then the following files should not exist:
| should_be_ignored.html | | should_be_ignored.html |
| should_be_ignored2.html | | should_be_ignored2.html |

View file

@ -0,0 +1,14 @@
Feature: Unicode filenames
In order to support non-ASCII characters in filenames
Scenario: Build with files containing unicode characters in their name
Given a successfully built app at "unicode-filenames-app"
When I cd to "build"
Then the file "snowmen-rule-.html" should contain ""
Scenario: Preview with files containing unicode characters in their name
Given the Server is running at "unicode-filenames-app"
When I go to "/snowmen-rule-.html"
# There seem to be encoding issues w/ the test framework so we can't check the content
Then I should see "Snowman!"

View file

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
page "/fake.html", :proxy => "/real.html", :layout => false page "/fake.html", :proxy => "/real.html", :layout => false
page "fake2.html", :proxy => "/real.html", :layout => false page "fake2.html", :proxy => "/real.html", :layout => false
page "fake3.html", :proxy => "real.html", :layout => false page "fake3.html", :proxy => "real.html", :layout => false
@ -28,6 +29,8 @@ page "/target_ignore4.html", :proxy => "should_be_ignored8.html", :ignore => tru
end end
end end
page "明日がある.html", :proxy => "/real.html", :layout => false
page "f*/*" do page "f*/*" do
@all_glob = "I am all glob" @all_glob = "I am all glob"
end end

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,4 @@
Snowman!
<div style="text-align:center; font-size:4000%;">
</div>

View file

@ -13,6 +13,10 @@ require "middleman-core/vendor/hooks-0.2.0/lib/hooks"
require "middleman-core/sitemap" require "middleman-core/sitemap"
# Let's serve all HTML as UTF-8
::Rack::Mime::MIME_TYPES['.html'] = 'text/html;charset=utf8'
::Rack::Mime::MIME_TYPES['.htm'] = 'text/html;charset=utf8'
# Core Middleman Class # Core Middleman Class
module Middleman module Middleman
class Application class Application
@ -381,16 +385,18 @@ module Middleman
start_time = Time.now start_time = Time.now
# Normalize the path and add index if we're looking at a directory # Normalize the path and add index if we're looking at a directory
@original_path = env["PATH_INFO"].dup @original_path = URI.decode(env["PATH_INFO"].dup)
@escaped_path = @original_path.gsub("%20", " ") if @original_path.respond_to? :force_encoding
@request_path = full_path(@escaped_path) @original_path.force_encoding('UTF-8')
end
@request_path = full_path(@original_path)
# Run before callbacks # Run before callbacks
run_hook :before run_hook :before
if @escaped_path != @request_path if @original_path != @request_path
# Get the resource object for this path # Get the resource object for this path
resource = sitemap.find_resource_by_destination_path(@escaped_path) resource = sitemap.find_resource_by_destination_path(@original_path)
end end
# Get the resource object for this full path # Get the resource object for this full path

View file

@ -104,7 +104,8 @@ module Middleman::Cli
output_file = File.join(build_dir, resource.destination_path) output_file = File.join(build_dir, resource.destination_path)
begin begin
response = self.class.shared_rack.get(resource.destination_path.gsub(/\s/, "%20")) response = self.class.shared_rack.get(URI.escape(resource.destination_path))
if response.status == 200 if response.status == 200
create_file(output_file, response.body, { :force => true }) create_file(output_file, response.body, { :force => true })
else else
@ -201,7 +202,7 @@ module Middleman::Cli
@app.sitemap.resources.select do |resource| @app.sitemap.resources.select do |resource|
resource.ext == ".css" resource.ext == ".css"
end.each do |resource| end.each do |resource|
Middleman::Cli::Build.shared_rack.get(resource.destination_path.gsub(/\s/, "%20")) Middleman::Cli::Build.shared_rack.get(URI.escape(resource.destination_path))
end end
puts "== Checking for Compass sprites" if @app.logging? puts "== Checking for Compass sprites" if @app.logging?

View file

@ -1,3 +1,5 @@
# encoding: UTF-8
require "rack/test" require "rack/test"
Given /^a clean server$/ do Given /^a clean server$/ do
@ -61,11 +63,11 @@ Given /^the Server is running at "([^\"]*)"$/ do |app_path|
end end
When /^I go to "([^\"]*)"$/ do |url| When /^I go to "([^\"]*)"$/ do |url|
@browser.get(url) @browser.get(URI.escape(url))
end end
Then /^going to "([^\"]*)" should not raise an exception$/ do |url| Then /^going to "([^\"]*)" should not raise an exception$/ do |url|
lambda { @browser.get(url) }.should_not raise_exception lambda { @browser.get(URI.escape(url)) }.should_not raise_exception
end end
Then /^I should see "([^\"]*)"$/ do |expected| Then /^I should see "([^\"]*)"$/ do |expected|

View file

@ -29,7 +29,8 @@ module Middleman
# @param [String] path # @param [String] path
# @return [String] # @return [String]
def self.normalize_path(path) def self.normalize_path(path)
path.sub(/^\//, "").gsub("%20", " ") # The tr call works around a bug in Ruby's Unicode handling
path.sub(/^\//, "").tr('','')
end end
# Extract the text of a Rack response as a string. # Extract the text of a Rack response as a string.