summaryrefslogtreecommitdiff
path: root/modules/http/mod_mime.c
diff options
context:
space:
mode:
authorBrian Pane <brianp@apache.org>2002-05-02 03:19:44 +0000
committerBrian Pane <brianp@apache.org>2002-05-02 03:19:44 +0000
commit8d637c1f13f4d6c3d2d31b245c745531169502c2 (patch)
tree64098f77121d455e12c2e8bbdbc0001b6e007c98 /modules/http/mod_mime.c
parent37060b992e96f872b75d7a6ad29c15847d2a4303 (diff)
downloadhttpd-8d637c1f13f4d6c3d2d31b245c745531169502c2.tar.gz
Performance fixes:
* eliminate some copying of sub-parts of the content type in analyze_ct() * take advantage of the fact that we know the lengths of those sub-parts in find_ct() to avoid having to recompute their length for concatenation The charset handling code needs the same type of optimization eventually. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@94900 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/http/mod_mime.c')
-rw-r--r--modules/http/mod_mime.c85
1 files changed, 54 insertions, 31 deletions
diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c
index bfd5dc18e9..d7ae93e267 100644
--- a/modules/http/mod_mime.c
+++ b/modules/http/mod_mime.c
@@ -136,8 +136,10 @@ typedef struct param_s {
} param;
typedef struct {
- char *type;
- char *subtype;
+ const char *type;
+ apr_size_t type_len;
+ const char *subtype;
+ apr_size_t subtype_len;
param *param;
} content_type;
@@ -533,7 +535,7 @@ static int is_quoted_pair(const char *s)
static content_type *analyze_ct(request_rec *r, const char *s)
{
- const char *cp, *mp, *tmp;
+ const char *cp, *mp;
char *attribute, *value;
int quoted = 0;
server_rec * ss = r->server;
@@ -551,51 +553,63 @@ static content_type *analyze_ct(request_rec *r, const char *s)
mp = s;
/* getting a type */
- if (!(cp = ap_strchr_c(mp, '/'))) {
+ cp = mp;
+ while (cp && apr_isspace(*cp)) {
+ cp++;
+ }
+ if (!*cp) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
"mod_mime: analyze_ct: cannot get media type from '%s'",
- (const char *) mp);
+ (const char *) mp);
return (NULL);
}
- ctp->type = zap_sp_and_dup(p, mp, cp, NULL);
- if (ctp->type == NULL || *(ctp->type) == '\0') {
+ ctp->type = cp;
+ do {
+ cp++;
+ } while (*cp && (*cp != '/') && !apr_isspace(*cp) && (*cp != ';'));
+ if (!*cp || (*cp == ';')) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
+ "Cannot get media type from '%s'",
+ (const char *) mp);
+ return (NULL);
+ }
+ while (apr_isspace(*cp)) {
+ cp++;
+ }
+ if (*cp != '/') {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
- "Cannot get media subtype.");
+ "mod_mime: analyze_ct: cannot get media type from '%s'",
+ (const char *) mp);
return (NULL);
}
- for (tmp = ctp->type; *tmp; tmp++) {
- if ((*tmp == ';') || (*tmp == ' ') || (*tmp == '\t')) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
- "Cannot get media subtype.");
- return (NULL);
- }
- }
+ ctp->type_len = cp - ctp->type;
- /* getting a subtype */
- cp++;
- mp = cp;
+ cp++; /* skip the '/' */
- for (; *cp != ';' && *cp != '\0'; cp++)
- continue;
- ctp->subtype = zap_sp_and_dup(p, mp, cp, NULL);
- if ((ctp->subtype == NULL) || (*(ctp->subtype) == '\0')) {
+ /* getting a subtype */
+ while (apr_isspace(*cp)) {
+ cp++;
+ }
+ if (!*cp) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
"Cannot get media subtype.");
return (NULL);
}
- for (tmp = ctp->subtype; *tmp; tmp++) {
- if ((*tmp == ' ') || (*tmp == '\t')) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
- "Cannot get media subtype.");
- return (NULL);
- }
+ ctp->subtype = cp;
+ do {
+ cp++;
+ } while (*cp && !apr_isspace(*cp) && (*cp != ';'));
+ ctp->subtype_len = cp - ctp->subtype;
+ while (apr_isspace(*cp)) {
+ cp++;
}
+
if (*cp == '\0') {
return (ctp);
}
/* getting parameters */
- cp++;
+ cp++; /* skip the ';' */
cp = zap_sp(cp);
if (cp == NULL || *cp == '\0') {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ss,
@@ -877,8 +891,17 @@ static int find_ct(request_rec *r)
if ((ctp = analyze_ct(r, r->content_type))) {
param *pp = ctp->param;
- ap_set_content_type(r, apr_pstrcat(r->pool, ctp->type, "/",
- ctp->subtype, NULL));
+ char *base_content_type = apr_palloc(r->pool, ctp->type_len +
+ ctp->subtype_len +
+ sizeof("/"));
+ char *tmp = base_content_type;
+ memcpy(tmp, ctp->type, ctp->type_len);
+ tmp += ctp->type_len;
+ *tmp++ = '/';
+ memcpy(tmp, ctp->subtype, ctp->subtype_len);
+ tmp += ctp->subtype_len;
+ *tmp = 0;
+ ap_set_content_type(r, base_content_type);
while (pp != NULL) {
if (charset && !strcmp(pp->attr, "charset")) {
if (!override) {