]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/mime.cc
3 * DEBUG: section 25 MIME Parsing and Internal Icons
4 * AUTHOR: Harvest Derived
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
38 #include "HttpHdrCc.h"
39 #include "HttpReply.h"
40 #include "HttpRequest.h"
45 #include "MemObject.h"
46 #include "RequestFlags.h"
47 #include "SquidConfig.h"
49 #include "StoreClient.h"
55 #define GET_HDR_SZ 1024
57 /* forward declarations */
58 static void mimeFreeMemory(void);
59 static char const *mimeGetIcon(const char *fn
);
61 class MimeIcon
: public StoreClient
67 void setName (char const *);
68 char const * getName () const;
71 void created (StoreEntry
*newEntry
);
82 void *operator new (size_t byteCount
);
83 void operator delete (void *address
);
86 regex_t compiled_pattern
;
89 char *content_encoding
;
92 unsigned int view_option
:1;
93 unsigned int download_option
:1;
99 static mimeEntry
*MimeTable
= NULL
;
100 static mimeEntry
**MimeTableTail
= &MimeTable
;
103 mimeEntry::operator new (size_t byteCount
)
105 return xcalloc(1, byteCount
);
109 mimeEntry::operator delete (void *address
)
115 mimeGetEntry(const char *fn
, int skip_encodings
)
119 char *name
= xstrdup(fn
);
124 for (m
= MimeTable
; m
; m
= m
->next
) {
125 if (regexec(&m
->compiled_pattern
, name
, 0, 0, 0) == 0)
133 else if (strcmp(m
->content_type
, dash_str
))
135 else if (!strcmp(m
->content_encoding
, dash_str
))
138 /* Assume we matched /\.\w$/ and cut off the last extension */
139 if ((t
= strrchr(name
, '.'))) {
142 /* What? A encoding without a extension? */
152 MimeIcon::MimeIcon () : icon (NULL
), url (NULL
)
155 MimeIcon::~MimeIcon ()
161 MimeIcon::setName (char const *aString
)
165 icon
= xstrdup (aString
);
166 url
= xstrdup (internalLocalUri("/squid-internal-static/icons/", icon
));
170 MimeIcon::getName () const
183 mimeGetIcon(const char *fn
)
185 mimeEntry
*m
= mimeGetEntry(fn
, 1);
190 if (!strcmp(m
->theIcon
.getName(), dash_str
))
193 return m
->theIcon
.getName();
197 mimeGetIconURL(const char *fn
)
199 char const *icon
= mimeGetIcon(fn
);
204 if (Config
.icons
.use_short_names
) {
207 mb
.Printf("/squid-internal-static/icons/%s", icon
);
210 return internalLocalUri("/squid-internal-static/icons/", icon
);
215 mimeGetContentType(const char *fn
)
217 mimeEntry
*m
= mimeGetEntry(fn
, 1);
222 if (!strcmp(m
->content_type
, dash_str
))
225 return m
->content_type
;
229 mimeGetContentEncoding(const char *fn
)
231 mimeEntry
*m
= mimeGetEntry(fn
, 0);
236 if (!strcmp(m
->content_encoding
, dash_str
))
239 return m
->content_encoding
;
243 mimeGetTransferMode(const char *fn
)
245 mimeEntry
*m
= mimeGetEntry(fn
, 0);
246 return m
? m
->transfer_mode
: 'I';
250 mimeGetDownloadOption(const char *fn
)
252 mimeEntry
*m
= mimeGetEntry(fn
, 1);
253 return m
? m
->download_option
: 0;
257 mimeGetViewOption(const char *fn
)
259 mimeEntry
*m
= mimeGetEntry(fn
, 0);
260 return m
? m
->view_option
: 0;
263 /* Initializes/reloads the mime table
264 * Note: Due to Solaris STDIO problems the caller should NOT
265 * call mimeFreeMemory on reconfigure. This way, if STDIO
266 * fails we at least have the old copy loaded.
269 mimeInit(char *filename
)
273 char chopbuf
[BUFSIZ
];
285 int re_flags
= REG_EXTENDED
| REG_NOSUB
| REG_ICASE
;
287 if (filename
== NULL
)
290 if ((fp
= fopen(filename
, "r")) == NULL
) {
291 debugs(25, DBG_IMPORTANT
, "mimeInit: " << filename
<< ": " << xstrerror());
296 setmode(fileno(fp
), O_TEXT
);
301 while (fgets(buf
, BUFSIZ
, fp
)) {
302 if ((t
= strchr(buf
, '#')))
305 if ((t
= strchr(buf
, '\r')))
308 if ((t
= strchr(buf
, '\n')))
314 xstrncpy(chopbuf
, buf
, BUFSIZ
);
316 if ((pattern
= strtok(chopbuf
, w_space
)) == NULL
) {
317 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
321 if ((type
= strtok(NULL
, w_space
)) == NULL
) {
322 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
326 if ((icon
= strtok(NULL
, w_space
)) == NULL
) {
327 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
331 if ((encoding
= strtok(NULL
, w_space
)) == NULL
) {
332 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
336 if ((mode
= strtok(NULL
, w_space
)) == NULL
) {
337 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
344 while ((option
= strtok(NULL
, w_space
)) != NULL
) {
345 if (!strcmp(option
, "+download"))
347 else if (!strcmp(option
, "+view"))
350 debugs(25, DBG_IMPORTANT
, "mimeInit: unknown option: '" << buf
<< "' (" << option
<< ")");
353 if (regcomp(&re
, pattern
, re_flags
) != 0) {
354 debugs(25, DBG_IMPORTANT
, "mimeInit: regcomp error: '" << buf
<< "'");
359 m
->pattern
= xstrdup(pattern
);
360 m
->content_type
= xstrdup(type
);
361 m
->theIcon
.setName(icon
);
362 m
->content_encoding
= xstrdup(encoding
);
363 m
->compiled_pattern
= re
;
365 if (!strcasecmp(mode
, "ascii"))
366 m
->transfer_mode
= 'A';
367 else if (!strcasecmp(mode
, "text"))
368 m
->transfer_mode
= 'A';
370 m
->transfer_mode
= 'I';
372 m
->view_option
= view_option
;
374 m
->download_option
= download_option
;
378 MimeTableTail
= &m
->next
;
380 debugs(25, 5, "mimeInit: added '" << buf
<< "'");
385 * Create Icon StoreEntry's
388 for (m
= MimeTable
; m
!= NULL
; m
= m
->next
)
391 debugs(25, DBG_IMPORTANT
, "Loaded Icons.");
399 while ((m
= MimeTable
)) {
401 safe_free(m
->pattern
);
402 safe_free(m
->content_type
);
404 safe_free(m
->content_encoding
);
405 regfree(&m
->compiled_pattern
);
409 MimeTableTail
= &MimeTable
;
415 const char *type
= mimeGetContentType(icon
);
418 fatal("Unknown icon format while reading mime.conf\n");
420 StoreEntry::getPublic(this, url
, Http::METHOD_GET
);
424 MimeIcon::created (StoreEntry
*newEntry
)
426 /* is already in the store, do nothing */
428 if (!newEntry
->isNull())
439 LOCAL_ARRAY(char, path
, MAXPATHLEN
);
443 snprintf(path
, MAXPATHLEN
, "%s/%s", Config
.icons
.directory
, icon
);
445 fd
= file_open(path
, O_RDONLY
| O_BINARY
);
448 debugs(25, DBG_CRITICAL
, "mimeLoadIconFile: " << path
<< ": " << xstrerror());
452 if (fstat(fd
, &sb
) < 0) {
453 debugs(25, DBG_CRITICAL
, "mimeLoadIconFile: FD " << fd
<< ": fstat: " << xstrerror());
458 flags
.cachable
= true;
459 StoreEntry
*e
= storeCreateEntry(url
,url
,flags
,Http::METHOD_GET
);
461 EBIT_SET(e
->flags
, ENTRY_SPECIAL
);
464 HttpRequest
*r
= HttpRequest::CreateFromUrl(url
);
467 fatal("mimeLoadIcon: cannot parse internal URL");
469 e
->mem_obj
->request
= HTTPMSGLOCK(r
);
471 HttpReply
*reply
= new HttpReply
;
473 reply
->setHeaders(HTTP_OK
, NULL
, mimeGetContentType(icon
), sb
.st_size
, sb
.st_mtime
, -1);
475 reply
->cache_control
= new HttpHdrCc();
477 reply
->cache_control
->maxAge(86400);
479 reply
->header
.putCc(reply
->cache_control
);
481 e
->replaceHttpReply(reply
);
483 /* read the file into the buffer and append it to store */
484 buf
= (char *)memAllocate(MEM_4K_BUF
);
486 while ((n
= FD_READ_METHOD(fd
, buf
, 4096)) > 0)
497 debugs(25, 3, "Loaded icon " << url
);
501 memFree(buf
, MEM_4K_BUF
);