Return-Path: Delivered-To: apmail-httpd-apreq-dev-archive@www.apache.org Received: (qmail 75519 invoked from network); 10 Mar 2005 23:31:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 10 Mar 2005 23:31:03 -0000 Received: (qmail 29325 invoked by uid 500); 10 Mar 2005 23:30:51 -0000 Delivered-To: apmail-httpd-apreq-dev-archive@httpd.apache.org Received: (qmail 29227 invoked by uid 500); 10 Mar 2005 23:30:50 -0000 Mailing-List: contact apreq-dev-help@httpd.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Delivered-To: mailing list apreq-dev@httpd.apache.org Received: (qmail 29158 invoked by uid 99); 10 Mar 2005 23:30:50 -0000 X-ASF-Spam-Status: No, hits=0.1 required=10.0 tests=FORGED_RCVD_HELO X-Spam-Check-By: apache.org Received-SPF: pass (hermes.apache.org: local policy) Received: from duempel.org (HELO swift.roonstrasse.net) (81.209.165.42) by apache.org (qpsmtpd/0.28) with SMTP; Thu, 10 Mar 2005 15:30:48 -0800 Received: (qmail 12384 invoked by uid 1001); 10 Mar 2005 23:30:21 -0000 Date: Fri, 11 Mar 2005 00:30:21 +0100 From: Max Kellermann To: apreq-dev@httpd.apache.org Subject: [PATCH multi-env] remove size() functions, empty string on n==0, apreq_fwritev() rewrite Message-ID: <20050310233021.GA12246@roonstrasse.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Nq2Wo0NMKNjxTN9z" Content-Disposition: inline User-Agent: Mutt/1.5.6+20040907i X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N --Nq2Wo0NMKNjxTN9z Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 04-remove_size_functions.patch - remove apreq_param_size() and apreq_cookie_size() 05-remove_empty_string_on_n_eq_0.patch - make apreq_join() and apreq_params_as_string() return an empty string on n==0 06-rewrite_fwritev.patch - rewrite apreq_fwritev() - no recursion; while(1) instead. - optimization: eliminate one loop checking the whole iovec array - check for endless loop (len == 0) please review the last patch very carefully, because I havn't tested that (writing a test for apreq_brigade_fwrite() is on my TODO list). Another remark: error.c checks the apr_strerror() value for APR_EGENERAL. A message for that was not implemented until httpd 2.1, i.e. the test fails with httpd 2.0.53. Max --Nq2Wo0NMKNjxTN9z Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="04-remove_size_functions.patch" Thu Mar 10 22:20:54 CET 2005 max@duempel.org * remove apreq_param_size() and apreq_cookie_size() diff -rN -u old-apreq2/include/apreq_cookie.h new-apreq2/include/apreq_cookie.h --- old-apreq2/include/apreq_cookie.h 2005-03-11 00:20:45.865312720 +0100 +++ new-apreq2/include/apreq_cookie.h 2005-03-10 23:42:03.000000000 +0100 @@ -60,8 +60,6 @@ } apreq_cookie_t; -APREQ_DECLARE(apr_size_t)apreq_cookie_size(const apreq_cookie_t *c); - /** Upgrades cookie jar table values to apreq_cookie_t structs. */ static APR_INLINE diff -rN -u old-apreq2/include/apreq_param.h new-apreq2/include/apreq_param.h --- old-apreq2/include/apreq_param.h 2005-03-11 00:20:45.862313176 +0100 +++ new-apreq2/include/apreq_param.h 2005-03-11 00:20:46.040286120 +0100 @@ -40,8 +40,6 @@ const apreq_value_t v; /**< underlying name/value info */ } apreq_param_t; -APREQ_DECLARE(apr_size_t)apreq_param_size(const apreq_param_t *p); - /** @return 1 if the taint flag is set, 0 otherwise. */ static APR_INLINE diff -rN -u old-apreq2/library/cookie.c new-apreq2/library/cookie.c --- old-apreq2/library/cookie.c 2005-03-11 00:20:45.873311504 +0100 +++ new-apreq2/library/cookie.c 2005-03-10 23:42:03.000000000 +0100 @@ -27,24 +27,6 @@ #define ADD_COOKIE(j,c) apreq_value_table_add(&c->v, j) -APREQ_DECLARE(apr_size_t)apreq_cookie_size(const apreq_cookie_t *c) -{ - apr_size_t alen = 0; - - if (c->path != NULL) - alen += strlen(c->path); - if (c->domain != NULL) - alen += strlen(c->domain); - if (c->port != NULL) - alen += strlen(c->port); - if (c->comment != NULL) - alen += strlen(c->comment); - if (c->commentURL != NULL) - alen += strlen(c->commentURL); - - return (apr_size_t)alen + c->v.nlen + c->v.dlen; -} - APREQ_DECLARE(void) apreq_cookie_expires(apreq_cookie_t *c, const char *time_str) { diff -rN -u old-apreq2/library/param.c new-apreq2/library/param.c --- old-apreq2/library/param.c 2005-03-11 00:20:45.868312264 +0100 +++ new-apreq2/library/param.c 2005-03-11 00:20:46.052284296 +0100 @@ -59,28 +59,6 @@ return param; } -static int elt_size(void *data, const char *key, const char *val) -{ - apr_size_t *s = data; - *s = strlen(key) + strlen(val); - return 1; /* keep searching */ -} - -APREQ_DECLARE(apr_size_t)apreq_param_size(const apreq_param_t *p) -{ - apr_size_t tlen = 0; - apr_off_t blen = 0; - - if (p->info != NULL) - apr_table_do(elt_size, &tlen, p->info, NULL); - if (p->upload != NULL) - apr_brigade_length(p->upload, 0, &blen); - - return (apr_size_t)blen + tlen + p->v.nlen + p->v.dlen; - -} - - APREQ_DECLARE(apr_status_t) apreq_param_decode(apreq_param_t **param, apr_pool_t *pool, const char *word, --Nq2Wo0NMKNjxTN9z Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="05-remove_empty_string_on_n_eq_0.patch" Thu Mar 10 22:29:52 CET 2005 max@duempel.org * make apreq_join() and apreq_params_as_string() return an empty string on n==0 diff -rN -u old-apreq2/include/apreq_param.h new-apreq2/include/apreq_param.h --- old-apreq2/include/apreq_param.h 2005-03-11 00:21:04.155532184 +0100 +++ new-apreq2/include/apreq_param.h 2005-03-10 23:42:03.000000000 +0100 @@ -159,14 +159,16 @@ /** * Returns a ", " -joined string containing all parameters - * for the requested key, NULL if none are found. The key is case-insensitive. + * for the requested key, an empty string if none are found. + * The key is case-insensitive. + * * @param p Allocates the return string. * @param t the parameter table returned by apreq_args(), apreq_body() * or apreq_params() * @param key Null-terminated parameter name, case insensitive. * key==NULL fetches all values. * @param mode Join type- see apreq_join(). - * @return the joined string + * @return the joined string or NULL on error * @remark Also parses the request if necessary. */ APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p, diff -rN -u old-apreq2/include/apreq_util.h new-apreq2/include/apreq_util.h --- old-apreq2/include/apreq_util.h 2005-03-11 00:21:04.153532488 +0100 +++ new-apreq2/include/apreq_util.h 2005-03-10 23:42:03.000000000 +0100 @@ -39,14 +39,15 @@ */ /** - * Join an array of values. + * Join an array of values. The result is an empty string if there are + * no values. * * @param p Pool to allocate return value. * @param sep String that is inserted between the joined values. * @param arr Array of apreq_value_t entries. * @param mode Join type- see apreq_join_t. * - * @return Resulting string; can be upgraded to an apreq_value_t. + * @return Resulting string or NULL on error */ APREQ_DECLARE(char *) apreq_join(apr_pool_t *p, const char *sep, diff -rN -u old-apreq2/library/param.c new-apreq2/library/param.c --- old-apreq2/library/param.c 2005-03-11 00:21:04.168530208 +0100 +++ new-apreq2/library/param.c 2005-03-10 23:42:03.000000000 +0100 @@ -199,7 +199,7 @@ apreq_param_t **elt = (apreq_param_t **)arr->elts; apreq_param_t **const end = elt + arr->nelts; if (arr->nelts == 0) - return NULL; + return apr_pstrdup(p, ""); while (elt < end) { *(const apreq_value_t **)elt = &(**elt).v; diff -rN -u old-apreq2/library/t/params.c new-apreq2/library/t/params.c --- old-apreq2/library/t/params.c 2005-03-11 00:21:04.157531880 +0100 +++ new-apreq2/library/t/params.c 2005-03-10 23:42:03.000000000 +0100 @@ -66,6 +66,8 @@ AT_int_eq(arr->nelts, 2); val = apreq_params_as_string(p,args,"a",APREQ_JOIN_AS_IS); AT_str_eq(val, "1, 2"); + val = apreq_params_as_string(p,args,"does_not_exist",APREQ_JOIN_AS_IS); + AT_str_eq(val, ""); } static void string_decoding_in_place(dAT) @@ -196,7 +198,7 @@ at_test_t test_list [] = { dT(request_make, 3), dT(request_args_get, 8), - dT(params_as, 2), + dT(params_as, 3), dT(string_decoding_in_place, 8), dT(header_attributes, 13), dT(make_param, 8), diff -rN -u old-apreq2/library/util.c new-apreq2/library/util.c --- old-apreq2/library/util.c 2005-03-11 00:21:04.166530512 +0100 +++ new-apreq2/library/util.c 2005-03-11 00:21:04.317507560 +0100 @@ -410,7 +410,7 @@ slen = sep ? strlen(sep) : 0; if (n == 0) - return NULL; + return apr_pstrdup(p, ""); for (j=0, len=0; j < n; ++j) len += a[j]->dlen + slen + 1; --Nq2Wo0NMKNjxTN9z Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="06-rewrite_fwritev.patch" Fri Mar 11 00:15:53 CET 2005 max@duempel.org * rewrote apreq_fwritev() with optimizations and endless-recursion fix diff -rN -u old-apreq2/library/util.c new-apreq2/library/util.c --- old-apreq2/library/util.c 2005-03-11 00:21:20.812999864 +0100 +++ new-apreq2/library/util.c 2005-03-11 00:06:07.000000000 +0100 @@ -501,42 +501,50 @@ static apr_status_t apreq_fwritev(apr_file_t *f, struct iovec *v, int *nelts, apr_size_t *bytes_written) { - apr_size_t len, bytes_avail = 0; - int n = *nelts; - apr_status_t s = apr_file_writev(f, v, n, &len); + apr_size_t len; + int n; + apr_status_t s; - *bytes_written = len; + *bytes_written = 0; - if (s != APR_SUCCESS) - return s; + while (1) { + /* try to write */ + s = apr_file_writev(f, v, *nelts, &len); - while (--n >= 0 && bytes_avail <= len) - bytes_avail += v[n].iov_len; + *bytes_written += len; + if (s != APR_SUCCESS) + return s; - if (bytes_avail > len) { - /* incomplete write: must shift v */ + /* see how far we've come */ n = 0; - while (v[n].iov_len <= len) { - len -= v[n].iov_len; - ++n; + while (n < *nelts && len >= v[n].iov_len) + len -= v[n++].iov_len; + + if (n == *nelts) { + /* nothing left to write, report success */ + *nelts = 0; + return APR_SUCCESS; } + + /* incomplete write: must shift v */ v[n].iov_len -= len; v[n].iov_base = (char *)(v[n].iov_base) + len; if (n > 0) { + /* we're satisfied for now if we can remove one iovec from + the "v" array */ (*nelts) -= n; memmove(v, v + n, sizeof(*v) * *nelts); + + return APR_SUCCESS; } - else { - s = apreq_fwritev(f, v, nelts, &len); - *bytes_written += len; - } - } - else - *nelts = 0; - return s; + /* we're still in the first iovec - check for endless loop, + and then try again */ + if (len == 0) + return APREQ_ERROR_GENERAL; + } } --Nq2Wo0NMKNjxTN9z--