From: wessels <> Date: Thu, 15 May 1997 07:06:49 +0000 (+0000) Subject: New MIME configuration, regular expression based X-Git-Tag: SQUID_3_0_PRE1~5018 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=812ed90c92653caeb9156937f2bdaeb2a4cfa2ec;p=thirdparty%2Fsquid.git New MIME configuration, regular expression based Added request_timeout config option Multiple HTTP sockets (Lincoln Dale). Moved 'fds_are_n_free' check to httpAccept(). s/USE_POLL/HAVE_POLL/; make poll() default if available. --- diff --git a/src/Makefile.in b/src/Makefile.in index 3dd1e9d397..e4486101da 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,7 +1,7 @@ # # Makefile for the Squid Object Cache server # -# $Id: Makefile.in,v 1.70 1997/05/14 21:08:15 wessels Exp $ +# $Id: Makefile.in,v 1.71 1997/05/15 01:06:49 wessels Exp $ # # Uncomment and customize the following to suit your needs: # @@ -12,7 +12,6 @@ ICMP_OPT = # -DUSE_ICMP=1 DELAY_HACK = # -DDELAY_HACK=1 USERAGENT_OPT = # -DUSE_USERAGENT_LOG=1 KILL_PARENT_OPT = # -DKILL_PARENT_OPT -USE_POLL_OPT = # -DUSE_POLL # do NOT define both USE_SPLAY_TREE and USE_BIN_TREE at the same time! USE_SPLAY_TREE = # -DUSE_SPLAY_TREE USE_BIN_TREE = # -DUSE_BIN_TREE @@ -33,6 +32,7 @@ srcdir = @srcdir@ VPATH = @srcdir@ DEFAULT_CONFIG_FILE = $(sysconfdir)/squid.conf +DEFAULT_MIME_TABLE = $(sysconfdir)/mime.conf DEFAULT_FTPGET = $(libexecdir)/ftpget DEFAULT_DNSSERVER = $(libexecdir)/dnsserver DEFAULT_CACHE_LOG = $(localstatedir)/logs/cache.log @@ -126,6 +126,7 @@ OBJS = \ DEFAULTS = \ -DDEFAULT_CONFIG_FILE=\"$(DEFAULT_CONFIG_FILE)\" \ + -DDEFAULT_MIME_TABLE=\"$(DEFAULT_MIME_TABLE)\" \ -DDEFAULT_FTPGET=\"$(DEFAULT_FTPGET)\" \ -DDEFAULT_DNSSERVER=\"$(DEFAULT_DNSSERVER)\" \ -DDEFAULT_CACHE_LOG=\"$(DEFAULT_CACHE_LOG)\" \ @@ -156,7 +157,7 @@ cachemgr.cgi: cachemgr.o $(CC) -o $@ $(LDFLAGS) cachemgr.o $(CLIENT_LIBS) ftpget: ftpget.o - $(CC) -o $@ $(LDFLAGS) ftpget.o debug.o $(FTPGET_LIBS) + $(CC) -o $@ $(LDFLAGS) ftpget.o debug.o mime.o $(FTPGET_LIBS) $(REGEXLIB) pinger: pinger.o $(CC) -o $@ $(LDFLAGS) pinger.o debug.o $(PINGER_LIBS) @@ -167,6 +168,7 @@ unlinkd: unlinkd.c squid.conf: squid.conf.pre Makefile sed "\ s%@DEFAULT_CONFIG_FILE@%$(DEFAULT_CONFIG_FILE)%g;\ + s%@DEFAULT_MIME_TABLE@%$(DEFAULT_MIME_TABLE)%g;\ s%@DEFAULT_FTPGET@%$(DEFAULT_FTPGET)%g;\ s%@DEFAULT_DNSSERVER@%$(DEFAULT_DNSSERVER)%g;\ s%@DEFAULT_UNLINKD@%$(DEFAULT_UNLINKD)%g;\ @@ -253,6 +255,13 @@ install: all install-mkdirs echo "$(INSTALL_FILE) squid.conf $(sysconfdir)"; \ $(INSTALL_FILE) squid.conf $(sysconfdir); \ fi + $(INSTALL_FILE) mime.conf $(sysconfdir)/mime.conf.default + @if test -f $(sysconfdir)/mime.conf ; then \ + echo "$@ will not overwrite existing $(sysconfdir)/mime.conf" ; \ + else \ + echo "$(INSTALL_FILE) mime.conf $(sysconfdir)"; \ + $(INSTALL_FILE) mime.conf $(sysconfdir); \ + fi install-pinger: @f=pinger; \ diff --git a/src/cache_cf.cc b/src/cache_cf.cc index 3c7fd308c4..0a7f4c0026 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,5 +1,5 @@ /* - * $Id: cache_cf.cc,v 1.184 1997/05/14 21:07:51 wessels Exp $ + * $Id: cache_cf.cc,v 1.185 1997/05/15 01:06:50 wessels Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -127,6 +127,7 @@ struct SquidConfig Config; #define DefaultReadTimeout (15 * 60) /* 15 min */ #define DefaultConnectTimeout 120 /* 2 min */ #define DefaultDeferTimeout 3600 /* 1 hour */ +#define DefaultRequestTimeout 30 /* 30 seconds */ #define DefaultClientLifetime 86400 /* 1 day */ #define DefaultShutdownLifetime 30 /* 30 seconds */ #define DefaultCleanRate -1 /* disabled */ @@ -179,6 +180,7 @@ struct SquidConfig Config; #define DefaultStallDelay 1 /* 1 seconds */ #define DefaultSingleParentBypass 0 /* default off */ #define DefaultPidFilename DEFAULT_PID_FILE +#define DefaultMimeTable DEFAULT_MIME_TABLE #define DefaultVisibleHostname (char *)NULL /* default NONE */ #define DefaultFtpUser "squid@" /* Default without domain */ #define DefaultAnnounceHost "sd.cache.nlanr.net" @@ -662,10 +664,15 @@ parseHttpPortLine(void) { char *token; int i; + if (Config.Port.n_http == MAXHTTPPORTS) { + sprintf(fatal_str, "Limit of %d HTTP Ports exceeded, redefine MAXHTTPPORTS.\n", + MAXHTTPPORTS); + fatal(fatal_str); + } GetInteger(i); if (i < 0) i = 0; - Config.Port.http = (u_short) i; + Config.Port.http[Config.Port.n_http++] = (u_short) i; } static void @@ -1031,6 +1038,8 @@ parseConfigFile(const char *file_name) parseTimeLine(&Config.Timeout.connect, T_SECOND_STR); else if (!strcmp(token, "defer_timeout")) parseTimeLine(&Config.Timeout.defer, T_MINUTE_STR); + else if (!strcmp(token, "request_timeout")) + parseTimeLine(&Config.Timeout.request, T_SECOND_STR); else if (!strcmp(token, "client_lifetime")) parseTimeLine(&Config.Timeout.lifetime, T_MINUTE_STR); else if (!strcmp(token, "shutdown_lifetime")) @@ -1147,7 +1156,8 @@ parseConfigFile(const char *file_name) else if (!strcmp(token, "pid_filename")) parsePathname(&Config.pidFilename, 0); - + else if (!strcmp(token, "mime_table")) + parsePathname(&Config.mimeTablePathname, 1); else if (!strcmp(token, "visible_hostname")) parseVisibleHostnameLine(); @@ -1291,6 +1301,7 @@ configFreeMemory(void) safe_free(Config.appendDomain); safe_free(Config.debugOptions); safe_free(Config.pidFilename); + safe_free(Config.mimeTablePathname); safe_free(Config.visibleHostname); safe_free(Config.ftpUser); #if USE_PROXY_AUTH @@ -1336,6 +1347,7 @@ configSetFactoryDefaults(void) Config.Timeout.read = DefaultReadTimeout; Config.Timeout.connect = DefaultConnectTimeout; Config.Timeout.defer = DefaultDeferTimeout; + Config.Timeout.request = DefaultRequestTimeout; Config.Timeout.lifetime = DefaultClientLifetime; Config.shutdownLifetime = DefaultShutdownLifetime; Config.maxRequestSize = DefaultMaxRequestSize; @@ -1360,7 +1372,8 @@ configSetFactoryDefaults(void) Config.effectiveGroup = safe_xstrdup(DefaultEffectiveGroup); Config.appendDomain = safe_xstrdup(DefaultAppendDomain); Config.errHtmlText = safe_xstrdup(DefaultErrHtmlText); - Config.Port.http = DefaultHttpPortNum; + Config.Port.n_http = 0; + Config.Port.http[0] = DefaultHttpPortNum; Config.Port.icp = DefaultIcpPortNum; Config.Log.log_fqdn = DefaultLogLogFqdn; Config.Log.log = safe_xstrdup(DefaultCacheLogFile); @@ -1382,6 +1395,7 @@ configSetFactoryDefaults(void) Config.Accel.port = DefaultAccelPort; Config.Accel.withProxy = DefaultAccelWithProxy; Config.pidFilename = safe_xstrdup(DefaultPidFilename); + Config.mimeTablePathname = safe_xstrdup(DefaultMimeTable); Config.visibleHostname = safe_xstrdup(DefaultVisibleHostname); #if USE_PROXY_AUTH Config.proxyAuth.File = safe_xstrdup(DefaultProxyAuthFile); @@ -1432,7 +1446,7 @@ configDoConfigure(void) vhost_mode = 1; sprintf(ThisCache, "%s:%d (Squid/%s)", getMyHostname(), - (int) Config.Port.http, + (int) Config.Port.http[0], SQUID_VERSION); if (!Config.udpMaxHitObjsz || Config.udpMaxHitObjsz > SQUID_UDP_SO_SNDBUF) Config.udpMaxHitObjsz = SQUID_UDP_SO_SNDBUF; diff --git a/src/client_db.cc b/src/client_db.cc index 810b5066af..83317703fc 100644 --- a/src/client_db.cc +++ b/src/client_db.cc @@ -1,6 +1,6 @@ /* - * $Id: client_db.cc,v 1.10 1997/04/28 04:22:59 wessels Exp $ + * $Id: client_db.cc,v 1.11 1997/05/15 01:06:51 wessels Exp $ * * DEBUG: section 0 Client Database * AUTHOR: Duane Wessels @@ -71,7 +71,7 @@ clientdbInit(void) } void -clientdbUpdate(struct in_addr addr, log_type log_type, u_short port) +clientdbUpdate(struct in_addr addr, log_type log_type, protocol_t p) { char *key; ClientInfo *c; @@ -83,10 +83,10 @@ clientdbUpdate(struct in_addr addr, log_type log_type, u_short port) c = clientdbAdd(addr); if (c == NULL) debug_trap("clientdbUpdate: Failed to add entry"); - if (port == Config.Port.http) { + if (p == PROTO_HTTP) { c->Http.n_requests++; c->Http.result_hist[log_type]++; - } else if (port == Config.Port.icp) { + } else if (p == PROTO_ICP) { c->Icp.n_requests++; c->Icp.result_hist[log_type]++; } diff --git a/src/comm.cc b/src/comm.cc index a8a5b37bdc..a4ad798c0c 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.150 1997/05/05 03:43:38 wessels Exp $ + * $Id: comm.cc,v 1.151 1997/05/15 01:06:53 wessels Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -134,13 +134,17 @@ FD_ENTRY *fd_table = NULL; /* also used in disk.c */ /* STATIC */ static int commBind _PARAMS((int s, struct in_addr, u_short port)); -#ifndef USE_POLL +#ifndef HAVE_POLL static int examine_select _PARAMS((fd_set *, fd_set *)); #endif static void checkTimeouts _PARAMS((void)); static void commSetReuseAddr _PARAMS((int)); static void commSetNoLinger _PARAMS((int)); +#if HAVE_POLL +static void comm_poll_incoming _PARAMS((void)); +#else static void comm_select_incoming _PARAMS((void)); +#endif static void CommWriteStateCallbackAndFree _PARAMS((int fd, int code)); #ifdef TCP_NODELAY static void commSetTcpNoDelay _PARAMS((int)); @@ -149,6 +153,7 @@ static void commSetTcpRcvbuf _PARAMS((int, int)); static void commConnectFree _PARAMS((int fd, void *data)); static void commConnectHandle _PARAMS((int fd, void *data)); static void commHandleWrite _PARAMS((int fd, void *data)); +static int fdIsHttpOrIcp _PARAMS((int fd)); static struct timeval zero_tv; @@ -595,29 +600,34 @@ comm_set_stall(int fd, int delta) } -#ifdef USE_POLL +#ifdef HAVE_POLL /* poll() version by: * Stewart Forster , and * Anthony Baxter */ static void -comm_select_incoming(void) +comm_poll_incoming(void) { int fd; int fds[4]; - struct pollfd pfds[4]; + struct pollfd pfds[3+MAXHTTPPORTS]; unsigned long N = 0; unsigned long i, nfds; - int dopoll = 0; + int j; PF *hdl = NULL; if (theInIcpConnection >= 0) fds[N++] = theInIcpConnection; if (theInIcpConnection != theOutIcpConnection) if (theOutIcpConnection >= 0) fds[N++] = theOutIcpConnection; - if (theHttpConnection >= 0 && fdstat_are_n_free_fd(RESERVED_FD)) - fds[N++] = theHttpConnection; + for (j=0; j squid_curtime) + continue; + fds[N++] = HttpSockets[j]; + } for (i = nfds = 0; i < N; i++) { int events; fd = fds[i]; @@ -667,14 +677,19 @@ comm_select_incoming(void) fd_set write_mask; int maxfd = 0; int fd = 0; - int fds[4]; + int fds[3+MAXHTTPPORTS]; int N = 0; int i = 0; PF *hdl = NULL; FD_ZERO(&read_mask); FD_ZERO(&write_mask); - if (theHttpConnection >= 0 && fdstat_are_n_free_fd(RESERVED_FD)) - fds[N++] = theHttpConnection; + for (i=0; i squid_curtime) + continue; + fds[N++] = HttpSockets[i]; + } if (theInIcpConnection >= 0) fds[N++] = theInIcpConnection; if (theInIcpConnection != theOutIcpConnection) @@ -717,10 +732,25 @@ comm_select_incoming(void) } #endif -#ifdef USE_POLL +static int +fdIsHttpOrIcp(int fd) +{ + int j; + if (fd == theInIcpConnection) + return 1; + if (fd == theOutIcpConnection) + return 1; + for (j = 0; j < NHttpSockets; j++) { + if (fd == HttpSockets[j]) + return 1; + } + return 0; +} + +#ifdef HAVE_POLL /* poll all sockets; call handlers for those that are ready. */ int -comm_select(time_t sec) +comm_poll(time_t sec) { struct pollfd pfds[SQUID_MAXFD]; PF *hdl = NULL; @@ -732,6 +762,7 @@ comm_select(time_t sec) static time_t last_timeout = 0; static time_t pending_time; int poll_time; + static int incoming_counter = 0; time_t timeout; /* assume all process are very fast (less than 1 second). Call * time() only once */ @@ -757,7 +788,6 @@ comm_select(time_t sec) } nfds = 0; maxfd = Biggest_FD + 1; - httpindex = -1; for (i = 0; i < maxfd; i++) { int events; events = 0; @@ -767,8 +797,6 @@ comm_select(time_t sec) if (fd_table[i].write_handler) events |= POLLWRNORM; if (events) { - if (i == theHttpConnection) - httpindex = nfds; pfds[nfds].fd = i; pfds[nfds].events = events; pfds[nfds].revents = 0; @@ -777,12 +805,8 @@ comm_select(time_t sec) pfds[i].fd = -1; } /* If we're out of free fd's, don't poll the http incoming fd */ - if (!fdstat_are_n_free_fd(RESERVED_FD) && httpindex >= 0) { - pfds[httpindex].fd = -1; - pfds[httpindex].events = 0; - } if (shutdown_pending || reread_pending) - debug(5, 2, "comm_select: Still waiting on %d FDs\n", nfds); + debug(5, 2, "comm_poll: Still waiting on %d FDs\n", nfds); if (pending_time == 0) pending_time = squid_curtime; if ((squid_curtime - pending_time) > (Config.shutdownLifetime + 5)) { @@ -814,21 +838,14 @@ comm_select(time_t sec) break; if (errno == EINTR) continue; - debug(5, 0, "comm_select: poll failure: %s\n", - xstrerror()); - if (errno == EINVAL) { - /* nfds greater than OPEN_MAX?? How possible? Time */ - /* to bail - write out nfds to cache.log and start */ - /* emergency shutdown by sending SIGTERM to self */ - debug(20, 1, "Poll returned EINVAL. Polled %d FD's\n", nfds); - kill(getpid(), SIGTERM); - } + debug(5, 0, "comm_poll: poll failure: %s\n", xstrerror()); + if (errno == EINVAL) + fatal_dump("Poll returned EINVAL"); return COMM_ERROR; /* NOTREACHED */ } getCurrentTime(); - debug(5, num ? 5 : 8, "comm_select: %d sockets ready at %d\n", - num, (int) squid_curtime); + debug(5, num ? 5 : 8, "comm_poll: %d sockets ready\n", num); /* Check timeout handlers ONCE each second. */ if (squid_curtime > last_timeout) { last_timeout = squid_curtime; @@ -843,22 +860,18 @@ comm_select(time_t sec) int revents; if (((revents = pfds[i].revents) == 0) || ((fd = pfds[i].fd) == -1)) continue; - /* - * Admit more connections quickly until we hit the hard limit. - * Don't forget to keep the UDP acks coming and going. - */ - if ((i % 2) == 0) - comm_select_incoming(); - if ((fd == theInIcpConnection) || (fd == theHttpConnection) || (fd == theOutIcpConnection) || (fd == 0)) + if ((incoming_counter++ % 2) == 0) + comm_poll_incoming(); + if (fdIsHttpOrIcp(fd)) continue; if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { - debug(5, 6, "comm_select: FD %d ready for reading\n", fd); + debug(5, 6, "comm_poll: FD %d ready for reading\n", fd); hdl = fd_table[fd].read_handler; fd_table[fd].read_handler = 0; hdl(fd, fd_table[fd].read_data); } if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { - debug(5, 5, "comm_select: FD %d ready for writing\n", fd); + debug(5, 5, "comm_poll: FD %d ready for writing\n", fd); hdl = fd_table[fd].write_handler; fd_table[fd].write_handler = 0; hdl(fd, fd_table[fd].write_data); @@ -869,7 +882,7 @@ comm_select(time_t sec) FD_ENTRY *fde = &fd_table[fd]; debug(5, 0, "WARNING: FD %d has handlers, but it's invalid.\n", fd); debug(5, 0, "FD %d is a %s\n", fd, fdstatTypeStr[fd_table[fd].type]); - debug(5, 0, "--> %s\n", fd_note(fd, NULL)); + debug(5, 0, "--> %s\n", fd_table[fd].desc); debug(5, 0, "tmout:%p read:%p write:%p\n", fde->timeout_handler, fde->read_handler, @@ -883,7 +896,7 @@ comm_select(time_t sec) safe_free(ch); } } else if (fde->timeout_handler) { - debug(5, 0, "examine_select: Calling Timeout Handler\n"); + debug(5, 0, "comm_poll: Calling Timeout Handler\n"); fde->timeout_handler(fd, fde->timeout_data); } fde->close_handler = NULL; @@ -894,7 +907,7 @@ comm_select(time_t sec) } return COMM_OK; } while (timeout > getCurrentTime()); - debug(5, 8, "comm_select: time out: %d.\n", squid_curtime); + debug(5, 8, "comm_poll: time out: %d.\n", squid_curtime); return COMM_TIMEOUT; } @@ -957,9 +970,6 @@ comm_select(time_t sec) FD_SET(i, &writefds); } } - if (!fdstat_are_n_free_fd(RESERVED_FD) && theHttpConnection >= 0) { - FD_CLR(theHttpConnection, &readfds); - } if (shutdown_pending || reread_pending) debug(5, 2, "comm_select: Still waiting on %d FDs\n", nfds); if (nfds == 0) @@ -1009,11 +1019,8 @@ comm_select(time_t sec) * Don't forget to keep the UDP acks coming and going. */ comm_select_incoming(); - if (fd == theInIcpConnection) - continue; - if (fd == theOutIcpConnection) - continue; - if (fd == theHttpConnection) + + if (fdIsHttpOrIcp(fd)) continue; if (FD_ISSET(fd, &readfds)) { debug(5, 6, "comm_select: FD %d ready for reading\n", fd); @@ -1226,7 +1233,7 @@ comm_init(void) } -#ifndef USE_POLL +#ifndef HAVE_POLL /* * examine_select - debug routine. * diff --git a/src/ftp.cc b/src/ftp.cc index d84957ea42..e326a1cec5 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.104 1997/05/05 03:43:42 wessels Exp $ + * $Id: ftp.cc,v 1.105 1997/05/15 01:06:54 wessels Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -141,7 +141,6 @@ static PF ftpServerClosed; static PF ftpStateFree; static PF ftpTimeout; static char *ftpGetBasicAuth _PARAMS((const char *)); -static const char *ftpTransferMode _PARAMS((const char *)); static void ftpProcessReplyHeader _PARAMS((FtpStateData *, const char *, int)); static void ftpStartComplete _PARAMS((void *, int)); static void ftpLoginParser _PARAMS((const char *, FtpStateData *)); @@ -412,26 +411,6 @@ ftpSendComplete(int fd, char *buf, int size, int errflag, void *data) ftpState, 0); } -static const char * -ftpTransferMode(const char *urlpath) -{ - const char *const ftpASCII = "A"; - const char *const ftpBinary = "I"; - char *ext = NULL; - const ext_table_entry *mime = NULL; - int len; - len = strlen(urlpath); - if (*(urlpath + len - 1) == '/') - return ftpASCII; - if ((ext = strrchr(urlpath, '.')) == NULL) - return ftpBinary; - if ((mime = mime_ext_to_type(++ext)) == NULL) - return ftpBinary; - if (!strcmp(mime->mime_encoding, "7bit")) - return ftpASCII; - return ftpBinary; -} - static void ftpSendRequest(int fd, void *data) { @@ -451,7 +430,7 @@ ftpSendRequest(int fd, void *data) buf = get_free_8k_page(); path = ftpState->request->urlpath; - mode = ftpTransferMode(path); + mode = "-"; /* let ftpget figure it out */ /* Start building the buffer ... */ strcat(buf, Config.Program.ftpget); diff --git a/src/gopher.cc b/src/gopher.cc index 9dc0365f0f..a41644360d 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -1,5 +1,5 @@ /* - * $Id: gopher.cc,v 1.78 1997/05/05 03:43:43 wessels Exp $ + * $Id: gopher.cc,v 1.79 1997/05/15 01:06:55 wessels Exp $ * * DEBUG: section 10 Gopher * AUTHOR: Harvest Derived @@ -198,50 +198,14 @@ gopherStateFree(int fd, void *data) /* figure out content type from file extension */ static void -gopher_mime_content(char *buf, const char *name, const char *def) +gopher_mime_content(char *buf, const char *name, const char *def_ctype) { - LOCAL_ARRAY(char, temp, MAX_URL); - char *ext1 = NULL; - char *ext2 = NULL; - const char *str = NULL; - const ext_table_entry *e = NULL; - - ext2 = NULL; - strcpy(temp, name); - for (ext1 = temp; *ext1; ext1++) - if (isupper(*ext1)) - *ext1 = tolower(*ext1); - if ((ext1 = strrchr(temp, '.')) == NULL) { - /* use default */ - sprintf(buf + strlen(buf), "Content-Type: %s\r\n", def); - return; - } - /* try extension table */ - *ext1++ = 0; - if (strcmp("gz", ext1) == 0 || strcmp("z", ext1) == 0) { - ext2 = ext1; - if ((ext1 = strrchr(temp, '.')) == NULL) { - ext1 = ext2; - ext2 = NULL; - } else - ext1++; - } - if ((e = mime_ext_to_type(ext1)) == NULL) { - /* mime_ext_to_type() can return a NULL */ - if (ext2 && (e = mime_ext_to_type(ext2))) { - str = e->mime_type; - ext2 = NULL; - } else { - str = def; - } - } else { - str = e->mime_type; - } - sprintf(buf + strlen(buf), "Content-Type: %s\r\n", str); - if (ext2 && (e = mime_ext_to_type(ext2))) { - sprintf(buf + strlen(buf), "Content-Encoding: %s\r\n", - e->mime_encoding); - } + char *ctype = mimeGetContentType(name); + char *cenc = mimeGetContentEncoding(name); + if (cenc) + sprintf(buf + strlen(buf), "Content-Encoding: %s\r\n", cenc); + sprintf(buf + strlen(buf), "Content-Type: %s\r\n", + ctype ? ctype : def_ctype); } @@ -287,14 +251,11 @@ gopherMimeCreate(GopherStateData * gopherState) /* Rightnow We have no idea what it is. */ gopher_mime_content(tempMIME, gopherState->request, def_gopher_bin); break; - case GOPHER_FILE: default: gopher_mime_content(tempMIME, gopherState->request, def_gopher_text); break; - } - strcat(tempMIME, "\r\n"); storeAppend(gopherState->entry, tempMIME, strlen(tempMIME)); } diff --git a/src/main.cc b/src/main.cc index 3476b9c1d6..36b0c02bf6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,5 @@ /* - * $Id: main.cc,v 1.143 1997/04/30 03:12:10 wessels Exp $ + * $Id: main.cc,v 1.144 1997/05/15 01:06:58 wessels Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -106,7 +106,8 @@ #include "squid.h" time_t squid_starttime = 0; -int theHttpConnection = -1; +int HttpSockets[MAXHTTPPORTS]; +int NHttpSockets = 0; int theInIcpConnection = -1; int theOutIcpConnection = -1; int vizSock = -1; @@ -334,26 +335,26 @@ serverConnectionsOpen(void) u_short port; int len; int x; - enter_suid(); - theHttpConnection = comm_open(SOCK_STREAM, - 0, - Config.Addrs.tcp_incoming, - Config.Port.http, - COMM_NONBLOCKING, - "HTTP Port"); - leave_suid(); - if (theHttpConnection < 0) { - fatal("Cannot open HTTP Port"); + int fd; + for (x = 0; x< Config.Port.n_http; x++) { + enter_suid(); + fd = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_incoming, + Config.Port.http[x], + COMM_NONBLOCKING, + "HTTP Socket"); + leave_suid(); + if (fd < 0) + continue; + comm_listen(fd); + commSetSelect(fd, COMM_SELECT_READ, httpAccept, NULL, 0); + debug(1, 1, "Accepting HTTP connections on port %d, FD %d.\n", + (int) Config.Port.http[x], fd); + HttpSockets[NHttpSockets++] = fd; } - fd_note(theHttpConnection, "HTTP socket"); - comm_listen(theHttpConnection); - commSetSelect(theHttpConnection, - COMM_SELECT_READ, - asciiHandleConn, - NULL, 0); - debug(1, 1, "Accepting HTTP connections on FD %d.\n", - theHttpConnection); - + if (NHttpSockets < 1) + fatal("Cannot open HTTP Port"); if (!httpd_accel_mode || Config.Accel.withProxy) { if ((port = Config.Port.icp) > (u_short) 0) { enter_suid(); @@ -465,15 +466,18 @@ serverConnectionsClose(void) { /* NOTE, this function will be called repeatedly while shutdown * is pending */ - if (theHttpConnection >= 0) { - debug(1, 1, "FD %d Closing HTTP connection\n", - theHttpConnection); - comm_close(theHttpConnection); - commSetSelect(theHttpConnection, - COMM_SELECT_READ, - NULL, - NULL, 0); - theHttpConnection = -1; + int i; + for (i=0; i= 0) { + debug(1, 1, "FD %d Closing HTTP connection\n", HttpSockets[i]); + comm_close(HttpSockets[i]); + commSetSelect(HttpSockets[i], + COMM_SELECT_READ, + NULL, + NULL, 0); + HttpSockets[i] = -1; + } + NHttpSockets = 0; } if (theInIcpConnection >= 0) { /* NOTE, don't close outgoing ICP connection, we need to write to @@ -540,7 +544,7 @@ mainInitialize(void) fatal("Don't run Squid as root, set 'cache_effective_user'!"); } if (httpPortNumOverride != 1) - Config.Port.http = (u_short) httpPortNumOverride; + Config.Port.http[0] = (u_short) httpPortNumOverride; if (icpPortNumOverride != 1) Config.Port.icp = (u_short) icpPortNumOverride; @@ -585,6 +589,7 @@ mainInitialize(void) } /* after this point we want to see the mallinfo() output */ do_mallinfo = 1; + mimeInit(Config.mimeTablePathname); } serverConnectionsOpen(); if (theOutIcpConnection >= 0 && (!httpd_accel_mode || Config.Accel.withProxy)) @@ -702,7 +707,11 @@ main(int argc, char **argv) eventRun(); if ((loop_delay = eventNextTime()) < 0) loop_delay = 0; +#if HAVE_POLL + switch (comm_poll(loop_delay)) { +#else switch (comm_select(loop_delay)) { +#endif case COMM_OK: errcount = 0; /* reset if successful */ break; diff --git a/src/mime.cc b/src/mime.cc index 49f9d8b40b..f845a35fd0 100644 --- a/src/mime.cc +++ b/src/mime.cc @@ -1,5 +1,5 @@ /* - * $Id: mime.cc,v 1.27 1996/12/18 03:50:24 wessels Exp $ + * $Id: mime.cc,v 1.28 1997/05/15 01:06:59 wessels Exp $ * * DEBUG: section 25 MIME Parsing * AUTHOR: Harvest Derived @@ -104,10 +104,26 @@ */ #include "squid.h" -#include "mime_table.h" #define GET_HDR_SZ 1024 +typedef struct _mime_entry { + char *pattern; + regex_t compiled_pattern; + char *icon; + char *content_type; + char *content_encoding; + char transfer_mode; + struct _mime_entry *next; +} mimeEntry; + +static mimeEntry *MimeTable = NULL; +static mimeEntry **MimeTableTail = NULL; + +static const char *const w_space = " \t\n\r"; +static const char *const dash_str = "-"; + + char * mime_get_header(const char *mime, const char *name) { @@ -172,49 +188,6 @@ mime_headers_end(const char *mime) return (char *) end; } -#ifdef OLD_CODE -int -mime_headers_size(const char *mime) -{ - const char *end; - end = mime_headers_end(mime); - if (end) - return end - mime; - else - return 0; -} -#endif - -const ext_table_entry * -mime_ext_to_type(const char *extension) -{ - int i; - int low; - int high; - int comp; - LOCAL_ARRAY(char, ext, 16); - char *cp = NULL; - - if (!extension || strlen(extension) >= (sizeof(ext) - 1)) - return NULL; - strcpy(ext, extension); - for (cp = ext; *cp; cp++) - if (isupper(*cp)) - *cp = tolower(*cp); - low = 0; - high = EXT_TABLE_LEN - 1; - while (low <= high) { - i = (low + high) / 2; - if ((comp = strcmp(ext, ext_mime_table[i].name)) == 0) - return &ext_mime_table[i]; - if (comp > 0) - low = i + 1; - else - high = i - 1; - } - return NULL; -} - /* * mk_mime_hdr - Generates a MIME header using the given parameters. * You can call mk_mime_hdr with a 'lmt = time(NULL) - ttl' to @@ -258,3 +231,145 @@ mk_mime_hdr(char *result, const char *type, int size, time_t ttl, time_t lmt) content_length); return 0; } + + +char * +mimeGetIcon(const char *fn) +{ + mimeEntry *m; + for (m = MimeTable; m; m = m->next) { + if (m->icon == NULL) + continue; + if (regexec(&m->compiled_pattern, fn, 0, 0, 0) == 0) + break; + } + if (m == NULL) + return NULL; + if (!strcmp(m->icon, dash_str)) + return NULL; + return m->icon; +} + +char * +mimeGetContentType(const char *fn) +{ + mimeEntry *m; + char *name = xstrdup(fn); + char *t; + if (mimeGetContentEncoding(name)) { + /* Assume we matched /\.\w$/ and cut off the last extension */ + if ((t = strrchr(name, '.'))) + *t = '\0'; + } + for (m = MimeTable; m; m = m->next) { + if (m->content_type == NULL) + continue; + if (regexec(&m->compiled_pattern, name, 0, 0, 0) == 0) + break; + } + xfree(name); + if (m == NULL) + return NULL; + if (!strcmp(m->content_type, dash_str)) + return NULL; + return m->content_type; +} + +char * +mimeGetContentEncoding(const char *fn) +{ + mimeEntry *m; + for (m = MimeTable; m; m = m->next) { + if (m->content_encoding == NULL) + continue; + if (regexec(&m->compiled_pattern, fn, 0, 0, 0) == 0) + break; + } + if (m == NULL) + return NULL; + if (!strcmp(m->content_encoding, dash_str)) + return NULL; + return m->content_encoding; +} + +char +mimeGetTransferMode(const char *fn) +{ + mimeEntry *m; + for (m = MimeTable; m; m = m->next) { + if (regexec(&m->compiled_pattern, fn, 0, 0, 0) == 0) + break; + } + return m ? m->transfer_mode : 'I'; +} + +void +mimeInit(char *filename) +{ + FILE *fp; + char buf[BUFSIZ]; + char chopbuf[BUFSIZ]; + char *t; + char *pattern; + char *icon; + char *type; + char *encoding; + char *mode; + regex_t re; + mimeEntry *m; + int re_flags = REG_EXTENDED | REG_NOSUB | REG_ICASE; + if (filename == NULL) + return; + if ((fp = fopen(filename, "r")) == NULL) { + debug(50, 1, "mimeInit: %s: %s\n", filename, xstrerror()); + return; + } + if (MimeTableTail == NULL) + MimeTableTail = &MimeTable; + while (fgets(buf, BUFSIZ, fp)) { + if ((t = strchr(buf, '#'))) + *t = '\0'; + if (buf[0] == '\0') + continue; + xstrncpy(chopbuf, buf, BUFSIZ); + if ((pattern = strtok(chopbuf, w_space)) == NULL) { + debug(25, 1, "mimeInit: parse error: '%s'\n", buf); + continue; + } + if ((type = strtok(NULL, w_space)) == NULL) { + debug(25, 1, "mimeInit: parse error: '%s'\n", buf); + continue; + } + if ((icon = strtok(NULL, w_space)) == NULL) { + debug(25, 1, "mimeInit: parse error: '%s'\n", buf); + continue; + } + if ((encoding = strtok(NULL, w_space)) == NULL) { + debug(25, 1, "mimeInit: parse error: '%s'\n", buf); + continue; + } + if ((mode = strtok(NULL, w_space)) == NULL) { + debug(25, 1, "mimeInit: parse error: '%s'\n", buf); + continue; + } + if (regcomp(&re, pattern, re_flags) != 0) { + debug(25, 1, "mimeInit: regcomp error: '%s'\n", buf); + continue; + } + m = xcalloc(1, sizeof(mimeEntry)); + m->pattern = xstrdup(pattern); + m->content_type = xstrdup(type); + m->icon = xstrdup(icon); + m->content_encoding = xstrdup(encoding); + m->compiled_pattern = re; + if (!strcasecmp(mode, "ascii")) + m->transfer_mode = 'A'; + else if (!strcasecmp(mode, "text")) + m->transfer_mode = 'A'; + else + m->transfer_mode = 'I'; + debug(25, 5, "mimeInit: added '%s'\n", buf); + *MimeTableTail = m; + MimeTableTail = &m->next; + } +} diff --git a/src/neighbors.cc b/src/neighbors.cc index b076cff19d..91e6ce39de 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,5 +1,5 @@ /* - * $Id: neighbors.cc,v 1.139 1997/05/05 03:43:47 wessels Exp $ + * $Id: neighbors.cc,v 1.140 1997/05/15 01:07:00 wessels Exp $ * * DEBUG: section 15 Neighbor Routines * AUTHOR: Harvest Derived @@ -745,11 +745,16 @@ neighborAdd(const char *host, int mcast_ttl) { peer *p = NULL; + int j; const char *me = getMyHostname(); - if (!strcmp(host, me) && http_port == Config.Port.http) { - debug(15, 0, "neighborAdd: skipping cache_host %s %s/%d/%d\n", - type, host, http_port, icp_port); - return; + if (!strcmp(host, me)) { + for (j=0; jhttp_port = http_port; diff --git a/src/send-announce.cc b/src/send-announce.cc index 209b20324a..0b36a2fbf9 100644 --- a/src/send-announce.cc +++ b/src/send-announce.cc @@ -1,6 +1,6 @@ /* - * $Id: send-announce.cc,v 1.34 1997/05/02 21:34:12 wessels Exp $ + * $Id: send-announce.cc,v 1.35 1997/05/15 01:07:01 wessels Exp $ * * DEBUG: section 27 Cache Announcer * AUTHOR: Duane Wessels @@ -63,7 +63,7 @@ send_announce(int fd, const ipcache_addrs * ia, void *data) strcat(sndbuf, tbuf); sprintf(tbuf, "Running on %s %d %d\n", getMyHostname(), - Config.Port.http, + Config.Port.http[0], Config.Port.icp); strcat(sndbuf, tbuf); if (Config.adminEmail) { diff --git a/src/squid.h b/src/squid.h index f8959272a6..b1512b1a8c 100644 --- a/src/squid.h +++ b/src/squid.h @@ -1,6 +1,6 @@ /* - * $Id: squid.h,v 1.110 1997/05/14 21:07:22 wessels Exp $ + * $Id: squid.h,v 1.111 1997/05/15 01:07:02 wessels Exp $ * * AUTHOR: Duane Wessels * @@ -162,12 +162,8 @@ #include #endif -#if defined(USE_POLL) && HAVE_POLL #if HAVE_POLL_H #include -#endif /* HAVE_POLL_H */ -#else -#undef USE_POLL #endif #ifdef __STDC__ @@ -319,7 +315,8 @@ extern void shut_down _PARAMS((int)); extern time_t squid_starttime; /* main.c */ extern int do_reuse; /* main.c */ -extern int theHttpConnection; /* main.c */ +extern int HttpSockets[]; /* main.c */ +extern int NHttpSockets; /* main.c */ extern int theInIcpConnection; /* main.c */ extern int theOutIcpConnection; /* main.c */ extern int vizSock; diff --git a/src/store.cc b/src/store.cc index da9632e8b7..95242f4469 100644 --- a/src/store.cc +++ b/src/store.cc @@ -1,6 +1,6 @@ /* - * $Id: store.cc,v 1.232 1997/05/14 21:07:21 wessels Exp $ + * $Id: store.cc,v 1.233 1997/05/15 01:07:03 wessels Exp $ * * DEBUG: section 20 Storeage Manager * AUTHOR: Harvest Derived @@ -1335,6 +1335,7 @@ storeSwapOutStartComplete(void *data, int fd) debug(20, 5, "storeSwapOutStart: Begin SwapOut '%s' to FD %d FILE %s.\n", e->url, fd, swapfilename); e->swap_file_number = swapno; + debug(20,5, "swap_file_number=%08X\n", e->swap_file_number); e->swap_status = SWAPPING_OUT; mem->swap_offset = 0; mem->e_swap_buf = get_free_8k_page(); diff --git a/src/tools.cc b/src/tools.cc index bfb4c2a1b3..842b68a8e6 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.104 1997/05/05 03:43:50 wessels Exp $ + * $Id: tools.cc,v 1.105 1997/05/15 01:07:04 wessels Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -137,9 +137,12 @@ int gethostname _PARAMS((char *, int)); static void releaseServerSockets(void) { + int i; /* Release the main ports as early as possible */ - if (theHttpConnection >= 0) - (void) close(theHttpConnection); + for (i = 0; i < NHttpSockets; i++) { + if (HttpSockets[i] >= 0) + (void) close(HttpSockets[i]); + } if (theInIcpConnection >= 0) (void) close(theInIcpConnection); if (theOutIcpConnection >= 0 && theOutIcpConnection != theInIcpConnection)