httpd-apreq-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject cvs commit: httpd-apreq-2/src README apreq.c apreq.h apreq_cookie.h apreq_env.h apreq_params.c apreq_params.h apreq_parsers.c apreq_version.h
Date Fri, 04 Jun 2004 22:02:11 GMT
joes        2004/06/04 15:02:11

  Modified:    .        CHANGES STATUS
               src      README apreq.c apreq.h apreq_cookie.h apreq_env.h
                        apreq_params.c apreq_params.h apreq_parsers.c
                        apreq_version.h
  Log:
    apreq_run_(hook|parser) are macros, so they are capitalized now.
    Fixed apreq_params_as_string() and added apreq_params_as_array().
    Reworked definitions of APREQ_DECLARE_HOOK, APREQ_DECLARE_PARSER
    and apreq_(parser|hook)_t, hopefully to be more Win32 friendly.
    Also updated the documentation.
  
  Revision  Changes    Path
  1.32      +7 -0      httpd-apreq-2/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/CHANGES,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- CHANGES	18 Apr 2004 01:40:47 -0000	1.31
  +++ CHANGES	4 Jun 2004 22:02:11 -0000	1.32
  @@ -4,6 +4,13 @@
   @section v2_03_dev Changes with libapreq2-2.03-dev
   
   - C API [joes]
  +  apreq_run_(hook|parser) are macros, so they are capitalized now.
  +  Fixed apreq_params_as_string() and added apreq_params_as_array().
  +  Reworked definitions of APREQ_DECLARE_HOOK, APREQ_DECLARE_PARSER 
  +  and apreq_(parser|hook)_t, hopefully to be more Win32 friendly.
  +  Also updated the documentation.
  +
  +- C API [joes]
     Compensate for a missing CRLF in empty file upload block, which 
     actually complies with RFC 2046 Section 5.1.1.  Konqueror (version unknown)
     and Mozilla 0.9.7 are known to emit such blocks.
  
  
  
  1.46      +4 -1      httpd-apreq-2/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/STATUS,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -r1.45 -r1.46
  --- STATUS	22 May 2004 15:25:43 -0000	1.45
  +++ STATUS	4 Jun 2004 22:02:11 -0000	1.46
  @@ -92,6 +92,9 @@
         but there are too many problems with the current (May 2004)
         ports of the auto* tools for us to accomodate FreeBSD (yet).
   
  +    - The current API does not handle failed query_string parsing
  +      adequately (apreq_request does log an error message, but 
  +      there's no status code in the struct for users to interrogate).
   
   WISH LIST:
   
  
  
  
  1.5       +7 -15     httpd-apreq-2/src/README
  
  Index: README
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/README,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- README	17 Jul 2003 21:56:38 -0000	1.4
  +++ README	4 Jun 2004 22:02:11 -0000	1.5
  @@ -3,20 +3,13 @@
   
   Data structures and relations:
   
  -  BASE:
  +  BASIC VALUE TYPE:
   
       apreq_value_t:  basic type for handling opaque data.  The type
                       is meant to be extended by placing all "metadata"
                       in front (within a larger structure).
   
  -    apreq_table_t : apreq_value_t container. treats value_t as 
  -                    "key -> data" pair and provides lookup api.  
  -                    Custom copy/merge functions can be added to 
  -                    internally handle additional metadata attached
  -                    to the contained apreq_value_t's.
  -
  -
  -  COOKIE EXTENSIONS:
  +  COOKIES:
   
       apreq_cookie_t: extends apreq_value_t to represent server-side
                   cookie data.
  @@ -24,11 +17,11 @@
       apreq_jar_t: A pool and a table with cookie-based copy/merge functions.
                    This struct is analogous to apreq_request_t for params.
   
  -
  -  PARAM EXTENSIONS:
  +  PARAMS:
   
       apreq_param_t: extends apreq_value_t to represent POST param data.
   
  +
       apreq_request_t: maintains arg/body tables which represent parsed data.
   
           REQUEST STATES:
  @@ -46,9 +39,8 @@
   
     PARSER EXTENSIONS:
   
  -    apreq_parser_t: extends apreq_value_t to represent a parser callback,
  -                    with its associated configuration data.
  +    apreq_parser_t: parser callback, with its associated configuration data.
   
  -    apreq_hook_t: extends multipart/form-data by transforming the input 
  -                  brigade and pushing buckets onto the current param->bb.
  +    apreq_hook_t: extends multipart/form-data parser by transforming incoming
  +                  brigades which represent the contents of a file upload.
   
  
  
  
  1.33      +22 -9     httpd-apreq-2/src/apreq.c
  
  Index: apreq.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq.c,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- apreq.c	24 Mar 2004 08:22:48 -0000	1.32
  +++ apreq.c	4 Jun 2004 22:02:11 -0000	1.33
  @@ -404,30 +404,38 @@
       return d - dest;
   }
   
  +APREQ_DECLARE(apr_size_t) apreq_quote_once(char *dest, const char *src, 
  +                                           const apr_size_t slen) 
  +{
  +    if (slen > 1 && src[0] == '"' && src[slen-1] == '"') {
  +        /* looks like src is already quoted */        
  +        memcpy(dest, src, slen);
  +        return slen;
  +    }
  +    else
  +        return apreq_quote(dest, src, slen);
  +}
  +
   APREQ_DECLARE(apr_size_t) apreq_quote(char *dest, const char *src, 
                                         const apr_size_t slen) 
   {
       char *d = dest;
       const char *s = src;
  +    const char *const last = src + slen - 1;
   
       if (slen == 0) {
           *d = 0;
           return 0;
       }
   
  -    if (src[0] == '"' && src[slen-1] == '"') { /* src is already quoted */
  -        memcpy(dest, src, slen);
  -        return slen;
  -    }
  -
       *d++ = '"';
   
  -    while (s < src + slen) {
  +    while (s <= last) {
   
           switch (*s) {
   
           case '\\': 
  -            if (s < src + slen - 1) {
  +            if (s < last) {
                   *d++ = *s++;
                   break;
               }
  @@ -533,12 +541,13 @@
   
   
       case QUOTE:
  -        d += apreq_quote(d, a[0]->data, a[0]->size);
  +
  +        d += apreq_quote_once(d, a[0]->data, a[0]->size);
   
           for (j = 1; j < n; ++j) {
               memcpy(d, sep, slen);
               d += slen;
  -            d += apreq_quote(d, a[j]->data, a[j]->size);
  +            d += apreq_quote_once(d, a[j]->data, a[j]->size);
           }
           break;
   
  @@ -578,6 +587,10 @@
       return rv->data;
   }
   
  +APREQ_DECLARE(apr_ssize_t) apreq_unescape(char *str)
  +{
  +    return apreq_decode(str,str,strlen(str));
  +}
   
   APR_INLINE
   static apr_status_t apreq_fwritev(apr_file_t *f, struct iovec *v, 
  
  
  
  1.39      +63 -14    httpd-apreq-2/src/apreq.h
  
  Index: apreq.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq.h,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- apreq.h	24 Mar 2004 08:22:48 -0000	1.38
  +++ apreq.h	4 Jun 2004 22:02:11 -0000	1.39
  @@ -114,7 +114,7 @@
    */
   typedef struct apreq_value_t {
       const char    *name;    /**< value's name */
  -    apr_status_t   status;  /**< APR status, usually SUCCESS or INCOMPLETE*/
  +    apr_status_t   status;  /**< APR status, usually APR_SUCCESS or APR_INCOMPLETE*/
       apr_size_t     size;    /**< Size of data.*/
       char           data[1]; /**< Actual data bytes.*/
   } apreq_value_t;
  @@ -126,9 +126,25 @@
   
   
   #define apreq_attr_to_type(T,A,P) ( (T*) ((char*)(P)-offsetof(T,A)) )
  -#define apreq_char_to_value(ptr)  apreq_attr_to_type(apreq_value_t, data, ptr)
   
  +/**
  + * Converts (char *) to (apreq_value_t *).  The char * is assumed
  + * to point at the data attribute of an apreq_value_t struct.
  + *
  + * @param ptr   points at the data field of an apreq_value_t struct.
  + */
  +
  +#define apreq_char_to_value(ptr)  apreq_attr_to_type(apreq_value_t, data, ptr)
   #define apreq_strtoval(ptr)  apreq_char_to_value(ptr)
  +
  +/**
  + * Computes the length of the string, but unlike strlen(),
  + * it permits embedded null characters.
  + *
  + * @param ptr  points at the data field of an apreq_value_t struct.
  + * 
  + */
  +
   #define apreq_strlen(ptr) (apreq_strtoval(ptr)->size)
   
   /**
  @@ -220,40 +236,56 @@
    * @param ndl  Search string
    * @param nlen Length of search string.
    * @param type Match type.
  + * @return Offset of match string, or -1 if mo match is found.
    *
    */
   APREQ_DECLARE(apr_ssize_t) apreq_index(const char* hay, apr_size_t hlen, 
                           const char* ndl, apr_size_t nlen, 
                           const apreq_match_t type);
   /**
  - * Places a quoted copy of src into dest.
  - * @param dest Location of quoted copy.  Must be large enough to hold the copy.
  + * Places a quoted copy of src into dest.  Embedded quotes are escaped with a
  + * backslash ('\').
  + * @param dest Location of quoted copy.  Must be large enough to hold the copy
  + *             and trailing null byte.
    * @param src  Original string.
    * @param slen Length of original string.
  + * @param dest Destination string.
    * @return length of quoted copy in dest.
    */
  +APREQ_DECLARE(apr_size_t) apreq_quote(char *dest, const char *src, 
  +                                      const apr_size_t slen);
   
  -APREQ_DECLARE(apr_size_t) apreq_quote(char *dest, const char *src, const apr_size_t slen);
  +/**
  + * Same as apreq_quote() except when src begins and ends in quote marks. In
  + * that case it assumes src is quoted correctly, and just copies src to dest.
  + * @param dest Location of quoted copy.  Must be large enough to hold the copy
  + *             and trailing null byte.
  + * @param src  Original string.
  + * @param slen Length of original string.
  + * @param dest Destination string.
  + * @return length of quoted copy in dest.
  + */
  +APREQ_DECLARE(apr_size_t) apreq_quote_once(char *dest, const char *src, 
  +                                           const apr_size_t slen);
   
   /**
    * Url-encodes a string.
  - * @param dest Location of url-encoded result string. Caller must ensure dest is
  - *             large enough.
  + * @param dest Location of url-encoded result string. Caller must ensure it
  + *             is large enough to hold the encoded string and trailing '\0'.
    * @param src  Original string.
    * @param slen Length of original string.
    * @return length of url-encoded string in dest.
    */
  -
  -APREQ_DECLARE(apr_size_t) apreq_encode(char *dest, const char *src, const apr_size_t slen);
  +APREQ_DECLARE(apr_size_t) apreq_encode(char *dest, const char *src, 
  +                                       const apr_size_t slen);
   
   /**
    * Url-decodes a string.
  - * @param dest Location of url-decoded result string. Caller must ensure dest is
  - *             large enough.
  + * @param dest Location of url-encoded result string. Caller must ensure dest is
  + *             large enough to hold the encoded string and trailing null character.
    * @param src  Original string.
    * @param slen Length of original string.
  - * @return Length of url-decoded string in dest, or < 0 on 
  - *         decoding (bad data) error.
  + * @return Length of url-decoded string in dest, or < 0 on decoding (bad data) error.
    */
   
   APREQ_DECLARE(apr_ssize_t) apreq_decode(char *dest, const char *src, const apr_size_t slen);
  @@ -274,10 +306,11 @@
    * An \e in-situ url-decoder.
    * @param str  The string to decode
    * @return  Length of decoded string, or < 0 on error.
  + * @remark Equivalent to apreq_decode(str,str,strlen(str)).
    */
   
   APREQ_DECLARE(apr_ssize_t) apreq_unescape(char *str);
  -#define apreq_unescape(str) apreq_decode(str,str,strlen(str))
  +
   
   /** @enum apreq_expires_t Expiration date format */
   typedef enum {
  @@ -340,6 +373,7 @@
    * @param path  The base directory which will contain the temp file.
    *              If param == NULL, the directory will be selected via
    *              tempnam().  See the tempnam manpage for details.
  + * @return APR_SUCCESS on success; error code otherwise.
    */
   
   APREQ_DECLARE(apr_status_t) apreq_file_mktemp(apr_file_t **fp, 
  @@ -356,9 +390,24 @@
   
   APREQ_DECLARE(apr_file_t *) apreq_brigade_spoolfile(apr_bucket_brigade *bb);
   
  +/**
  + * Duplicate a brigade.
  + * @param bb Original brigade.
  + * @return New brigade containing a bucket-by-bucket copy of the original.
  + */
  +
   APREQ_DECLARE(apr_bucket_brigade *)
            apreq_brigade_copy(const apr_bucket_brigade *bb);
   
  +/**
  + * Search a header string for the value of a particular named attribute.
  + * @param hdr Header string to scan.
  + * @param name Name of attribute to search for.
  + * @param nlen Length of name.
  + * @param val Location of (first) matching value.
  + * @param vlen Length of matching value.
  + * @return APR_SUCCESS if found, otherwise APR_NOTFOUND.
  + */
   APREQ_DECLARE(apr_status_t)
            apreq_header_attribute(const char *hdr,
                                   const char *name, const apr_size_t nlen,
  
  
  
  1.21      +4 -0      httpd-apreq-2/src/apreq_cookie.h
  
  Index: apreq_cookie.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_cookie.h,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- apreq_cookie.h	28 Feb 2004 07:48:14 -0000	1.20
  +++ apreq_cookie.h	4 Jun 2004 22:02:11 -0000	1.21
  @@ -197,6 +197,10 @@
   APREQ_DECLARE(apr_status_t) apreq_cookie_bake2(const apreq_cookie_t *c,
                                                  void *env);
   
  +/**
  + *
  + *
  + */
   APREQ_DECLARE(apreq_cookie_version_t) apreq_ua_cookie_version(void *env);
   
   /** @} */
  
  
  
  1.23      +152 -0    httpd-apreq-2/src/apreq_env.h
  
  Index: apreq_env.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_env.h,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- apreq_env.h	24 Mar 2004 08:22:48 -0000	1.22
  +++ apreq_env.h	4 Jun 2004 22:02:11 -0000	1.23
  @@ -74,37 +74,166 @@
    * @{
    */
   
  +/**
  + * Analog of Apache's ap_log_rerror().
  + * @param file Filename to list in the log message.
  + * @param line Line number from the file.
  + * @param level Log level.
  + * @param status Status code.
  + * @param env Current environment.
  + * @param fmt Format string for the log message.
  + */
  +
   APREQ_DECLARE_NONSTD(void) apreq_log(const char *file, int line,
                                        int level, apr_status_t status,
                                        void *env, const char *fmt, ...);
  +/**
  + * Pool associated with the environment.
  + * @param env The current environment
  + * @return The associated pool.
  + */
   
   APREQ_DECLARE(apr_pool_t *) apreq_env_pool(void *env);
  +
  +/**
  + * Get/set the jar currently associated to the environment.
  + * @param env The current environment.
  + * @param jar New Jar to associate.
  + * @return The previous jar associated to the environment.
  + * jar == NULL gets the current jar, which will remain associated
  + * after the call.
  + */
   APREQ_DECLARE(apreq_jar_t *) apreq_env_jar(void *env, apreq_jar_t *jar);
  +
  +/**
  + * Get/set the request currently associated to the environment.
  + * @param env The current environment.
  + * @param req New request to associate.
  + * @return The previous request associated to the environment.
  + * req == NULL gets the current request, which will remain associated
  + * after the call.
  + */
   APREQ_DECLARE(apreq_request_t *) apreq_env_request(void *env,
                                                      apreq_request_t *req);
   
  +/**
  + * Fetch the query string.
  + * @param env The current environment.
  + * @return The query string.
  + */
   APREQ_DECLARE(const char *) apreq_env_query_string(void *env);
  +
  +/**
  + * Fetch the header value (joined by ", " if there are multiple headers)
  + * for a given header name.
  + * @param env The current environment.
  + * @param name The header name.
  + * @return The value of the header, NULL if not found.
  + */
   APREQ_DECLARE(const char *) apreq_env_header_in(void *env, const char *name);
   
  +
  +/**
  + * Fetch the environment's "Content-Type" header.
  + * @param env The current environment.
  + * @return The value of the Content-Type header, NULL if not found.
  + */
   #define apreq_env_content_type(env) apreq_env_header_in(env, "Content-Type")
  +
  +
  +/**
  + * Fetch the environment's "Cookie" header.
  + * @param env The current environment.
  + * @return The value of the "Cookie" header, NULL if not found.
  + */
   #define apreq_env_cookie(env) apreq_env_header_in(env, "Cookie")
  +
  +/**
  + * Fetch the environment's "Cookie2" header.
  + * @param env The current environment.
  + * @return The value of the "Cookie2" header, NULL if not found.
  + */
   #define apreq_env_cookie2(env) apreq_env_header_in(env, "Cookie2")
   
  +/**
  + * Add a header field to the environment's outgoing response headers
  + * @param env The current environment.
  + * @param name The name of the outgoing header.
  + * @param val Value of the outgoing header.
  + * @return APR_SUCCESS on success, error code otherwise.
  + */
   APREQ_DECLARE(apr_status_t)apreq_env_header_out(void *env, 
                                                   const char *name,
                                                   char *val);
   
  +/**
  + * Add a "Set-Cookie" header to the outgoing response headers.
  + * @param e The current environment.
  + * @param s The cookie string.
  + * @return APR_SUCCESS on success, error code otherwise.
  + */
   #define apreq_env_set_cookie(e,s) apreq_env_header_out(e,"Set-Cookie",s)
  +
  +/**
  + * Add a "Set-Cookie2" header to the outgoing response headers.
  + * @param e The current environment.
  + * @param s The cookie string.
  + * @return APR_SUCCESS on success, error code otherwise.
  + */
   #define apreq_env_set_cookie2(e,s) apreq_env_header_out(e,"Set-Cookie2",s)
   
  +/**
  + * Read data from the environment and into the current active parser.
  + * @param env The current environment.
  + * @param block Read type (APR_READ_BLOCK or APR_READ_NONBLOCK).
  + * @param bytes Maximum number of bytes to read.
  + * @return APR_INCOMPLETE if there's more data to read,
  + *         APR_SUCCESS if everything was read & parsed successfully,
  + *         error code otherwise.
  + */
   APREQ_DECLARE(apr_status_t) apreq_env_read(void *env,
                                              apr_read_type_e block,
                                              apr_off_t bytes);
   
  +/**
  + * Get/set the current temporary directory.
  + * @param env The current environment.
  + * @param path The full pathname of the new directory.
  + * @return The path of the previous temporary directory.  Note: a call using
  + * path==NULL fetches the current directory without resetting it to NULL.
  + */
  +
   APREQ_DECLARE(const char *) apreq_env_temp_dir(void *env, const char *path);
  +
  +/**
  + * Get/set the current max_body setting.  This is the maximum
  + * amount of bytes that will be read into the environment's parser.
  + * @param env The current environment.
  + * @param bytes The new max_body setting.
  + * @return The previous max_body setting.  Note: a call using
  + * bytes == -1 fetches the current max_body setting without modifying it.
  + *
  + */
  +
   APREQ_DECLARE(apr_off_t) apreq_env_max_body(void *env, apr_off_t bytes);
  +
  +/**
  + * Get/set the current max_brigade setting.  This is the maximum
  + * amount of heap-allocated buckets libapreq2 will use for its brigades.  
  + * If additional buckets are necessary, they will be created from a temporary file.
  + * @param env The current environment.
  + * @param bytes The new max_brigade setting.
  + * @return The previous max_brigade setting.  Note: a call using
  + * bytes == -1 fetches the current max_brigade setting without modifying it.
  + *
  + */
   APREQ_DECLARE(apr_ssize_t) apreq_env_max_brigade(void *env, apr_ssize_t bytes);
   
  +/**
  + * The environment structure, which must be fully defined
  + * for libapreq2 to operate properly in a given environment.
  + */
  +
   typedef struct apreq_env_t {
       const char *name;
       apr_uint32_t magic_number;
  @@ -121,15 +250,38 @@
       apr_ssize_t (*max_brigade)(void *, apr_ssize_t);
   } apreq_env_t;
   
  +/**
  + * Convenience macro for defining an environment module by mapping
  + * a function prefix to an associated environment structure.
  + * @param pre Prefix to define new environment.  All attributes of
  + * the apreq_env_t struct are defined with this as their prefix. The
  + * generated struct is named by appending "_module" to the prefix.
  + * @param name Name of this environment.
  + * @param mmn Magic number (i.e. version number) of this environment.
  + */
   #define APREQ_ENV_MODULE(pre, name, mmn) const apreq_env_t pre##_module = { \
     name, mmn, pre##_log, pre##_pool, pre##_jar, pre##_request,               \
     pre##_query_string, pre##_header_in, pre##_header_out, pre##_read,        \
     pre##_temp_dir, pre##_max_body, pre##_max_brigade }
   
   
  +/**
  + * Get/set function for the active environment stucture. Usually this
  + * is called only once per process, to define the correct environment.
  + * @param mod  The new active environment.
  + * @return The previous active environment.  Note: a call using
  + * mod == NULL fetches the current environment module without modifying it.
  + */
   APREQ_DECLARE(const apreq_env_t *) apreq_env_module(const apreq_env_t *mod);
   
  +/**
  + * The current environment's name.
  + */
   #define apreq_env_name (apreq_env_module(NULL)->name)
  +
  +/**
  + * The current environment's magic (ie. version) number.
  + */
   #define apreq_env_magic_number (apreq_env_module(NULL)->magic_number)
   
   /** @} */
  
  
  
  1.40      +52 -1     httpd-apreq-2/src/apreq_params.c
  
  Index: apreq_params.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.c,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- apreq_params.c	13 Apr 2004 21:46:38 -0000	1.39
  +++ apreq_params.c	4 Jun 2004 22:02:11 -0000	1.40
  @@ -129,6 +129,57 @@
   }
   
   
  +static int param_push(void *data, const char *key, const char *val)
  +{
  +    apr_array_header_t *arr = data;
  +    *(apreq_param_t **)apr_array_push(arr) = 
  +        apreq_value_to_param(apreq_strtoval(val));
  +    return 0;
  +}
  +
  +
  +APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
  +                                                          apreq_request_t *req,
  +                                                          const char *key)
  +{
  +    apr_status_t s;
  +    apr_array_header_t *arr = apr_array_make(p, apr_table_elts(req->args)->nelts,
  +                                             sizeof(apreq_param_t *));
  +
  +    apr_table_do(param_push, arr, req->args, key);
  +
  +    do s = apreq_env_read(req->env, APR_BLOCK_READ, APREQ_READ_AHEAD);
  +    while (s == APR_INCOMPLETE);
  +
  +    if (req->body)
  +        apr_table_do(param_push, arr, req->body, key);
  +
  +    return arr;
  +}
  +
  +APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
  +                                                   apreq_request_t *req,
  +                                                   const char *key,
  +                                                   apreq_join_t mode)
  +{
  +    /* Must adjust apreq_param_t pointers to apreq_value_t. */
  +#ifdef DEBUG
  +    assert(sizeof(apreq_param_t **) == sizeof(apreq_value_t **));
  +#endif
  +    apr_array_header_t *arr = apreq_params_as_array(p, req, key);
  +    apreq_param_t **elt = (apreq_param_t **)arr->elts;
  +    apreq_param_t **const end = elt + arr->nelts;
  +    if (arr->nelts == 0)
  +        return NULL;
  +
  +    while (elt < end) {
  +        *(apreq_value_t **)elt = &(**elt).v;
  +        ++elt;
  +    }
  +    return apreq_join(p, ", ", arr, mode);
  +}
  +
  +
   APREQ_DECLARE(apreq_param_t *) apreq_decode_param(apr_pool_t *pool, 
                                                     const char *word,
                                                     const apr_size_t nlen, 
  @@ -242,7 +293,7 @@
       if (req->body == NULL)
           req->body = apr_table_make(apreq_env_pool(req->env),APREQ_NELTS);
   
  -    return apreq_run_parser(req->parser, req->env, req->body, bb);
  +    return APREQ_RUN_PARSER(req->parser, req->env, req->body, bb);
   }
   
   
  
  
  
  1.28      +164 -50   httpd-apreq-2/src/apreq_params.h
  
  Index: apreq_params.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_params.h,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- apreq_params.h	24 Mar 2004 08:22:48 -0000	1.27
  +++ apreq_params.h	4 Jun 2004 22:02:11 -0000	1.28
  @@ -42,6 +42,7 @@
       apreq_value_t        v;    /**< underlying name/value/status info */
   } apreq_param_t;
   
  +/* These structs are defined below */
   typedef struct apreq_hook_t apreq_hook_t;
   typedef struct apreq_parser_t apreq_parser_t;
   
  @@ -96,33 +97,49 @@
    * if NULL.
    * @remark Also parses the request as necessary.
    */
  -
   APREQ_DECLARE(apreq_param_t *) apreq_param(const apreq_request_t *req, 
                                              const char *name); 
   
  +
   /**
  - * Returns all parameters for the requested key,
  - * NULL if none found. The key is case-insensitive.
  + * Returns a table containing key-value pairs for the full request
  + * (args + body).
  + * @param p Allocates the returned table.
    * @param req The current apreq_request_t object.
  - * @param key Nul-terminated search key.  Returns the first table value 
  - * if NULL.
  - * @remark Also parses the request as necessary.
  + * @remark Also parses the request if necessary.
    */
  -
   APREQ_DECLARE(apr_table_t *) apreq_params(apr_pool_t *p,
                                             const apreq_request_t *req);
   
   
  +
  +/**
  + * Returns an array of parameters (apreq_param_t *) matching the given key.
  + * The key is case-insensitive.
  + * @param p Allocates the returned array.
  + * @param req The current apreq_request_t object.
  + * @param key Null-terminated search key.  key==NULL fetches all parameters.
  + * @remark Also parses the request if necessary.
  + */
  +APREQ_DECLARE(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,
  +                                                          apreq_request_t *req,
  +                                                          const char *key);
  +
   /**
    * Returns a ", " -separated string containing all parameters 
  - * for the requested key, NULL if none found.  The key is case-insensitive.
  + * for the requested key, NULL if none are found.  The key is case-insensitive.
  + * @param p Allocates the return string.
    * @param req The current apreq_request_t object.
  - * @param key Nul-terminated search key.  Returns the first table value 
  - * if NULL.
  - * @remark Also parses the request as necessary.
  + * @param key Null-terminated parameter name. key==NULL fetches all values. 
  + * @param mode Join type- see apreq_join().
  + * @return Returned string is the data attribute of an apreq_value_t,
  + *         so it is safe to use in apreq_strlen() and apreq_strtoval().
  + * @remark Also parses the request if necessary.
    */
  -#define apreq_params_as_string(req,key,pool, mode) \
  - apreq_join(pool, ", ", apreq_params(req,pool,key), mode)
  +APREQ_DECLARE(const char *) apreq_params_as_string(apr_pool_t *p,
  +                                                   apreq_request_t *req,
  +                                                   const char *key,
  +                                                   apreq_join_t mode);
   
   
   /**
  @@ -142,6 +159,9 @@
                                                     const apr_size_t vlen);
   /**
    * Url-encodes the param into a name-value pair.
  + * @param pool Pool which allocates the returned string.
  + * @param param Param to encode.
  + * @return name-value pair representing the param.
    */
   
   APREQ_DECLARE(char *) apreq_encode_param(apr_pool_t *pool, 
  @@ -152,6 +172,7 @@
    * @param pool    pool used to allocate the param data.
    * @param table   table to which the params are added.
    * @param qs      Query string to url-decode.
  + * @return        APR_SUCCESS if successful, error otherwise.
    * @remark        This function uses [&;] as the set of tokens
    *                to delineate words, and will treat a word w/o '='
    *                as a name-value pair with value-length = 0.
  @@ -169,12 +190,6 @@
    * @return    APR_INCOMPLETE if the parse is incomplete,
    *            APR_SUCCESS if the parser is finished (saw eos),
    *            unrecoverable error value otherwise.
  - *
  - * @remark    Polymorphic buckets (file, pipe, socket, etc.)
  - *            will generate new buckets during parsing, which
  - *            may cause problems with the configuration checks.
  - *            To be on the safe side, the caller should avoid
  - *            placing such buckets in the passed brigade.
    */
   
   APREQ_DECLARE(apr_status_t)apreq_parse_request(apreq_request_t *req, 
  @@ -183,6 +198,8 @@
    * Returns a table of all params in req->body with non-NULL bucket brigades.
    * @param pool Pool which allocates the table struct.
    * @param req  Current request.
  + * @return Upload table.
  + * @remark Will parse the request if necessary.
    */
   
   APREQ_DECLARE(apr_table_t *) apreq_uploads(apr_pool_t *pool,
  @@ -191,63 +208,160 @@
   /**
    * Returns the first param in req->body which has both param->v.name 
    * matching key and param->bb != NULL.
  + * @param req The current request.
  + * @param key Parameter name. key == NULL returns first upload.
  + * @return Corresponding upload, NULL if none found.
  + * @remark Will parse the request as necessary.
    */
   
   APREQ_DECLARE(apreq_param_t *) apreq_upload(const apreq_request_t *req,
                                               const char *key);
   
  +/** Parser arguments. */
  +#define APREQ_PARSER_ARGS (apreq_parser_t *parser,     \
  +                           void *env,                  \
  +                           apr_table_t *t,             \
  +                           apr_bucket_brigade *bb)
  +
  +/** Hook arguments */
  +#define APREQ_HOOK_ARGS   (apreq_hook_t *hook,         \
  +                           void *env,                  \
  +                           const apreq_param_t *param, \
  +                           apr_bucket_brigade *bb)
   
  -#define APREQ_DECLARE_PARSER(f) apr_status_t (f)(apreq_parser_t *parser, \
  -                                                 void *env,              \
  -                                                 apr_table_t *t,         \
  -                                                 apr_bucket_brigade *bb)
  -
  -#define APREQ_DECLARE_HOOK(f) apr_status_t (f)(apreq_hook_t *hook,         \
  -                                               void *env,                  \
  -                                               const apreq_param_t *param, \
  -                                               apr_bucket_brigade *bb)
  +/**
  + * Declares a API parser.
  + */
  +#define APREQ_DECLARE_PARSER(f) APREQ_DECLARE(apr_status_t) \
  +                                (f) APREQ_PARSER_ARGS
  +
  +/**
  + * Declares an API hook.
  + */
  +#define APREQ_DECLARE_HOOK(f)   APREQ_DECLARE(apr_status_t) \
  +                                (f) APREQ_HOOK_ARGS
   
  +/**
  + * Singly linked list of hooks.
  + *
  + */
   struct apreq_hook_t {
  -    APREQ_DECLARE_HOOK    (*hook);
  -    apreq_hook_t           *next;
  -    void                   *ctx;
  +    apr_status_t  (*hook) APREQ_HOOK_ARGS;
  +    apreq_hook_t   *next;
  +    void           *ctx;
   };
   
  +/**
  + * Request parser with associated enctype and hooks. 
  + *
  + */
   struct apreq_parser_t {
  -    APREQ_DECLARE_PARSER  (*parser);
  -    const char             *enctype;
  -    apreq_hook_t           *hook;
  -    void                   *ctx;
  +    apr_status_t (*parser) APREQ_PARSER_ARGS;
  +    const char    *enctype;
  +    apreq_hook_t  *hook;
  +    void          *ctx;
   };
   
   
  -#define apreq_run_parser(psr,env,t,bb) (psr)->parser(psr,env,t,bb)
  -#define apreq_run_hook(h,env,param,bb) (h)->hook(h,env,param,bb)
  +/**
  + * Parse the incoming brigade into a table.
  + */
  +#define APREQ_RUN_PARSER(psr,env,t,bb) (psr)->parser(psr,env,t,bb)
  +
  +/**
  + * Run the hook with the current parameter and the incoming 
  + * bucket brigade.  The hook may modify the brigade if necessary.
  + * Once all hooks have completed, the contents of the brigade will 
  + * be added to the parameter's bb attribute.
  + */
  +#define APREQ_RUN_HOOK(h,env,param,bb) (h)->hook(h,env,param,bb)
   
  +/**
  + * Concatenates the brigades, spooling large brigades into
  + * a tempfile bucket according to the environment's max_brigade
  + * setting- see apreq_env_max_brigade().
  + * @param env Environment.
  + * @param out Resulting brigade.
  + * @param in Brigade to append.
  + * @return APR_SUCCESS on success, error code otherwise.
  + */
   APREQ_DECLARE(apr_status_t) apreq_brigade_concat(void *env,
                                                    apr_bucket_brigade *out, 
                                                    apr_bucket_brigade *in);
   
   
  +/**
  + * Rfc822 Header parser.
  + */
   APREQ_DECLARE_PARSER(apreq_parse_headers);
  +
  +/**
  + * Rfc2396 application/x-www-form-urlencoded parser.
  + */
   APREQ_DECLARE_PARSER(apreq_parse_urlencoded);
  +
  +/**
  + * Rfc2388 multipart/form-data parser.
  + */
   APREQ_DECLARE_PARSER(apreq_parse_multipart);
   
  -APREQ_DECLARE(apreq_parser_t *) apreq_make_parser(apr_pool_t *pool,
  -                                                  const char *enctype,
  -                                                  APREQ_DECLARE_PARSER(*parser),
  -                                                  apreq_hook_t *hook,
  -                                                  void *ctx);
  -
  -APREQ_DECLARE(apreq_hook_t *) apreq_make_hook(apr_pool_t *pool,
  -                                              APREQ_DECLARE_HOOK(*hook),
  -                                              apreq_hook_t *next,
  -                                              void *ctx);
  +/**
  + * Construct a parser.
  + *
  + * @param pool Pool used to allocate the parser.
  + * @param enctype Content-type that this parser can deal with.
  + * @param parser The parser function.
  + * @param hook Hooks to asssociate this parser with.
  + * @param ctx Parser's internal scratch pad.
  + * @return New parser.
  + */
  +APREQ_DECLARE(apreq_parser_t *)
  +        apreq_make_parser(apr_pool_t *pool,
  +                          const char *enctype,
  +                          apr_status_t (*parser) APREQ_PARSER_ARGS,
  +                          apreq_hook_t *hook,
  +                          void *ctx);
   
  -APREQ_DECLARE(apr_status_t)apreq_add_hook(apreq_parser_t *p, 
  -                                          apreq_hook_t *h);
  +/**
  + * Construct a hook.
  + *
  + * @param Pool used to allocate the hook.
  + * @param hook The hook function.
  + * @param next List of other hooks for this hook to call on.
  + * @param ctx Hook's internal scratch pad.
  + * @return New hook.
  + */
  +APREQ_DECLARE(apreq_hook_t *)
  +        apreq_make_hook(apr_pool_t *pool,
  +                        apr_status_t (*hook) APREQ_HOOK_ARGS,
  +                        apreq_hook_t *next,
  +                        void *ctx);
   
  -APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env, apreq_hook_t *hook);
  +/**
  + * Add a new hook to the end of the parser's hook list.
  + *
  + * @param p Parser.
  + * @param h Hook to append.
  + */
  +APREQ_DECLARE(void) apreq_add_hook(apreq_parser_t *p, 
  +                                   apreq_hook_t *h);
  +
  +/**
  + * Create the default parser associated with the
  + * current request's Content-Type (if possible).
  + * @param env The current environment.
  + * @param hook Hook(s) to add to the parser.
  + * @return New parser, NULL if the Content-Type is
  + * unrecognized.  apreq_parser() currently recognizes
  + * APREQ_URL_ENCTYPE and APREQ_MFD_ENCTYPE.
  + *
  + * @param env The current environment.
  + * @param hook Additional hooks to supply the parser with.
  + * @return The built-in parser; NULL if the environment's
  + * Content-Type is unrecognized.
  + */
  +APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env,
  +                                            apreq_hook_t *hook);
   
   /** @} */
   #ifdef __cplusplus
  
  
  
  1.45      +16 -18    httpd-apreq-2/src/apreq_parsers.c
  
  Index: apreq_parsers.c
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.c,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -u -r1.44 -r1.45
  --- apreq_parsers.c	30 Apr 2004 05:08:35 -0000	1.44
  +++ apreq_parsers.c	4 Jun 2004 22:02:11 -0000	1.45
  @@ -31,11 +31,12 @@
   #define CRLF    "\015\012"
   #endif
   
  -APREQ_DECLARE(apreq_parser_t *) apreq_make_parser(apr_pool_t *pool,
  -                                                  const char *enctype,
  -                                                  APREQ_DECLARE_PARSER(*parser),
  -                                                  apreq_hook_t *hook,
  -                                                  void *ctx)
  +APREQ_DECLARE(apreq_parser_t *)
  +    apreq_make_parser(apr_pool_t *pool,
  +                      const char *enctype,
  +                      apr_status_t (*parser) APREQ_PARSER_ARGS,
  +                      apreq_hook_t *hook,
  +                      void *ctx)
   {
       apreq_parser_t *p = apr_palloc(pool, sizeof *p);
       p->enctype = apr_pstrdup(pool,enctype);
  @@ -45,10 +46,11 @@
       return p;
   }
   
  -APREQ_DECLARE(apreq_hook_t *) apreq_make_hook(apr_pool_t *pool,
  -                                              APREQ_DECLARE_HOOK(*hook),
  -                                              apreq_hook_t *next,
  -                                              void *ctx)
  +APREQ_DECLARE(apreq_hook_t *)
  +    apreq_make_hook(apr_pool_t *pool,
  +                    apr_status_t (*hook) APREQ_HOOK_ARGS,
  +                    apreq_hook_t *next,
  +                    void *ctx)
   {
       apreq_hook_t *h = apr_palloc(pool, sizeof *h);
       h->hook = hook;
  @@ -58,20 +60,16 @@
   }
   
   
  -APREQ_DECLARE(apr_status_t)apreq_add_hook(apreq_parser_t *p, 
  -                                          apreq_hook_t *h)
  +APREQ_DECLARE(void) apreq_add_hook(apreq_parser_t *p, 
  +                                   apreq_hook_t *h)
   {
       apreq_hook_t *last = h;
   
  -    if (p == NULL || h == NULL)
  -        return APR_EINIT;
  -
       while (last->next)
           last = last->next;
   
       last->next = p->hook;
       p->hook = h;
  -    return APR_SUCCESS;
   }
   
   APREQ_DECLARE(apreq_parser_t *)apreq_parser(void *env, apreq_hook_t *hook)
  @@ -839,7 +837,7 @@
               if (ctx->info == NULL)
                   ctx->info = apr_table_make(pool, APREQ_NELTS);
   
  -            s = apreq_run_parser(ctx->hdr_parser, env, ctx->info, bb);
  +            s = APREQ_RUN_PARSER(ctx->hdr_parser, env, ctx->info, bb);
   
               if (s != APR_SUCCESS)
                   return (s == APR_EOF) ? APR_SUCCESS : s;
  @@ -984,7 +982,7 @@
   
               case APR_INCOMPLETE:
                   if (parser->hook) {
  -                    s = apreq_run_hook(parser->hook, env, param, ctx->bb);
  +                    s = APREQ_RUN_HOOK(parser->hook, env, param, ctx->bb);
                       if (s != APR_INCOMPLETE && s != APR_SUCCESS)
                           return s;
                   }
  @@ -996,7 +994,7 @@
                       apr_bucket *eos = 
                           apr_bucket_eos_create(ctx->bb->bucket_alloc);
                       APR_BRIGADE_INSERT_TAIL(ctx->bb, eos);
  -                    s = apreq_run_hook(parser->hook, env, param, ctx->bb);
  +                    s = APREQ_RUN_HOOK(parser->hook, env, param, ctx->bb);
                       apr_bucket_delete(eos);
                       if (s != APR_SUCCESS)
                           return s;
  
  
  
  1.9       +1 -1      httpd-apreq-2/src/apreq_version.h
  
  Index: apreq_version.h
  ===================================================================
  RCS file: /home/cvs/httpd-apreq-2/src/apreq_version.h,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- apreq_version.h	24 Mar 2004 08:22:48 -0000	1.8
  +++ apreq_version.h	4 Jun 2004 22:02:11 -0000	1.9
  @@ -60,7 +60,7 @@
   #define APREQ_MINOR_VERSION       0
   
   /** patch level */
  -#define APREQ_PATCH_VERSION       5
  +#define APREQ_PATCH_VERSION       6
   
   /** 
    *  This symbol is defined for internal, "development" copies of libapreq.
  
  
  

Mime
View raw message