Lines 62-68
Link Here
|
62 |
public static final String RUBY_MIME_TYPE = "text/x-ruby"; // application/x-ruby is also used a fair bit. |
62 |
public static final String RUBY_MIME_TYPE = "text/x-ruby"; // application/x-ruby is also used a fair bit. |
63 |
|
63 |
|
64 |
/** Number of bytes to sniff from the file headers */ |
64 |
/** Number of bytes to sniff from the file headers */ |
65 |
private static final int HEADER_LENGTH = 20; |
65 |
static final int HEADER_LENGTH = 40; |
66 |
|
66 |
|
67 |
public RubyMimeResolver() { |
67 |
public RubyMimeResolver() { |
68 |
} |
68 |
} |
Lines 104-214
Link Here
|
104 |
return null; |
104 |
return null; |
105 |
} |
105 |
} |
106 |
|
106 |
|
107 |
public static boolean isRubyHeader(byte[] header) { |
|
|
108 |
int max = header.length; |
109 |
|
110 |
if ((max < 2) || (header[0] != '#') || (header[1] != '!')) { |
111 |
return false; |
112 |
} |
113 |
|
114 |
// See if we have either |
115 |
// #!/usr/bin/ruby |
116 |
// or some variation of that, e.g. |
117 |
// #! C:\programs\ruby.exe |
118 |
// or the env variety |
119 |
// #!/usr/bin/env ruby |
120 |
// or some variety of that |
121 |
|
122 |
// Skip spaces |
123 |
int index = 2; |
124 |
|
125 |
while ((index < max) && (header[index] == ' ')) { |
126 |
index++; |
127 |
} |
128 |
|
129 |
// Look for the end of the path |
130 |
while ((index < max) && (header[index] != '\n') && (header[index] != ' ')) { |
131 |
index++; |
132 |
} |
133 |
|
134 |
index--; |
135 |
|
136 |
// Back up and see what the last word was |
137 |
while ((index >= 2) && (header[index] != '/') && (header[index] != '\\') && |
138 |
(header[index] != ' ')) { |
139 |
index--; |
140 |
} |
141 |
|
142 |
index++; |
143 |
|
144 |
// See if it's "ruby", "jruby", or "env" ? |
145 |
if ((((index + 3) < max) && (header[index] == 'r') && (header[index + 1] == 'u') && |
146 |
(header[index + 2] == 'b') && (header[index + 3] == 'y')) || |
147 |
(((index + 4) < max) && (header[index] == 'j') && (header[index + 1] == 'r') && |
148 |
(header[index + 2] == 'u') && (header[index + 3] == 'b') && |
149 |
(header[index + 4] == 'y'))) { |
150 |
// It's ruby or jruby |
151 |
// See if the suffix is okay |
152 |
if (header[index] == 'j') { |
153 |
index += 5; |
154 |
} else { |
155 |
index += 4; |
156 |
} |
157 |
|
158 |
if ((index >= max) || (header[index] == '\n') || (header[index] == ' ')) { |
159 |
return true; |
160 |
} |
161 |
|
162 |
if ((header[index] == '.') && ((index + 3) < max) && (header[index + 1] == 'e') && |
163 |
(header[index + 2] == 'x') && (header[index + 3] == 'e')) { |
164 |
return true; |
165 |
} |
166 |
|
167 |
return false; |
168 |
} else if (((index + 2) < max) && (header[index] == 'e') && (header[index + 1] == 'n') && |
169 |
(header[index + 2] == 'v')) { |
170 |
index += 3; |
171 |
|
172 |
// It's env |
173 |
if ((header[index] == ' ') || |
174 |
((header[index] == '.') && ((index + 4) < max) && (header[index + 1] == 'e') && |
175 |
(header[index + 2] == 'x') && (header[index + 3] == 'e') && |
176 |
(header[index + 4] == ' '))) { |
177 |
// Find the next space and look for ruby or jruby |
178 |
if (header[index] == '.') { |
179 |
index += 4; |
180 |
} |
181 |
|
182 |
while ((index < max) && (header[index] == ' ')) { |
183 |
index++; |
184 |
} |
185 |
|
186 |
// Make sure we have "ruby" or "jruby" (or ruby.exe)? |
187 |
if ((((index + 3) < max) && (header[index] == 'r') && (header[index + 1] == 'u') && |
188 |
(header[index + 2] == 'b') && (header[index + 3] == 'y')) || |
189 |
(((index + 4) < max) && (header[index] == 'j') && |
190 |
(header[index + 1] == 'r') && (header[index + 2] == 'u') && |
191 |
(header[index + 3] == 'b') && (header[index + 4] == 'y'))) { |
192 |
// Ensure that nothing FOLLOWS ruby or jruby |
193 |
if (header[index] == 'j') { |
194 |
index += 5; |
195 |
} else { |
196 |
index += 4; |
197 |
} |
198 |
|
199 |
if ((index == max) || (header[index] == '\n') || (header[index] == ' ') || |
200 |
((header[index] == '.') && ((index + 3) < max) && |
201 |
(header[index + 1] == 'e') && (header[index + 2] == 'x') && |
202 |
(header[index + 3] == 'e'))) { |
203 |
return true; |
204 |
} |
205 |
} |
206 |
} |
207 |
} |
208 |
|
209 |
return false; |
210 |
} |
211 |
|
212 |
private byte[] readHeader(FileObject fo) { |
107 |
private byte[] readHeader(FileObject fo) { |
213 |
// See if it looks like a Ruby file based on the shebang line |
108 |
// See if it looks like a Ruby file based on the shebang line |
214 |
byte[] header = new byte[HEADER_LENGTH]; |
109 |
byte[] header = new byte[HEADER_LENGTH]; |
Lines 245-248
Link Here
|
245 |
|
140 |
|
246 |
return header; |
141 |
return header; |
247 |
} |
142 |
} |
|
|
143 |
|
144 |
public static boolean isRubyHeader(byte[] header) { |
145 |
int max = header.length; |
146 |
|
147 |
if ((max < 2) || (header[0] != '#') || (header[1] != '!')) { |
148 |
return false; |
149 |
} |
150 |
|
151 |
// See if the first line contains the word "ruby" (but not as a path component) |
152 |
find: |
153 |
for (int index = 0; index < max - 3; index++) { |
154 |
byte b = header[index]; |
155 |
if (b == '\n') { |
156 |
break; |
157 |
} |
158 |
if (b == 'r' && (header[index + 1] == 'u') && |
159 |
(header[index + 2] == 'b') && (header[index + 3] == 'y')) { |
160 |
// No slash/backslash before the end of the line or next word |
161 |
for (int j = index+4; j < max; j++) { |
162 |
byte c = header[j]; |
163 |
if (c == ' ' || c == '\n') { |
164 |
break; |
165 |
} else if (c == '/' || c == '\\') { |
166 |
continue find; |
167 |
} |
168 |
} |
169 |
return true; |
170 |
} |
171 |
} |
172 |
|
173 |
return false; |
174 |
} |
248 |
} |
175 |
} |