You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by di...@locus.apache.org on 2000/03/17 02:09:10 UTC

cvs commit: apache-2.0/src/modules/standard mod_mime.c

dirkx       00/03/16 17:09:10

  Modified:    src/modules/standard mod_mime.c
  Log:
  
  
  Revision  Changes    Path
  1.11      +361 -12   apache-2.0/src/modules/standard/mod_mime.c
  
  Index: mod_mime.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_mime.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -u -r1.10 -r1.11
  --- mod_mime.c	2000/03/10 00:07:12	1.10
  +++ mod_mime.c	2000/03/17 01:09:10	1.11
  @@ -73,6 +73,20 @@
   #include <string.h>
   #endif
   
  +/* XXXX - fix me / EBCDIC
  + *        there was a cludge here which would use its
  + *	  own version ap_isascii(). Indicating that
  + *	  on some platforms that might be needed. 
  + *
  + *	  #define OS_ASC(c) (c)		    -- for mere mortals 
  + *     or
  + *        #define OS_ASC(c) (ebcdic2ascii[c]) -- for dino's
  + *
  + *        #define ap_isascii(c) ((OS_ASC(c) & 0x80) == 0)
  + */
  +
  +/* XXXXX - fix me - See note with NOT_PROXY */
  +
   typedef struct handlers_info {
       char *name;
   } handlers_info;
  @@ -82,13 +96,34 @@
       ap_table_t *encoding_types;      /* Added with AddEncoding... */
       ap_table_t *language_types;      /* Added with AddLanguage... */
       ap_table_t *handlers;            /* Added with AddHandler...  */
  +    ap_table_t *charset_types;       /* Added with AddCharset... */       
       ap_array_header_t *handlers_remove;     /* List of handlers to remove */
   
       char *type;                 /* Type forced with ForceType  */
       char *handler;              /* Handler forced with SetHandler */
       char *default_language;     /* Language if no AddLanguage ext found */
  +	                        /* Due to the FUD about JS and charsets 
  +                                 * default_charset is actually in src/main */
   } mime_dir_config;
   
  +typedef struct param_s {
  +    char *attr;
  +    char *val;
  +    struct param_s *next;
  +} param;
  +
  +typedef struct {
  +    char *type;
  +    char *subtype;
  +    param *param;
  +} content_type;
  +
  +static char tspecial[] = {
  +    '(', ')', '<', '>', '@', ',', ';', ':',
  +    '\\', '"', '/', '[', ']', '?', '=',
  +    '\0'
  +};
  +
   module MODULE_VAR_EXPORT mime_module;
   
   static void *create_mime_dir_config(ap_context_t *p, char *dummy)
  @@ -98,6 +133,7 @@
   
       new->forced_types = ap_make_table(p, 4);
       new->encoding_types = ap_make_table(p, 4);
  +    new->charset_types = ap_make_table(p, 4);
       new->language_types = ap_make_table(p, 4);
       new->handlers = ap_make_table(p, 4);
       new->handlers_remove = ap_make_array(p, 4, sizeof(handlers_info));
  @@ -124,9 +160,11 @@
       }
   
       new->forced_types = ap_overlay_tables(p, add->forced_types,
  -                                       base->forced_types);
  +					 base->forced_types);
       new->encoding_types = ap_overlay_tables(p, add->encoding_types,
                                            base->encoding_types);
  +    new->charset_types = ap_overlay_tables(p, add->charset_types,
  +					   base->charset_types);
       new->language_types = ap_overlay_tables(p, add->language_types,
                                            base->language_types);
       new->handlers = ap_overlay_tables(p, add->handlers,
  @@ -140,17 +178,18 @@
       return new;
   }
   
  -static const char *add_type(cmd_parms *cmd, mime_dir_config * m, char *ct,
  +static const char *add_type(cmd_parms *cmd, mime_dir_config *m, char *ct,
                               char *ext)
   {
       if (*ext == '.')
  -        ++ext;
  +	++ext;
  +	
       ap_str_tolower(ct);
       ap_table_setn(m->forced_types, ext, ct);
       return NULL;
   }
   
  -static const char *add_encoding(cmd_parms *cmd, mime_dir_config * m, char *enc,
  +static const char *add_encoding(cmd_parms *cmd, mime_dir_config *m, char *enc,
                                   char *ext)
   {
       if (*ext == '.')
  @@ -159,18 +198,30 @@
       ap_table_setn(m->encoding_types, ext, enc);
       return NULL;
   }
  +
  +static const char *add_charset(cmd_parms *cmd, mime_dir_config *m,
  +			       char *charset, char *ext)
  +{
  +    if (*ext == '.') {
  +	++ext;
  +    }
  +    ap_str_tolower(charset);
  +    ap_table_setn(m->charset_types, ext, charset);
  +    return NULL;
  +}
   
  -static const char *add_language(cmd_parms *cmd, mime_dir_config * m, char *lang,
  +static const char *add_language(cmd_parms *cmd, mime_dir_config *m, char *lang,
                                   char *ext)
   {
  -    if (*ext == '.')
  -        ++ext;
  +    if (*ext == '.') {
  +	++ext;
  +    }
       ap_str_tolower(lang);
       ap_table_setn(m->language_types, ext, lang);
       return NULL;
   }
   
  -static const char *add_handler(cmd_parms *cmd, mime_dir_config * m, char *hdlr,
  +static const char *add_handler(cmd_parms *cmd, mime_dir_config *m, char *hdlr,
                                  char *ext)
   {
       if (*ext == '.')
  @@ -214,6 +265,8 @@
        "a mime type followed by one or more file extensions"},
       {"AddEncoding", add_encoding, NULL, OR_FILEINFO, ITERATE2,
        "an encoding (e.g., gzip), followed by one or more file extensions"},
  +    {"AddCharset", add_charset, NULL, OR_FILEINFO, ITERATE2,
  +     "a charset (e.g., iso-2022-jp), followed by one or more file extensions"},
       {"AddLanguage", add_language, NULL, OR_FILEINFO, ITERATE2,
        "a language (e.g., fr), followed by one or more file extensions"},
       {"AddHandler", add_handler, NULL, OR_FILEINFO, ITERATE2,
  @@ -281,6 +334,251 @@
       ap_cfg_closefile(f);
   }
   
  +static char *zap_sp(char *s)
  +{
  +    char *tp;
  +
  +    if (s == NULL) {
  +	return (NULL);
  +    }
  +    if (*s == '\0') {
  +	return (s);
  +    }
  +
  +    /* delete prefixed white space */
  +    for (; *s == ' ' || *s == '\t' || *s == '\n'; s++);
  +
  +    /* delete postfixed white space */
  +    for (tp = s; *tp != '\0'; tp++);
  +    for (tp--; tp != s && (*tp == ' ' || *tp == '\t' || *tp == '\n'); tp--) {
  +	*tp = '\0';
  +    }
  +    return (s);
  +}
  +
  +static int is_token(char c)
  +{
  +    int res;
  +
  +    res = (ap_isascii(c) && ap_isgraph(c)
  +	   && (strchr(tspecial, c) == NULL)) ? 1 : -1;
  +    return res;
  +}
  +
  +static int is_qtext(char c)
  +{
  +    int res;
  +
  +    res = (ap_isascii(c) && (c != '"') && (c != '\\') && (c != '\n'))
  +	? 1 : -1;
  +    return res;
  +}
  +
  +static int is_quoted_pair(char *s)
  +{
  +    int res = -1;
  +    int c;
  +
  +    if (((s + 1) != NULL) && (*s == '\\')) {
  +	c = (int) *(s + 1);
  +	if (ap_isascii(c)) {
  +	    res = 1;
  +	}
  +    }
  +    return (res);
  +}
  +
  +static content_type *analyze_ct(request_rec *r, char *s)
  +{
  +    char *tp, *mp, *cp;
  +    char *attribute, *value;
  +    int quoted = 0;
  +    server_rec * ss = r->server;
  +    ap_context_t  * p = r->pool;
  +
  +    content_type *ctp;
  +    param *pp, *npp;
  +
  +    /* initialize ctp */
  +    ctp = (content_type *) ap_palloc(p, sizeof(content_type));
  +    ctp->type = NULL;
  +    ctp->subtype = NULL;
  +    ctp->param = NULL;
  +
  +    tp = ap_pstrdup(p, s);
  +
  +    mp = tp;
  +    cp = mp;
  +
  +    /* getting a type */
  +    if (!(cp = strchr(mp, '/'))) {
  +	ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +		     "mod_mime: analyze_ct: cannot get media type from '%s'",
  +		     (const char *) mp);
  +	return (NULL);
  +    }
  +    ctp->type = ap_pstrndup(p, mp, cp - mp);
  +    ctp->type = zap_sp(ctp->type);
  +    if (ctp->type == NULL || *(ctp->type) == '\0' ||
  +	strchr(ctp->type, ';') || strchr(ctp->type, ' ') ||
  +	strchr(ctp->type, '\t')) {
  +	ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +		     "Cannot get media subtype.");
  +	return (NULL);
  +    }
  +
  +    /* getting a subtype */
  +    cp++;
  +    mp = cp;
  +
  +    for (; *cp != ';' && *cp != '\0'; cp++);
  +    ctp->subtype = ap_pstrndup(p, mp, cp - mp);
  +    ctp->subtype = zap_sp(ctp->subtype);
  +    if ((ctp->subtype == NULL) || (*(ctp->subtype) == '\0') ||
  +	strchr(ctp->subtype, ' ') || strchr(ctp->subtype, '\t')) {
  +	ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +		     "Cannot get media subtype.");
  +	return (NULL);
  +    }
  +    cp = zap_sp(cp);
  +    if (cp == NULL || *cp == '\0') {
  +	return (ctp);
  +    }
  +
  +    /* getting parameters */
  +    cp++;
  +    cp = zap_sp(cp);
  +    if (cp == NULL || *cp == '\0') {
  +	ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +		     "Cannot get media parameter.");
  +	return (NULL);
  +    }
  +    mp = cp;
  +    attribute = NULL;
  +    value = NULL;
  +
  +    while (cp != NULL && *cp != '\0') {
  +	if (attribute == NULL) {
  +	    if (is_token((int) *cp) > 0) {
  +		cp++;
  +		continue;
  +	    }
  +	    else if (*cp == ' ' || *cp == '\t' || *cp == '\n') {
  +		cp++;
  +		continue;
  +	    }
  +	    else if (*cp == '=') {
  +		attribute = ap_pstrndup(p, mp, cp - mp);
  +		attribute = zap_sp(attribute);
  +		if (attribute == NULL || *attribute == '\0') {
  +		    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +				 "Cannot get media parameter.");
  +		    return (NULL);
  +		}
  +		cp++;
  +		cp = zap_sp(cp);
  +		if (cp == NULL || *cp == '\0') {
  +		    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +				 "Cannot get media parameter.");
  +		    return (NULL);
  +		}
  +		mp = cp;
  +		continue;
  +	    }
  +	    else {
  +		ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +			     "Cannot get media parameter.");
  +		return (NULL);
  +	    }
  +	}
  +	else {
  +	    if (mp == cp) {
  +		if (*cp == '"') {
  +		    quoted = 1;
  +		    cp++;
  +		}
  +		else {
  +		    quoted = 0;
  +		}
  +	    }
  +	    if (quoted > 0) {
  +		while (quoted && *cp != '\0') {
  +		    if (is_qtext((int) *cp) > 0) {
  +			cp++;
  +		    }
  +		    else if (is_quoted_pair(cp) > 0) {
  +			cp += 2;
  +		    }
  +		    else if (*cp == '"') {
  +			cp++;
  +			while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
  +			    cp++;
  +			}
  +			if (*cp != ';' && *cp != '\0') {
  +			    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +					 "Cannot get media parameter.");
  +			    return(NULL);
  +			}
  +			quoted = 0;
  +		    }
  +		    else {
  +			ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +				     "Cannot get media parameter.");
  +			return (NULL);
  +		    }
  +		}
  +	    }
  +	    else {
  +		while (1) {
  +		    if (is_token((int) *cp) > 0) {
  +			cp++;
  +		    }
  +		    else if (*cp == '\0' || *cp == ';') {
  +			break;
  +		    }
  +		    else {
  +			ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +				     "Cannot get media parameter.");
  +			return (NULL);
  +		    }
  +		}
  +	    }
  +	    value = ap_pstrndup(p, mp, cp - mp);
  +	    value = zap_sp(value);
  +	    if (value == NULL || *value == '\0') {
  +		ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
  +			     "Cannot get media parameter.");
  +		return (NULL);
  +	    }
  +
  +	    pp = ap_palloc(p, sizeof(param));
  +	    pp->attr = attribute;
  +	    pp->val = value;
  +	    pp->next = NULL;
  +
  +	    if (ctp->param == NULL) {
  +		ctp->param = pp;
  +	    }
  +	    else {
  +		npp = ctp->param;
  +		while (npp->next) {
  +		    npp = npp->next;
  +		}
  +		npp->next = pp;
  +	    }
  +	    quoted = 0;
  +	    attribute = NULL;
  +	    value = NULL;
  +	    if (*cp == '\0') {
  +		break;
  +	    }
  +	    cp++;
  +	    mp = cp;
  +	}
  +    }
  +    return (ctp);
  +}
  +
   static int find_ct(request_rec *r)
   {
       const char *fn = strrchr(r->filename, '/');
  @@ -289,6 +587,7 @@
       char *ext;
       const char *orighandler = r->handler;
       const char *type;
  +    const char *charset = NULL;
   
       if (r->finfo.filetype == APR_DIR) {
           r->content_type = DIR_MAGIC_TYPE;
  @@ -300,8 +599,9 @@
        * pointer to getword, causing a SEGV ..
        */
   
  -    if (fn == NULL)
  -        fn = r->filename;
  +    if (fn == NULL) {
  +	fn = r->filename;
  +    }
   
       /* Parse filename extensions, which can be in any order */
       while ((ext = ap_getword(r->pool, &fn, '.')) && *ext) {
  @@ -314,6 +614,12 @@
               found = 1;
           }
   
  +	/* Add charset to Content-Type */
  +	if ((type = ap_table_get(conf->charset_types, ext))) {
  +	    charset = type;
  +	    found = 1;
  +	}
  +
           /* Check for Content-Language */
           if ((type = ap_table_get(conf->language_types, ext))) {
               const char **new;
  @@ -337,7 +643,12 @@
           }
   
           /* Check for a special handler, but not for proxy request */
  -        if ((type = ap_table_get(conf->handlers, ext)) && !r->proxyreq) {
  +        if ((type = ap_table_get(conf->handlers, ext))
  +#if 0	
  +	/* XXX fix me when the proxy code is updated */
  +	    && r->proxyreq == NOT_PROXY) 
  +#endif
  +        ) {
               r->handler = type;
               found = 1;
           }
  @@ -353,8 +664,46 @@
               r->content_languages = NULL;
               r->content_encoding = NULL;
               r->handler = orighandler;
  -        }
  +	    charset = NULL;
  +	}
  +    }
   
  +    if (r->content_type) {
  +	content_type *ctp;
  +	char *ct;
  +	int override = 0;
  +
  +	ct = (char *) ap_palloc(r->pool,
  +				sizeof(char) * (strlen(r->content_type) + 1));
  +	strcpy(ct, r->content_type);
  +
  +	if ((ctp = analyze_ct(r, ct))) {
  +	    param *pp = ctp->param;
  +	    r->content_type = ap_pstrcat(r->pool, ctp->type, "/",
  +					 ctp->subtype, NULL);
  +	    while (pp != NULL) {
  +		if (charset && !strcmp(pp->attr, "charset")) {
  +		    if (!override) {
  +			r->content_type = ap_pstrcat(r->pool, r->content_type,
  +						     "; charset=", charset,
  +						     NULL);
  +			override = 1;
  +		    }
  +		}
  +		else {
  +		    r->content_type = ap_pstrcat(r->pool, r->content_type,
  +						 "; ", pp->attr,
  +						 "=", pp->val,
  +						 NULL);
  +		}
  +		pp = pp->next;
  +	    }
  +	    if (charset && !override) {
  +		r->content_type = ap_pstrcat(r->pool, r->content_type,
  +					     "; charset=", charset,
  +					     NULL);
  +	    }
  +	}
       }
   
       /* Set default language, if none was specified by the extensions
  
  
  

Re: cvs commit: apache-2.0/src/modules/standard mod_mime.c

Posted by Dirk-Willem van Gulik <di...@webweaving.org>.
dirkx@locus.apache.org wrote:
> 
> dirkx       00/03/16 17:09:10
> 
>   Modified:    src/modules/standard mod_mime.c
>   Log:
> 
Sorry, I pressed ctrl-C at the wrong moment. And it was commited but
I broke the mail. The nxt commit has the msg in it.

DW.