]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/mime.cc
2 * DEBUG: section 25 MIME Parsing and Internal Icons
3 * AUTHOR: Harvest Derived
5 * SQUID Web Proxy Cache http://www.squid-cache.org/
6 * ----------------------------------------------------------
8 * Squid is the result of efforts by numerous individuals from
9 * the Internet community; see the CONTRIBUTORS file for full
10 * details. Many organizations have provided support for Squid's
11 * development; see the SPONSORS file for full details. Squid is
12 * Copyrighted (C) 2001 by the Regents of the University of
13 * California; see the COPYRIGHT file for full details. Squid
14 * incorporates software developed and/or copyrighted by other
15 * sources; see the CREDITS file for full details.
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
37 #include "HttpHdrCc.h"
38 #include "HttpReply.h"
39 #include "HttpRequest.h"
43 #include "MemObject.h"
45 #include "RequestFlags.h"
46 #include "SquidConfig.h"
48 #include "StoreClient.h"
54 #define GET_HDR_SZ 1024
56 /* forward declarations */
57 static void mimeFreeMemory(void);
58 static char const *mimeGetIcon(const char *fn
);
60 class MimeIcon
: public StoreClient
63 explicit MimeIcon(const char *aName
);
65 void setName(char const *);
66 char const * getName() const;
68 void created(StoreEntry
*newEntry
);
69 MEMPROXY_CLASS(MimeIcon
);
75 MEMPROXY_CLASS_INLINE(MimeIcon
);
80 explicit MimeEntry(const char *aPattern
, const regex_t
&compiledPattern
,
81 const char *aContentType
,
82 const char *aContentEncoding
, const char *aTransferMode
,
83 bool optionViewEnable
, bool optionDownloadEnable
,
84 const char *anIconName
);
86 MEMPROXY_CLASS(MimeEntry
);
89 regex_t compiled_pattern
;
90 const char *content_type
;
91 const char *content_encoding
;
98 MEMPROXY_CLASS_INLINE(MimeEntry
);
100 static MimeEntry
*MimeTable
= NULL
;
101 static MimeEntry
**MimeTableTail
= &MimeTable
;
104 mimeGetEntry(const char *fn
, int skip_encodings
)
108 char *name
= xstrdup(fn
);
113 for (m
= MimeTable
; m
; m
= m
->next
) {
114 if (regexec(&m
->compiled_pattern
, name
, 0, 0, 0) == 0)
122 else if (strcmp(m
->content_type
, dash_str
))
124 else if (!strcmp(m
->content_encoding
, dash_str
))
127 /* Assume we matched /\.\w$/ and cut off the last extension */
128 if ((t
= strrchr(name
, '.'))) {
131 /* What? A encoding without a extension? */
141 MimeIcon::MimeIcon(const char *aName
) :
142 icon_(xstrdup(aName
))
144 url_
= xstrdup(internalLocalUri("/squid-internal-static/icons/", icon_
));
147 MimeIcon::~MimeIcon()
154 MimeIcon::setName(char const *aString
)
158 icon_
= xstrdup (aString
);
159 url_
= xstrdup (internalLocalUri("/squid-internal-static/icons/", icon_
));
163 MimeIcon::getName() const
169 mimeGetIcon(const char *fn
)
171 MimeEntry
*m
= mimeGetEntry(fn
, 1);
176 if (!strcmp(m
->theIcon
.getName(), dash_str
))
179 return m
->theIcon
.getName();
183 mimeGetIconURL(const char *fn
)
185 char const *icon
= mimeGetIcon(fn
);
190 if (Config
.icons
.use_short_names
) {
193 mb
.Printf("/squid-internal-static/icons/%s", icon
);
196 return internalLocalUri("/squid-internal-static/icons/", icon
);
201 mimeGetContentType(const char *fn
)
203 MimeEntry
*m
= mimeGetEntry(fn
, 1);
208 if (!strcmp(m
->content_type
, dash_str
))
211 return m
->content_type
;
215 mimeGetContentEncoding(const char *fn
)
217 MimeEntry
*m
= mimeGetEntry(fn
, 0);
222 if (!strcmp(m
->content_encoding
, dash_str
))
225 return m
->content_encoding
;
229 mimeGetTransferMode(const char *fn
)
231 MimeEntry
*m
= mimeGetEntry(fn
, 0);
232 return m
? m
->transfer_mode
: 'I';
236 mimeGetDownloadOption(const char *fn
)
238 MimeEntry
*m
= mimeGetEntry(fn
, 1);
239 return m
? m
->download_option
: 0;
243 mimeGetViewOption(const char *fn
)
245 MimeEntry
*m
= mimeGetEntry(fn
, 0);
246 return m
!= 0 ? m
->view_option
: false;
249 /* Initializes/reloads the mime table
250 * Note: Due to Solaris STDIO problems the caller should NOT
251 * call mimeFreeMemory on reconfigure. This way, if STDIO
252 * fails we at least have the old copy loaded.
255 mimeInit(char *filename
)
259 char chopbuf
[BUFSIZ
];
271 int re_flags
= REG_EXTENDED
| REG_NOSUB
| REG_ICASE
;
273 if (filename
== NULL
)
276 if ((fp
= fopen(filename
, "r")) == NULL
) {
277 debugs(25, DBG_IMPORTANT
, "mimeInit: " << filename
<< ": " << xstrerror());
282 setmode(fileno(fp
), O_TEXT
);
287 while (fgets(buf
, BUFSIZ
, fp
)) {
288 if ((t
= strchr(buf
, '#')))
291 if ((t
= strchr(buf
, '\r')))
294 if ((t
= strchr(buf
, '\n')))
300 xstrncpy(chopbuf
, buf
, BUFSIZ
);
302 if ((pattern
= strtok(chopbuf
, w_space
)) == NULL
) {
303 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
307 if ((type
= strtok(NULL
, w_space
)) == NULL
) {
308 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
312 if ((icon
= strtok(NULL
, w_space
)) == NULL
) {
313 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
317 if ((encoding
= strtok(NULL
, w_space
)) == NULL
) {
318 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
322 if ((mode
= strtok(NULL
, w_space
)) == NULL
) {
323 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
330 while ((option
= strtok(NULL
, w_space
)) != NULL
) {
331 if (!strcmp(option
, "+download"))
333 else if (!strcmp(option
, "+view"))
336 debugs(25, DBG_IMPORTANT
, "mimeInit: unknown option: '" << buf
<< "' (" << option
<< ")");
339 if (regcomp(&re
, pattern
, re_flags
) != 0) {
340 debugs(25, DBG_IMPORTANT
, "mimeInit: regcomp error: '" << buf
<< "'");
344 m
= new MimeEntry(pattern
,re
,type
,encoding
,mode
,view_option
,
345 download_option
,icon
);
349 MimeTableTail
= &m
->next
;
351 debugs(25, 5, "mimeInit: added '" << buf
<< "'");
356 for (m
= MimeTable
; m
!= NULL
; m
= m
->next
)
358 debugs(25, DBG_IMPORTANT
, "Finished loading MIME types and icons.");
366 while ((m
= MimeTable
)) {
371 MimeTableTail
= &MimeTable
;
377 const char *type
= mimeGetContentType(icon_
);
380 fatal("Unknown icon format while reading mime.conf\n");
382 StoreEntry::getPublic(this, url_
, Http::METHOD_GET
);
386 MimeIcon::created (StoreEntry
*newEntry
)
388 /* if the icon is already in the store, do nothing */
389 if (!newEntry
->isNull())
396 LOCAL_ARRAY(char, path
, MAXPATHLEN
);
399 snprintf(path
, MAXPATHLEN
, "%s/%s", Config
.icons
.directory
, icon_
);
401 fd
= file_open(path
, O_RDONLY
| O_BINARY
);
403 debugs(25, DBG_CRITICAL
, "Problem opening icon file " << path
<< ": " << xstrerror());
406 if (fstat(fd
, &sb
) < 0) {
407 debugs(25, DBG_CRITICAL
, "Problem opening icon file. Fd: " << fd
<< ", fstat error " << xstrerror());
412 flags
.cachable
= true;
413 StoreEntry
*e
= storeCreateEntry(url_
,url_
,flags
,Http::METHOD_GET
);
415 EBIT_SET(e
->flags
, ENTRY_SPECIAL
);
418 HttpRequest
*r
= HttpRequest::CreateFromUrl(url_
);
421 fatal("mimeLoadIcon: cannot parse internal URL");
423 e
->mem_obj
->request
= r
;
424 HTTPMSGLOCK(e
->mem_obj
->request
);
426 HttpReply
*reply
= new HttpReply
;
428 reply
->setHeaders(Http::scOkay
, NULL
, mimeGetContentType(icon_
), sb
.st_size
, sb
.st_mtime
, -1);
429 reply
->cache_control
= new HttpHdrCc();
430 reply
->cache_control
->maxAge(86400);
431 reply
->header
.putCc(reply
->cache_control
);
432 e
->replaceHttpReply(reply
);
434 /* read the file into the buffer and append it to store */
435 buf
= (char *)memAllocate(MEM_4K_BUF
);
436 while ((n
= FD_READ_METHOD(fd
, buf
, 4096)) > 0)
444 memFree(buf
, MEM_4K_BUF
);
445 debugs(25, 3, "Loaded icon " << url_
);
448 MimeEntry::~MimeEntry()
451 safe_free(content_type
);
452 safe_free(content_encoding
);
453 regfree(&compiled_pattern
);
456 MimeEntry::MimeEntry(const char *aPattern
, const regex_t
&compiledPattern
,
457 const char *aContentType
, const char *aContentEncoding
,
458 const char *aTransferMode
, bool optionViewEnable
,
459 bool optionDownloadEnable
, const char *anIconName
) :
460 pattern(xstrdup(aPattern
)),
461 compiled_pattern(compiledPattern
),
462 content_type(xstrdup(aContentType
)),
463 content_encoding(xstrdup(aContentEncoding
)),
464 view_option(optionViewEnable
),
465 download_option(optionViewEnable
),
466 theIcon(anIconName
), next(NULL
)
468 if (!strcasecmp(aTransferMode
, "ascii"))
470 else if (!strcasecmp(aTransferMode
, "text"))