]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/mime.cc
5 * DEBUG: section 25 MIME Parsing and Internal Icons
6 * AUTHOR: Harvest Derived
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
39 #include "HttpHdrCc.h"
40 #include "HttpReply.h"
41 #include "HttpRequest.h"
43 #include "MemObject.h"
46 #include "StoreClient.h"
52 #define GET_HDR_SZ 1024
54 class MimeIcon
: public StoreClient
60 void setName (char const *);
61 char const * getName () const;
64 void created (StoreEntry
*newEntry
);
75 void *operator new (size_t byteCount
);
76 void operator delete (void *address
);
79 regex_t compiled_pattern
;
82 char *content_encoding
;
85 unsigned int view_option
:1;
86 unsigned int download_option
:1;
92 static mimeEntry
*MimeTable
= NULL
;
93 static mimeEntry
**MimeTableTail
= &MimeTable
;
96 mimeEntry::operator new (size_t byteCount
)
98 return xcalloc(1, byteCount
);
102 mimeEntry::operator delete (void *address
)
108 mimeGetEntry(const char *fn
, int skip_encodings
)
112 char *name
= xstrdup(fn
);
117 for (m
= MimeTable
; m
; m
= m
->next
) {
118 if (regexec(&m
->compiled_pattern
, name
, 0, 0, 0) == 0)
126 else if (strcmp(m
->content_type
, dash_str
))
128 else if (!strcmp(m
->content_encoding
, dash_str
))
131 /* Assume we matched /\.\w$/ and cut off the last extension */
132 if ((t
= strrchr(name
, '.'))) {
135 /* What? A encoding without a extension? */
145 MimeIcon::MimeIcon () : icon (NULL
), url (NULL
)
148 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
177 mimeGetIcon(const char *fn
)
179 mimeEntry
*m
= mimeGetEntry(fn
, 1);
184 if (!strcmp(m
->theIcon
.getName(), dash_str
))
187 return m
->theIcon
.getName();
191 mimeGetIconURL(const char *fn
)
193 char const *icon
= mimeGetIcon(fn
);
198 if (Config
.icons
.use_short_names
) {
201 mb
.Printf("/squid-internal-static/icons/%s", icon
);
204 return internalLocalUri("/squid-internal-static/icons/", icon
);
209 mimeGetContentType(const char *fn
)
211 mimeEntry
*m
= mimeGetEntry(fn
, 1);
216 if (!strcmp(m
->content_type
, dash_str
))
219 return m
->content_type
;
223 mimeGetContentEncoding(const char *fn
)
225 mimeEntry
*m
= mimeGetEntry(fn
, 0);
230 if (!strcmp(m
->content_encoding
, dash_str
))
233 return m
->content_encoding
;
237 mimeGetTransferMode(const char *fn
)
239 mimeEntry
*m
= mimeGetEntry(fn
, 0);
240 return m
? m
->transfer_mode
: 'I';
244 mimeGetDownloadOption(const char *fn
)
246 mimeEntry
*m
= mimeGetEntry(fn
, 1);
247 return m
? m
->download_option
: 0;
251 mimeGetViewOption(const char *fn
)
253 mimeEntry
*m
= mimeGetEntry(fn
, 0);
254 return m
? m
->view_option
: 0;
257 /* Initializes/reloads the mime table
258 * Note: Due to Solaris STDIO problems the caller should NOT
259 * call mimeFreeMemory on reconfigure. This way, if STDIO
260 * fails we at least have the old copy loaded.
263 mimeInit(char *filename
)
267 char chopbuf
[BUFSIZ
];
279 int re_flags
= REG_EXTENDED
| REG_NOSUB
| REG_ICASE
;
281 if (filename
== NULL
)
284 if ((fp
= fopen(filename
, "r")) == NULL
) {
285 debugs(25, DBG_IMPORTANT
, "mimeInit: " << filename
<< ": " << xstrerror());
290 setmode(fileno(fp
), O_TEXT
);
295 while (fgets(buf
, BUFSIZ
, fp
)) {
296 if ((t
= strchr(buf
, '#')))
299 if ((t
= strchr(buf
, '\r')))
302 if ((t
= strchr(buf
, '\n')))
308 xstrncpy(chopbuf
, buf
, BUFSIZ
);
310 if ((pattern
= strtok(chopbuf
, w_space
)) == NULL
) {
311 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
315 if ((type
= strtok(NULL
, w_space
)) == NULL
) {
316 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
320 if ((icon
= strtok(NULL
, w_space
)) == NULL
) {
321 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
325 if ((encoding
= strtok(NULL
, w_space
)) == NULL
) {
326 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
330 if ((mode
= strtok(NULL
, w_space
)) == NULL
) {
331 debugs(25, DBG_IMPORTANT
, "mimeInit: parse error: '" << buf
<< "'");
338 while ((option
= strtok(NULL
, w_space
)) != NULL
) {
339 if (!strcmp(option
, "+download"))
341 else if (!strcmp(option
, "+view"))
344 debugs(25, DBG_IMPORTANT
, "mimeInit: unknown option: '" << buf
<< "' (" << option
<< ")");
347 if (regcomp(&re
, pattern
, re_flags
) != 0) {
348 debugs(25, DBG_IMPORTANT
, "mimeInit: regcomp error: '" << buf
<< "'");
353 m
->pattern
= xstrdup(pattern
);
354 m
->content_type
= xstrdup(type
);
355 m
->theIcon
.setName(icon
);
356 m
->content_encoding
= xstrdup(encoding
);
357 m
->compiled_pattern
= re
;
359 if (!strcasecmp(mode
, "ascii"))
360 m
->transfer_mode
= 'A';
361 else if (!strcasecmp(mode
, "text"))
362 m
->transfer_mode
= 'A';
364 m
->transfer_mode
= 'I';
366 m
->view_option
= view_option
;
368 m
->download_option
= download_option
;
372 MimeTableTail
= &m
->next
;
374 debugs(25, 5, "mimeInit: added '" << buf
<< "'");
379 * Create Icon StoreEntry's
382 for (m
= MimeTable
; m
!= NULL
; m
= m
->next
)
385 debugs(25, DBG_IMPORTANT
, "Loaded Icons.");
393 while ((m
= MimeTable
)) {
395 safe_free(m
->pattern
);
396 safe_free(m
->content_type
);
398 safe_free(m
->content_encoding
);
399 regfree(&m
->compiled_pattern
);
403 MimeTableTail
= &MimeTable
;
409 const char *type
= mimeGetContentType(icon
);
412 fatal("Unknown icon format while reading mime.conf\n");
414 StoreEntry::getPublic(this, url
, METHOD_GET
);
418 MimeIcon::created (StoreEntry
*newEntry
)
420 /* is already in the store, do nothing */
422 if (!newEntry
->isNull())
433 LOCAL_ARRAY(char, path
, MAXPATHLEN
);
437 snprintf(path
, MAXPATHLEN
, "%s/%s", Config
.icons
.directory
, icon
);
439 fd
= file_open(path
, O_RDONLY
| O_BINARY
);
442 debugs(25, DBG_CRITICAL
, "mimeLoadIconFile: " << path
<< ": " << xstrerror());
446 if (fstat(fd
, &sb
) < 0) {
447 debugs(25, DBG_CRITICAL
, "mimeLoadIconFile: FD " << fd
<< ": fstat: " << xstrerror());
453 StoreEntry
*e
= storeCreateEntry(url
,
458 EBIT_SET(e
->flags
, ENTRY_SPECIAL
);
461 HttpRequest
*r
= HttpRequest::CreateFromUrl(url
);
464 fatal("mimeLoadIcon: cannot parse internal URL");
466 e
->mem_obj
->request
= HTTPMSGLOCK(r
);
468 HttpReply
*reply
= new HttpReply
;
470 reply
->setHeaders(HTTP_OK
, NULL
, mimeGetContentType(icon
), sb
.st_size
, sb
.st_mtime
, -1);
472 reply
->cache_control
= new HttpHdrCc();
474 reply
->cache_control
->maxAge(86400);
476 reply
->header
.putCc(reply
->cache_control
);
478 e
->replaceHttpReply(reply
);
480 /* read the file into the buffer and append it to store */
481 buf
= (char *)memAllocate(MEM_4K_BUF
);
483 while ((n
= FD_READ_METHOD(fd
, buf
, 4096)) > 0)
494 debugs(25, 3, "Loaded icon " << url
);
498 memFree(buf
, MEM_4K_BUF
);