Annotation of win32/apache22/include/util_filter.h, revision 1.1
1.1 ! moko 1: /* Licensed to the Apache Software Foundation (ASF) under one or more
! 2: * contributor license agreements. See the NOTICE file distributed with
! 3: * this work for additional information regarding copyright ownership.
! 4: * The ASF licenses this file to You under the Apache License, Version 2.0
! 5: * (the "License"); you may not use this file except in compliance with
! 6: * the License. You may obtain a copy of the License at
! 7: *
! 8: * http://www.apache.org/licenses/LICENSE-2.0
! 9: *
! 10: * Unless required by applicable law or agreed to in writing, software
! 11: * distributed under the License is distributed on an "AS IS" BASIS,
! 12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! 13: * See the License for the specific language governing permissions and
! 14: * limitations under the License.
! 15: */
! 16:
! 17: /**
! 18: * @file util_filter.h
! 19: * @brief Apache filter library
! 20: */
! 21:
! 22: #ifndef AP_FILTER_H
! 23: #define AP_FILTER_H
! 24:
! 25: #include "apr.h"
! 26: #include "apr_buckets.h"
! 27:
! 28: #include "httpd.h"
! 29:
! 30: #if APR_HAVE_STDARG_H
! 31: #include <stdarg.h>
! 32: #endif
! 33:
! 34: #ifdef __cplusplus
! 35: extern "C" {
! 36: #endif
! 37:
! 38: /** Returned by the bottom-most filter if no data was written.
! 39: * @see ap_pass_brigade(). */
! 40: #define AP_NOBODY_WROTE -1
! 41: /** Returned by the bottom-most filter if no data was read.
! 42: * @see ap_get_brigade(). */
! 43: #define AP_NOBODY_READ -2
! 44: /** Returned when?? @bug find out when! */
! 45: #define AP_FILTER_ERROR -3
! 46:
! 47: /**
! 48: * @brief input filtering modes
! 49: */
! 50: typedef enum {
! 51: /** The filter should return at most readbytes data. */
! 52: AP_MODE_READBYTES,
! 53: /** The filter should return at most one line of CRLF data.
! 54: * (If a potential line is too long or no CRLF is found, the
! 55: * filter may return partial data).
! 56: */
! 57: AP_MODE_GETLINE,
! 58: /** The filter should implicitly eat any CRLF pairs that it sees. */
! 59: AP_MODE_EATCRLF,
! 60: /** The filter read should be treated as speculative and any returned
! 61: * data should be stored for later retrieval in another mode. */
! 62: AP_MODE_SPECULATIVE,
! 63: /** The filter read should be exhaustive and read until it can not
! 64: * read any more.
! 65: * Use this mode with extreme caution.
! 66: */
! 67: AP_MODE_EXHAUSTIVE,
! 68: /** The filter should initialize the connection if needed,
! 69: * NNTP or FTP over SSL for example.
! 70: */
! 71: AP_MODE_INIT
! 72: } ap_input_mode_t;
! 73:
! 74: /**
! 75: * @defgroup APACHE_CORE_FILTER Filter Chain
! 76: * @ingroup APACHE_CORE
! 77: *
! 78: * Filters operate using a "chaining" mechanism. The filters are chained
! 79: * together into a sequence. When output is generated, it is passed through
! 80: * each of the filters on this chain, until it reaches the end (or "bottom")
! 81: * and is placed onto the network.
! 82: *
! 83: * The top of the chain, the code generating the output, is typically called
! 84: * a "content generator." The content generator's output is fed into the
! 85: * filter chain using the standard Apache output mechanisms: ap_rputs(),
! 86: * ap_rprintf(), ap_rwrite(), etc.
! 87: *
! 88: * Each filter is defined by a callback. This callback takes the output from
! 89: * the previous filter (or the content generator if there is no previous
! 90: * filter), operates on it, and passes the result to the next filter in the
! 91: * chain. This pass-off is performed using the ap_fc_* functions, such as
! 92: * ap_fc_puts(), ap_fc_printf(), ap_fc_write(), etc.
! 93: *
! 94: * When content generation is complete, the system will pass an "end of
! 95: * stream" marker into the filter chain. The filters will use this to flush
! 96: * out any internal state and to detect incomplete syntax (for example, an
! 97: * unterminated SSI directive).
! 98: */
! 99:
! 100: /* forward declare the filter type */
! 101: typedef struct ap_filter_t ap_filter_t;
! 102:
! 103: /**
! 104: * @name Filter callbacks
! 105: *
! 106: * This function type is used for filter callbacks. It will be passed a
! 107: * pointer to "this" filter, and a "bucket" containing the content to be
! 108: * filtered.
! 109: *
! 110: * In filter->ctx, the callback will find its context. This context is
! 111: * provided here, so that a filter may be installed multiple times, each
! 112: * receiving its own per-install context pointer.
! 113: *
! 114: * Callbacks are associated with a filter definition, which is specified
! 115: * by name. See ap_register_input_filter() and ap_register_output_filter()
! 116: * for setting the association between a name for a filter and its
! 117: * associated callback (and other information).
! 118: *
! 119: * If the initialization function argument passed to the registration
! 120: * functions is non-NULL, it will be called iff the filter is in the input
! 121: * or output filter chains and before any data is generated to allow the
! 122: * filter to prepare for processing.
! 123: *
! 124: * The *bucket structure (and all those referenced by ->next and ->prev)
! 125: * should be considered "const". The filter is allowed to modify the
! 126: * next/prev to insert/remove/replace elements in the bucket list, but
! 127: * the types and values of the individual buckets should not be altered.
! 128: *
! 129: * For the input and output filters, the return value of a filter should be
! 130: * an APR status value. For the init function, the return value should
! 131: * be an HTTP error code or OK if it was successful.
! 132: *
! 133: * @ingroup filter
! 134: * @{
! 135: */
! 136: typedef apr_status_t (*ap_out_filter_func)(ap_filter_t *f,
! 137: apr_bucket_brigade *b);
! 138: typedef apr_status_t (*ap_in_filter_func)(ap_filter_t *f,
! 139: apr_bucket_brigade *b,
! 140: ap_input_mode_t mode,
! 141: apr_read_type_e block,
! 142: apr_off_t readbytes);
! 143: typedef int (*ap_init_filter_func)(ap_filter_t *f);
! 144:
! 145: typedef union ap_filter_func {
! 146: ap_out_filter_func out_func;
! 147: ap_in_filter_func in_func;
! 148: } ap_filter_func;
! 149:
! 150: /** @} */
! 151:
! 152: /**
! 153: * Filters have different types/classifications. These are used to group
! 154: * and sort the filters to properly sequence their operation.
! 155: *
! 156: * The types have a particular sort order, which allows us to insert them
! 157: * into the filter chain in a determistic order. Within a particular grouping,
! 158: * the ordering is equivalent to the order of calls to ap_add_*_filter().
! 159: */
! 160: typedef enum {
! 161: /** These filters are used to alter the content that is passed through
! 162: * them. Examples are SSI or PHP. */
! 163: AP_FTYPE_RESOURCE = 10,
! 164: /** These filters are used to alter the content as a whole, but after all
! 165: * AP_FTYPE_RESOURCE filters are executed. These filters should not
! 166: * change the content-type. An example is deflate. */
! 167: AP_FTYPE_CONTENT_SET = 20,
! 168: /** These filters are used to handle the protocol between server and
! 169: * client. Examples are HTTP and POP. */
! 170: AP_FTYPE_PROTOCOL = 30,
! 171: /** These filters implement transport encodings (e.g., chunking). */
! 172: AP_FTYPE_TRANSCODE = 40,
! 173: /** These filters will alter the content, but in ways that are
! 174: * more strongly associated with the connection. Examples are
! 175: * splitting an HTTP connection into multiple requests and
! 176: * buffering HTTP responses across multiple requests.
! 177: *
! 178: * It is important to note that these types of filters are not
! 179: * allowed in a sub-request. A sub-request's output can certainly
! 180: * be filtered by ::AP_FTYPE_RESOURCE filters, but all of the "final
! 181: * processing" is determined by the main request. */
! 182: AP_FTYPE_CONNECTION = 50,
! 183: /** These filters don't alter the content. They are responsible for
! 184: * sending/receiving data to/from the client. */
! 185: AP_FTYPE_NETWORK = 60
! 186: } ap_filter_type;
! 187:
! 188: /**
! 189: * This is the request-time context structure for an installed filter (in
! 190: * the output filter chain). It provides the callback to use for filtering,
! 191: * the request this filter is associated with (which is important when
! 192: * an output chain also includes sub-request filters), the context for this
! 193: * installed filter, and the filter ordering/chaining fields.
! 194: *
! 195: * Filter callbacks are free to use ->ctx as they please, to store context
! 196: * during the filter process. Generally, this is superior over associating
! 197: * the state directly with the request. A callback should not change any of
! 198: * the other fields.
! 199: */
! 200:
! 201: typedef struct ap_filter_rec_t ap_filter_rec_t;
! 202: typedef struct ap_filter_provider_t ap_filter_provider_t;
! 203:
! 204: /**
! 205: * @brief This structure is used for recording information about the
! 206: * registered filters. It associates a name with the filter's callback
! 207: * and filter type.
! 208: *
! 209: * At the moment, these are simply linked in a chain, so a ->next pointer
! 210: * is available.
! 211: *
! 212: * It is used for any filter that can be inserted in the filter chain.
! 213: * This may be either a httpd-2.0 filter or a mod_filter harness.
! 214: * In the latter case it contains dispatch, provider and protocol information.
! 215: * In the former case, the new fields (from dispatch) are ignored.
! 216: */
! 217: struct ap_filter_rec_t {
! 218: /** The registered name for this filter */
! 219: const char *name;
! 220:
! 221: /** The function to call when this filter is invoked. */
! 222: ap_filter_func filter_func;
! 223:
! 224: /** The function to call directly before the handlers are invoked
! 225: * for a request. The init function is called once directly
! 226: * before running the handlers for a request or subrequest. The
! 227: * init function is never called for a connection filter (with
! 228: * ftype >= AP_FTYPE_CONNECTION). Any use of this function for
! 229: * filters for protocols other than HTTP is specified by the
! 230: * module supported that protocol.
! 231: */
! 232: ap_init_filter_func filter_init_func;
! 233:
! 234: /** The type of filter, either AP_FTYPE_CONTENT or AP_FTYPE_CONNECTION.
! 235: * An AP_FTYPE_CONTENT filter modifies the data based on information
! 236: * found in the content. An AP_FTYPE_CONNECTION filter modifies the
! 237: * data based on the type of connection.
! 238: */
! 239: ap_filter_type ftype;
! 240:
! 241: /** The next filter_rec in the list */
! 242: struct ap_filter_rec_t *next;
! 243:
! 244: /** Providers for this filter */
! 245: ap_filter_provider_t *providers;
! 246:
! 247: /** Trace level for this filter */
! 248: int debug;
! 249:
! 250: /** Protocol flags for this filter */
! 251: unsigned int proto_flags;
! 252: };
! 253:
! 254: /**
! 255: * @brief The representation of a filter chain.
! 256: *
! 257: * Each request has a list
! 258: * of these structures which are called in turn to filter the data. Sub
! 259: * requests get an exact copy of the main requests filter chain.
! 260: */
! 261: struct ap_filter_t {
! 262: /** The internal representation of this filter. This includes
! 263: * the filter's name, type, and the actual function pointer.
! 264: */
! 265: ap_filter_rec_t *frec;
! 266:
! 267: /** A place to store any data associated with the current filter */
! 268: void *ctx;
! 269:
! 270: /** The next filter in the chain */
! 271: ap_filter_t *next;
! 272:
! 273: /** The request_rec associated with the current filter. If a sub-request
! 274: * adds filters, then the sub-request is the request associated with the
! 275: * filter.
! 276: */
! 277: request_rec *r;
! 278:
! 279: /** The conn_rec associated with the current filter. This is analogous
! 280: * to the request_rec, except that it is used for input filtering.
! 281: */
! 282: conn_rec *c;
! 283: };
! 284:
! 285: /**
! 286: * Get the current bucket brigade from the next filter on the filter
! 287: * stack. The filter returns an apr_status_t value. If the bottom-most
! 288: * filter doesn't read from the network, then ::AP_NOBODY_READ is returned.
! 289: * The bucket brigade will be empty when there is nothing left to get.
! 290: * @param filter The next filter in the chain
! 291: * @param bucket The current bucket brigade. The original brigade passed
! 292: * to ap_get_brigade() must be empty.
! 293: * @param mode The way in which the data should be read
! 294: * @param block How the operations should be performed
! 295: * ::APR_BLOCK_READ, ::APR_NONBLOCK_READ
! 296: * @param readbytes How many bytes to read from the next filter.
! 297: */
! 298: AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *filter,
! 299: apr_bucket_brigade *bucket,
! 300: ap_input_mode_t mode,
! 301: apr_read_type_e block,
! 302: apr_off_t readbytes);
! 303:
! 304: /**
! 305: * Pass the current bucket brigade down to the next filter on the filter
! 306: * stack. The filter returns an apr_status_t value. If the bottom-most
! 307: * filter doesn't write to the network, then ::AP_NOBODY_WROTE is returned.
! 308: * The caller relinquishes ownership of the brigade.
! 309: * @param filter The next filter in the chain
! 310: * @param bucket The current bucket brigade
! 311: */
! 312: AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *filter,
! 313: apr_bucket_brigade *bucket);
! 314:
! 315: /**
! 316: * This function is used to register an input filter with the system.
! 317: * After this registration is performed, then a filter may be added
! 318: * into the filter chain by using ap_add_input_filter() and simply
! 319: * specifying the name.
! 320: *
! 321: * @param name The name to attach to the filter function
! 322: * @param filter_func The filter function to name
! 323: * @param filter_init The function to call before the filter handlers
! 324: are invoked
! 325: * @param ftype The type of filter function, either ::AP_FTYPE_CONTENT or
! 326: * ::AP_FTYPE_CONNECTION
! 327: * @see add_input_filter()
! 328: */
! 329: AP_DECLARE(ap_filter_rec_t *) ap_register_input_filter(const char *name,
! 330: ap_in_filter_func filter_func,
! 331: ap_init_filter_func filter_init,
! 332: ap_filter_type ftype);
! 333:
! 334: /**
! 335: * This function is used to register an output filter with the system.
! 336: * After this registration is performed, then a filter may be added
! 337: * into the filter chain by using ap_add_output_filter() and simply
! 338: * specifying the name. It may also be used as a provider under mod_filter.
! 339: * This is (equivalent to) ap_register_output_filter_protocol with
! 340: * proto_flags=0, and is retained for back-compatibility with 2.0 modules.
! 341: *
! 342: * @param name The name to attach to the filter function
! 343: * @param filter_func The filter function to name
! 344: * @param filter_init The function to call before the filter handlers
! 345: * are invoked
! 346: * @param ftype The type of filter function, either ::AP_FTYPE_CONTENT or
! 347: * ::AP_FTYPE_CONNECTION
! 348: * @see ap_add_output_filter()
! 349: */
! 350: AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name,
! 351: ap_out_filter_func filter_func,
! 352: ap_init_filter_func filter_init,
! 353: ap_filter_type ftype);
! 354:
! 355: /* For httpd-2.2 I suggest replacing the above with
! 356: #define ap_register_output_filter(name,ffunc,init,ftype) \
! 357: ap_register_output_filter_protocol(name,ffunc,init,ftype,0)
! 358: */
! 359:
! 360: /**
! 361: * This function is used to register an output filter with the system.
! 362: * After this registration is performed, then a filter may be added
! 363: * into the filter chain by using ap_add_output_filter() and simply
! 364: * specifying the name. It may also be used as a provider under mod_filter.
! 365: *
! 366: * @param name The name to attach to the filter function
! 367: * @param filter_func The filter function to name
! 368: * @param filter_init The function to call before the filter handlers
! 369: * are invoked
! 370: * @param ftype The type of filter function, either ::AP_FTYPE_CONTENT or
! 371: * ::AP_FTYPE_CONNECTION
! 372: * @param proto_flags Protocol flags: logical OR of AP_FILTER_PROTO_* bits
! 373: * @see ap_add_output_filter()
! 374: */
! 375: AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter_protocol(
! 376: const char *name,
! 377: ap_out_filter_func filter_func,
! 378: ap_init_filter_func filter_init,
! 379: ap_filter_type ftype,
! 380: unsigned int proto_flags);
! 381:
! 382: /**
! 383: * Adds a named filter into the filter chain on the specified request record.
! 384: * The filter will be installed with the specified context pointer.
! 385: *
! 386: * Filters added in this way will always be placed at the end of the filters
! 387: * that have the same type (thus, the filters have the same order as the
! 388: * calls to ap_add_filter). If the current filter chain contains filters
! 389: * from another request, then this filter will be added before those other
! 390: * filters.
! 391: *
! 392: * To re-iterate that last comment. This function is building a FIFO
! 393: * list of filters. Take note of that when adding your filter to the chain.
! 394: *
! 395: * @param name The name of the filter to add
! 396: * @param ctx Context data to provide to the filter
! 397: * @param r The request to add this filter for (or NULL if it isn't associated with a request)
! 398: * @param c The connection to add the fillter for
! 399: */
! 400: AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
! 401: request_rec *r, conn_rec *c);
! 402:
! 403: /**
! 404: * Variant of ap_add_input_filter() that accepts a registered filter handle
! 405: * (as returned by ap_register_input_filter()) rather than a filter name
! 406: *
! 407: * @param f The filter handle to add
! 408: * @param ctx Context data to provide to the filter
! 409: * @param r The request to add this filter for (or NULL if it isn't associated with a request)
! 410: * @param c The connection to add the fillter for
! 411: */
! 412: AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f,
! 413: void *ctx,
! 414: request_rec *r,
! 415: conn_rec *c);
! 416:
! 417: /**
! 418: * Returns the filter handle for use with ap_add_input_filter_handle.
! 419: *
! 420: * @param name The filter name to look up
! 421: */
! 422: AP_DECLARE(ap_filter_rec_t *) ap_get_input_filter_handle(const char *name);
! 423:
! 424: /**
! 425: * Add a filter to the current request. Filters are added in a FIFO manner.
! 426: * The first filter added will be the first filter called.
! 427: * @param name The name of the filter to add
! 428: * @param ctx Context data to set in the filter
! 429: * @param r The request to add this filter for (or NULL if it isn't associated with a request)
! 430: * @param c The connection to add this filter for
! 431: */
! 432: AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx,
! 433: request_rec *r, conn_rec *c);
! 434:
! 435: /**
! 436: * Variant of ap_add_output_filter() that accepts a registered filter handle
! 437: * (as returned by ap_register_output_filter()) rather than a filter name
! 438: *
! 439: * @param f The filter handle to add
! 440: * @param r The request to add this filter for (or NULL if it isn't associated with a request)
! 441: * @param c The connection to add the fillter for
! 442: */
! 443: AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f,
! 444: void *ctx,
! 445: request_rec *r,
! 446: conn_rec *c);
! 447:
! 448: /**
! 449: * Returns the filter handle for use with ap_add_output_filter_handle.
! 450: *
! 451: * @param name The filter name to look up
! 452: */
! 453: AP_DECLARE(ap_filter_rec_t *) ap_get_output_filter_handle(const char *name);
! 454:
! 455: /**
! 456: * Remove an input filter from either the request or connection stack
! 457: * it is associated with.
! 458: * @param f The filter to remove
! 459: */
! 460:
! 461: AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f);
! 462:
! 463: /**
! 464: * Remove an output filter from either the request or connection stack
! 465: * it is associated with.
! 466: * @param f The filter to remove
! 467: */
! 468:
! 469: AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f);
! 470:
! 471: /* The next two filters are for abstraction purposes only. They could be
! 472: * done away with, but that would require that we break modules if we ever
! 473: * want to change our filter registration method. The basic idea, is that
! 474: * all filters have a place to store data, the ctx pointer. These functions
! 475: * fill out that pointer with a bucket brigade, and retrieve that data on
! 476: * the next call. The nice thing about these functions, is that they
! 477: * automatically concatenate the bucket brigades together for you. This means
! 478: * that if you have already stored a brigade in the filters ctx pointer, then
! 479: * when you add more it will be tacked onto the end of that brigade. When
! 480: * you retrieve data, if you pass in a bucket brigade to the get function,
! 481: * it will append the current brigade onto the one that you are retrieving.
! 482: */
! 483:
! 484: /**
! 485: * prepare a bucket brigade to be setaside. If a different brigade was
! 486: * set-aside earlier, then the two brigades are concatenated together.
! 487: * @param f The current filter
! 488: * @param save_to The brigade that was previously set-aside. Regardless, the
! 489: * new bucket brigade is returned in this location.
! 490: * @param b The bucket brigade to save aside. This brigade is always empty
! 491: * on return
! 492: * @param p Ensure that all data in the brigade lives as long as this pool
! 493: */
! 494: AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f,
! 495: apr_bucket_brigade **save_to,
! 496: apr_bucket_brigade **b, apr_pool_t *p);
! 497:
! 498: /**
! 499: * Flush function for apr_brigade_* calls. This calls ap_pass_brigade
! 500: * to flush the brigade if the brigade buffer overflows.
! 501: * @param bb The brigade to flush
! 502: * @param ctx The filter to pass the brigade to
! 503: * @note this function has nothing to do with FLUSH buckets. It is simply
! 504: * a way to flush content out of a brigade and down a filter stack.
! 505: */
! 506: AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb,
! 507: void *ctx);
! 508:
! 509: /**
! 510: * Flush the current brigade down the filter stack.
! 511: * @param f The filter we are passing to
! 512: * @param bb The brigade to flush
! 513: */
! 514: AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb);
! 515:
! 516: /**
! 517: * Write a buffer for the current filter, buffering if possible.
! 518: * @param f the filter we are writing to
! 519: * @param bb The brigade to buffer into
! 520: * @param data The data to write
! 521: * @param nbyte The number of bytes in the data
! 522: */
! 523: #define ap_fwrite(f, bb, data, nbyte) \
! 524: apr_brigade_write(bb, ap_filter_flush, f, data, nbyte)
! 525:
! 526: /**
! 527: * Write a buffer for the current filter, buffering if possible.
! 528: * @param f the filter we are writing to
! 529: * @param bb The brigade to buffer into
! 530: * @param str The string to write
! 531: */
! 532: #define ap_fputs(f, bb, str) \
! 533: apr_brigade_puts(bb, ap_filter_flush, f, str)
! 534:
! 535: /**
! 536: * Write a character for the current filter, buffering if possible.
! 537: * @param f the filter we are writing to
! 538: * @param bb The brigade to buffer into
! 539: * @param c The character to write
! 540: */
! 541: #define ap_fputc(f, bb, c) \
! 542: apr_brigade_putc(bb, ap_filter_flush, f, c)
! 543:
! 544: /**
! 545: * Write an unspecified number of strings to the current filter
! 546: * @param f the filter we are writing to
! 547: * @param bb The brigade to buffer into
! 548: * @param ... The strings to write
! 549: */
! 550: AP_DECLARE_NONSTD(apr_status_t) ap_fputstrs(ap_filter_t *f,
! 551: apr_bucket_brigade *bb,
! 552: ...);
! 553:
! 554: /**
! 555: * Output data to the filter in printf format
! 556: * @param f the filter we are writing to
! 557: * @param bb The brigade to buffer into
! 558: * @param fmt The format string
! 559: * @param ... The argumets to use to fill out the format string
! 560: */
! 561: AP_DECLARE_NONSTD(apr_status_t) ap_fprintf(ap_filter_t *f,
! 562: apr_bucket_brigade *bb,
! 563: const char *fmt,
! 564: ...)
! 565: __attribute__((format(printf,3,4)));
! 566:
! 567: /**
! 568: * set protocol requirements for an output content filter
! 569: * (only works with AP_FTYPE_RESOURCE and AP_FTYPE_CONTENT_SET)
! 570: * @param f the filter in question
! 571: * @param proto_flags Logical OR of AP_FILTER_PROTO_* bits
! 572: */
! 573: AP_DECLARE(void) ap_filter_protocol(ap_filter_t* f, unsigned int proto_flags);
! 574:
! 575: /** Filter changes contents (so invalidating checksums/etc) */
! 576: #define AP_FILTER_PROTO_CHANGE 0x1
! 577:
! 578: /** Filter changes length of contents (so invalidating content-length/etc) */
! 579: #define AP_FILTER_PROTO_CHANGE_LENGTH 0x2
! 580:
! 581: /** Filter requires complete input and can't work on byteranges */
! 582: #define AP_FILTER_PROTO_NO_BYTERANGE 0x4
! 583:
! 584: /** Filter should not run in a proxy */
! 585: #define AP_FILTER_PROTO_NO_PROXY 0x8
! 586:
! 587: /** Filter makes output non-cacheable */
! 588: #define AP_FILTER_PROTO_NO_CACHE 0x10
! 589:
! 590: /** Filter is incompatible with "Cache-Control: no-transform" */
! 591: #define AP_FILTER_PROTO_TRANSFORM 0x20
! 592:
! 593: #ifdef __cplusplus
! 594: }
! 595: #endif
! 596:
! 597: #endif /* !AP_FILTER_H */
E-mail: