diff options
author | Simon Chiang <simon.a.chiang@gmail.com> | 2010-10-23 14:33:34 -0600 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2010-12-09 12:07:31 -0600 |
commit | 2ed5a13da5d0af5f958b1b9fc115dfaf7347d7df (patch) | |
tree | 86eca69e7afdf62bffd27b9e6635ace6a697bde8 | |
parent | 35bb5ba6746b5d346de9202c004cc926039650c7 (diff) | |
download | rack-2ed5a13da5d0af5f958b1b9fc115dfaf7347d7df.tar.gz |
performance improvement by making derived regexps into constants
-rw-r--r-- | lib/rack/utils.rb | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index bf044207..edc317e2 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -498,10 +498,19 @@ module Rack EOL = "\r\n" MULTIPART_BOUNDARY = "AaB03x" - + MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|n + TOKEN = /[^\s()<>,;:\\"\/\[\]?=]+/ + CONDISP = /Content-Disposition:\s*#{TOKEN}\s*/i + DISPPARM = /;\s*(#{TOKEN})=("(?:\\"|[^"])*"|#{TOKEN})*/ + RFC2183 = /^#{CONDISP}(#{DISPPARM})+$/i + BROKEN_QUOTED = /^#{CONDISP}.*;\sfilename="(.*?)"(?:\s*$|\s*;\s*#{TOKEN}=)/i + BROKEN_UNQUOTED = /^#{CONDISP}.*;\sfilename=(#{TOKEN})/i + MULTIPART_CONTENT_TYPE = /Content-Type: (.*)#{EOL}/ni + MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:.*\s+name="?([^\";]*)"?/ni + MULTIPART_CONTENT_ID = /Content-ID:([^#{EOL}]*)/ni + def self.parse_multipart(env) - unless env['CONTENT_TYPE'] =~ - %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|n + unless env['CONTENT_TYPE'] =~ MULTIPART nil else boundary = "--#{$1}" @@ -534,29 +543,21 @@ module Rack head = buf.slice!(0, i+2) # First \r\n buf.slice!(0, 2) # Second \r\n - token = /[^\s()<>,;:\\"\/\[\]?=]+/ - condisp = /Content-Disposition:\s*#{token}\s*/i - dispparm = /;\s*(#{token})=("(?:\\"|[^"])*"|#{token})*/ - - rfc2183 = /^#{condisp}(#{dispparm})+$/i - broken_quoted = /^#{condisp}.*;\sfilename="(.*?)"(?:\s*$|\s*;\s*#{token}=)/i - broken_unquoted = /^#{condisp}.*;\sfilename=(#{token})/i - - if head =~ rfc2183 - filename = Hash[head.scan(dispparm)]['filename'] + if head =~ RFC2183 + filename = Hash[head.scan(DISPPARM)]['filename'] filename = $1 if filename and filename =~ /^"(.*)"$/ - elsif head =~ broken_quoted + elsif head =~ BROKEN_QUOTED filename = $1 - elsif head =~ broken_unquoted + elsif head =~ BROKEN_UNQUOTED filename = $1 end if filename && filename !~ /\\[^\\"]/ filename = Utils.unescape(filename).gsub(/\\(.)/, '\1') end - - content_type = head[/Content-Type: (.*)#{EOL}/ni, 1] - name = head[/Content-Disposition:.*\s+name="?([^\";]*)"?/ni, 1] || head[/Content-ID:\s*([^#{EOL}]*)/ni, 1] + + content_type = head[MULTIPART_CONTENT_TYPE, 1] + name = head[MULTIPART_CONTENT_DISPOSITION, 1] || head[MULTIPART_CONTENT_ID, 1] if filename body = Tempfile.new("RackMultipart") |