content_type 2.1.2 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +1 -0
- data/Rakefile +2 -2
- data/ext/content_type.c +24 -1
- metadata +3 -3
data/README
CHANGED
@@ -16,6 +16,7 @@ SYNOPSIS
|
|
16
16
|
irb> require 'content_type'
|
17
17
|
irb> File.content_type('file.pdf') #=> "application/pdf"
|
18
18
|
irb> File.open('file.doc').content_type #=> "application/msword"
|
19
|
+
irb> "hi".content_type #=> "text/plain"
|
19
20
|
irb> ContentType.new('file.jpg').content_type #=> "image/jpeg"
|
20
21
|
|
21
22
|
DESCRIPTION
|
data/Rakefile
CHANGED
@@ -29,8 +29,8 @@ Jeweler::Tasks.new do |s|
|
|
29
29
|
s.email = 'dsturnbull@me.com'
|
30
30
|
s.homepage = 'http://github.com/dsturnbull/content_type'
|
31
31
|
s.description =<<-eod
|
32
|
-
Provides ContentType#content_type, File#content_type
|
33
|
-
|
32
|
+
Provides ContentType#content_type, File#content_type, File::content_type
|
33
|
+
and String#content_type methods to determine mime type
|
34
34
|
eod
|
35
35
|
s.executables = []
|
36
36
|
s.authors = ['David Turnbull']
|
data/ext/content_type.c
CHANGED
@@ -4,19 +4,27 @@
|
|
4
4
|
#include <sys/stat.h>
|
5
5
|
#include <stdbool.h>
|
6
6
|
|
7
|
+
// see libmagic(3)
|
7
8
|
#define MAGIC_OPTIONS MAGIC_SYMLINK | MAGIC_MIME_TYPE | MAGIC_PRESERVE_ATIME
|
9
|
+
|
10
|
+
// presume file extensions are at max 16 chars. this is fine for now since
|
11
|
+
// only microsoft crap is overridden.
|
8
12
|
#define MAX_EXT_LEN 16
|
9
13
|
|
14
|
+
// ContentType prototypes
|
10
15
|
VALUE content_type = Qnil;
|
11
16
|
VALUE content_type_initialize(VALUE self, VALUE path);
|
12
17
|
VALUE content_type_content_type(VALUE self);
|
13
18
|
|
19
|
+
// File prototypes
|
14
20
|
VALUE file_content_type_wrap(VALUE self, VALUE path);
|
15
21
|
VALUE file_content_type(VALUE self);
|
16
22
|
VALUE file_singleton_content_type(VALUE self, VALUE path);
|
17
23
|
|
24
|
+
// String prototypes
|
18
25
|
VALUE string_content_type(VALUE self);
|
19
26
|
|
27
|
+
// internal prototypes
|
20
28
|
bool content_type_file_ext(VALUE self, char *ext);
|
21
29
|
void magic_fail(const char *error);
|
22
30
|
|
@@ -41,6 +49,7 @@ const char *content_type_ext_overrides[][2] = {
|
|
41
49
|
{ "xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template" },
|
42
50
|
};
|
43
51
|
|
52
|
+
// Init_content_type - initialize the extension
|
44
53
|
void
|
45
54
|
Init_content_type()
|
46
55
|
{
|
@@ -64,6 +73,8 @@ Init_content_type()
|
|
64
73
|
rb_define_method(rb_cString, "content_type", string_content_type, 0);
|
65
74
|
}
|
66
75
|
|
76
|
+
// content_type_initialize - initialize the object and check file path exists
|
77
|
+
//
|
67
78
|
// iv @content_type, @filepath and @processed are available in all variations
|
68
79
|
// because each implementation creates a ContentType obj through here
|
69
80
|
// (except String#content_type)
|
@@ -85,7 +96,7 @@ content_type_initialize(VALUE self, VALUE path)
|
|
85
96
|
return self;
|
86
97
|
}
|
87
98
|
|
88
|
-
// content_type_file_ext
|
99
|
+
// content_type_file_ext - return the file extension of the file
|
89
100
|
bool
|
90
101
|
content_type_file_ext(VALUE self, char *ext)
|
91
102
|
{
|
@@ -115,6 +126,7 @@ content_type_file_ext(VALUE self, char *ext)
|
|
115
126
|
return false;
|
116
127
|
}
|
117
128
|
|
129
|
+
// content_type_content_type - check for hardcoded extensions or use libmagic
|
118
130
|
VALUE
|
119
131
|
content_type_content_type(VALUE self)
|
120
132
|
{
|
@@ -125,6 +137,7 @@ content_type_content_type(VALUE self)
|
|
125
137
|
char ext[MAX_EXT_LEN]; // TODO dynamicly sized
|
126
138
|
int i;
|
127
139
|
|
140
|
+
// check for hardcoded extension overrides first
|
128
141
|
if (content_type_file_ext(self, ext))
|
129
142
|
for (i = sizeof(content_type_ext_overrides) / sizeof(char *) / 2 - 1;
|
130
143
|
i >= 0; i--) {
|
@@ -134,12 +147,14 @@ content_type_content_type(VALUE self)
|
|
134
147
|
|
135
148
|
if ((memcmp(ext, o_ext, strlen(o_ext))) == 0) {
|
136
149
|
ct = rb_str_new2(o_mime);
|
150
|
+
// memoize
|
137
151
|
rb_iv_set(self, "@content_type", ct);
|
138
152
|
rb_iv_set(self, "@processed", Qtrue);
|
139
153
|
return ct;
|
140
154
|
}
|
141
155
|
}
|
142
156
|
|
157
|
+
// otherwise use libmagic to get the mime type
|
143
158
|
if (rb_iv_get(self, "@processed"))
|
144
159
|
return rb_iv_get(self, "@content_type");
|
145
160
|
|
@@ -153,6 +168,8 @@ content_type_content_type(VALUE self)
|
|
153
168
|
magic_fail("file");
|
154
169
|
|
155
170
|
ct = rb_str_new(mime, strlen(mime));
|
171
|
+
|
172
|
+
// memoize
|
156
173
|
rb_iv_set(self, "@content_type", ct);
|
157
174
|
rb_iv_set(self, "@processed", Qtrue);
|
158
175
|
magic_close(mh);
|
@@ -160,6 +177,7 @@ content_type_content_type(VALUE self)
|
|
160
177
|
return ct;
|
161
178
|
}
|
162
179
|
|
180
|
+
// file_content_type_wrap - pass file path into ContentType#content_type
|
163
181
|
VALUE
|
164
182
|
file_content_type_wrap(VALUE self, VALUE path)
|
165
183
|
{
|
@@ -172,18 +190,21 @@ file_content_type_wrap(VALUE self, VALUE path)
|
|
172
190
|
return rb_funcall(ct, rb_intern("content_type"), 0);
|
173
191
|
}
|
174
192
|
|
193
|
+
// file_content_type - provide File#content_type
|
175
194
|
VALUE
|
176
195
|
file_content_type(VALUE self)
|
177
196
|
{
|
178
197
|
return file_content_type_wrap(self, rb_funcall(self, rb_intern("path"), 0));
|
179
198
|
}
|
180
199
|
|
200
|
+
// file_singleton_content_type - provide File.content_type
|
181
201
|
VALUE
|
182
202
|
file_singleton_content_type(VALUE self, VALUE path)
|
183
203
|
{
|
184
204
|
return file_content_type_wrap(self, path);
|
185
205
|
}
|
186
206
|
|
207
|
+
// string_content_type - pass the string as a buffer to libmagic
|
187
208
|
VALUE
|
188
209
|
string_content_type(VALUE self)
|
189
210
|
{
|
@@ -209,6 +230,7 @@ string_content_type(VALUE self)
|
|
209
230
|
return ct;
|
210
231
|
}
|
211
232
|
|
233
|
+
// magic_fail - raise exceptions
|
212
234
|
void
|
213
235
|
magic_fail(const char *error)
|
214
236
|
{
|
@@ -219,3 +241,4 @@ magic_fail(const char *error)
|
|
219
241
|
sprintf((char *)error_message, format, error);
|
220
242
|
rb_raise(rb_const_get(rb_cObject, rb_intern("RuntimeError")), error_message);
|
221
243
|
}
|
244
|
+
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 2
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 2.1.
|
8
|
+
- 3
|
9
|
+
version: 2.1.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- David Turnbull
|
@@ -18,7 +18,7 @@ date: 2010-04-10 00:00:00 +10:00
|
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
21
|
-
description: " Provides ContentType#content_type, File#content_type
|
21
|
+
description: " Provides ContentType#content_type, File#content_type, File::content_type\n and String#content_type methods to determine mime type\n"
|
22
22
|
email: dsturnbull@me.com
|
23
23
|
executables: []
|
24
24
|
|