cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2004-09-29 Thread stas
stas2004/09/29 20:45:11

  Modified:src/modules/perl modperl_filter.c
  Log:
  space cleanup
  
  Revision  ChangesPath
  1.100 +1 -1  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.99
  retrieving revision 1.100
  diff -u -u -r1.99 -r1.100
  --- modperl_filter.c  30 Sep 2004 03:39:24 -  1.99
  +++ modperl_filter.c  30 Sep 2004 03:45:10 -  1.100
  @@ -321,7 +321,7 @@
   #ifdef MP_DEBUG
   apr_pool_tag(temp_pool, "mod_perl temp filter");
   #endif
  -
  +
   filter->temp_pool = temp_pool;
   filter->mode  = mode;
   filter->f = f;
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2004-09-09 Thread stas
stas2004/09/09 08:17:21

  Modified:src/modules/perl modperl_filter.c
  Log:
  log the filter failure error message only once
  
  Revision  ChangesPath
  1.98  +5 -12 modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.97
  retrieving revision 1.98
  diff -u -u -r1.97 -r1.98
  --- modperl_filter.c  9 Sep 2004 15:08:03 -   1.97
  +++ modperl_filter.c  9 Sep 2004 15:17:20 -   1.98
  @@ -66,18 +66,11 @@
  );   \
   }
   
  -/* Restore previously saved value of $@, warning if a new error was
  - * generated */
  +/* Restore previously saved value of [EMAIL PROTECTED] if there was a filter error
  + * it'd have been logged by modperl_errsv call following
  + * modperl_callback */
   #define MP_FILTER_RESTORE_ERRSV(tmpsv)  \
   if (tmpsv) {\
  -if (SvTRUE(ERRSV)) {\
  -Perl_warn(aTHX_ "%s", SvPVX(ERRSV));\
  -MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT   \
  -   "error: %s", \
  -MP_FILTER_NAME(filter->f),  \
  -SvPVX(ERRSV)\
  -);  \
  -}   \
   sv_setsv(ERRSV, tmpsv); \
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT   \
  "Restoring [EMAIL PROTECTED]'%s'", \
  @@ -542,13 +535,13 @@
"Apache::Filter");
   }
   
  +MP_FILTER_RESTORE_ERRSV(errsv);
  + 
   MP_INTERP_PUTBACK(interp);
   
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  "return: %d\n", modperl_handler_name(handler), status);
   
  -MP_FILTER_RESTORE_ERRSV(errsv);
  - 
   return status;
   }
   
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2004-08-18 Thread stas
stas2004/08/18 15:45:46

  Modified:src/modules/perl modperl_filter.c
  Log:
  polish (no code change)
  
  Revision  ChangesPath
  1.96  +35 -33modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.95
  retrieving revision 1.96
  diff -u -u -r1.95 -r1.96
  --- modperl_filter.c  18 Aug 2004 22:05:16 -  1.95
  +++ modperl_filter.c  18 Aug 2004 22:45:46 -  1.96
  @@ -19,25 +19,26 @@
   
   #define MP_FILTER_NAME_FORMAT "   %s\n\n\t"
   
  -#define MP_FILTER_NAME(f) \
  -(is_modperl_filter(f) \
  -? modperl_handler_name(((modperl_filter_ctx_t *)(f)->ctx)->handler) \
  -: (f)->frec->name)
  +#define MP_FILTER_NAME(f)   \
  +(is_modperl_filter(f)   \
  + ? modperl_handler_name(\
  + ((modperl_filter_ctx_t *)(f)->ctx)->handler)   \
  + : (f)->frec->name)
   
  -#define MP_FILTER_TYPE(filter) \
  -(is_modperl_filter(filter->f) \
  +#define MP_FILTER_TYPE(filter) \
  +(is_modperl_filter(filter->f)  \
   ? ((modperl_filter_ctx_t *)(filter)->f->ctx)->handler->attrs & \
  -MP_FILTER_CONNECTION_HANDLER  ? "connection" : "request" \
  +MP_FILTER_CONNECTION_HANDLER  ? "connection" : "request"   \
   : "unknown")
   
  -#define MP_FILTER_MODE(filter) \
  +#define MP_FILTER_MODE(filter)  \
   (filter->mode == MP_INPUT_FILTER_MODE ? "input" : "output")
   
   #define MP_FILTER_POOL(f) f->r ? f->r->pool : f->c->pool
   
  -/* allocate wbucket memory using malloc and not request pools, since
  - * we may need many of these if the filter is invoked multiple
  - * times */
  +/* allocate wbucket memory using a sub-pool and not a ap_filter_t
  + * pool, since we may need many of these if the filter is invoked
  + * multiple times */
   #define WBUCKET_INIT(filter) \
   if (!filter->wbucket) {  \
   modperl_wbucket_t *wb =  \
  @@ -51,7 +52,7 @@
   filter->wbucket  = wb;   \
   }
   
  -#define FILTER_FREE(filter)\
  +#define FILTER_FREE(filter) \
   apr_pool_destroy(filter->temp_pool);
   
   /* Save the value of $@ if it was set */
  @@ -65,7 +66,8 @@
  );   \
   }
   
  -/* Restore previously saved value of $@, warning if a new error was generated */
  +/* Restore previously saved value of $@, warning if a new error was
  + * generated */
   #define MP_FILTER_RESTORE_ERRSV(tmpsv)  \
   if (tmpsv) {\
   if (SvTRUE(ERRSV)) {\
  @@ -323,18 +325,18 @@
   }
   filter = (modperl_filter_t *)apr_pcalloc(temp_pool, sizeof(*filter));
   
  -filter->mode = mode;
  -filter->f = f;
   filter->temp_pool = temp_pool;
  -filter->pool = p;
  -filter->wbucket = NULL;
  +filter->mode  = mode;
  +filter->f = f;
  +filter->pool  = p;
  +filter->wbucket   = NULL;
   
   if (mode == MP_INPUT_FILTER_MODE) {
  -filter->bb_in  = NULL;
  -filter->bb_out = bb;
  +filter->bb_in  = NULL;
  +filter->bb_out = bb;
   filter->input_mode = input_mode;
  -filter->block = block;
  -filter->readbytes = readbytes;
  +filter->block  = block;
  +filter->readbytes  = readbytes;
   }
   else {
   filter->bb_in  = bb;
  @@ -553,23 +555,23 @@
   
   /* unrolled APR_BRIGADE_FOREACH loop */
   
  -#define MP_FILTER_EMPTY(filter) \
  -APR_BRIGADE_EMPTY(filter->bb_in)
  +#define MP_FILTER_EMPTY(filter) \
  +APR_BRIGADE_EMPTY(filter->bb_in)
   
  -#define MP_FILTER_SENTINEL(filter) \
  -APR_BRIGADE_SENTINEL(filter->bb_in)
  +#define MP_FILTER_SENTINEL(filter)  \
  +APR_BRIGADE_SENTINEL(filter->bb_in)
   
  -#define MP_FILTER_FIRST(filter) \
  -APR_BRIGADE_FIRST(filter->bb_in)
  +#define MP_FILTER_FIRST(filter) \
  +APR_BRIGADE_FIRST(filter->bb_in)
   
  -#define MP_FILTER_NEXT(filter) \
  -APR_BUCKET_NEXT(filter->bucket)
  +#define MP_FILTER_NEXT(filter)  \
  +APR_BUCKET_NEXT(filter->bucket)
   
  -#define MP_FILTER_IS_EOS(filter) \
  -APR_BUCKET_IS_EOS(filter->bucket)
  +#define MP_FILTER_IS_EOS(filter)\
  +APR_BUCKET_IS_EOS(filter->bucket)
   
  -#define MP_FILTER_IS_FLUSH(filter) \
  -APR_BUCKET_IS_FLUSH(filter->bucket)
  +#define MP_FILTER_IS_FLUSH

cvs commit: modperl-2.0/src/modules/perl modperl_filter.c modperl_types.h

2004-08-18 Thread stas
stas2004/08/18 15:05:16

  Modified:.Changes
   src/modules/perl modperl_filter.c modperl_types.h
  Log:
  replace the memory allocation for modperl filter handlers to use a
  temporary subpool of the ap_filter_t object. previously using perl's
  safemalloc had problems on win32 (randonly my_perl == NULL)
  
  Revision  ChangesPath
  1.455 +4 -0  modperl-2.0/Changes
  
  Index: Changes
  ===
  RCS file: /home/cvs/modperl-2.0/Changes,v
  retrieving revision 1.454
  retrieving revision 1.455
  diff -u -u -r1.454 -r1.455
  --- Changes   18 Aug 2004 18:05:29 -  1.454
  +++ Changes   18 Aug 2004 22:05:16 -  1.455
  @@ -12,6 +12,10 @@
   
   =item 1.99_15-dev
   
  +replace the memory allocation for modperl filter handlers to use a
  +temporary subpool of the ap_filter_t object. previously using perl's
  +safemalloc had problems on win32 (randonly my_perl == NULL) [Stas]
  +
   Apache::Module remove_loaded_module re-added [Gozer]
   
   Disable Apache::HookRun::run_create_request -- it's already run
  
  
  
  1.95  +27 -17modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.94
  retrieving revision 1.95
  diff -u -u -r1.94 -r1.95
  --- modperl_filter.c  10 Aug 2004 00:38:35 -  1.94
  +++ modperl_filter.c  18 Aug 2004 22:05:16 -  1.95
  @@ -38,21 +38,21 @@
   /* allocate wbucket memory using malloc and not request pools, since
* we may need many of these if the filter is invoked multiple
* times */
  -#define WBUCKET_INIT(wb, p, next_filter)   \
  -if (!wb) { \
  -wb = (modperl_wbucket_t *)safemalloc(sizeof(*wb)); \
  -wb->pool= p;   \
  -wb->filters = &next_filter;\
  -wb->outcnt  = 0;   \
  -wb->r   = NULL;\
  -wb->header_parse = 0;  \
  +#define WBUCKET_INIT(filter) \
  +if (!filter->wbucket) {  \
  +modperl_wbucket_t *wb =  \
  +(modperl_wbucket_t *)apr_pcalloc(filter->temp_pool,  \
  + sizeof(*wb));   \
  +wb->pool = filter->pool; \
  +wb->filters  = &(filter->f->next);   \
  +wb->outcnt   = 0;\
  +wb->r= NULL; \
  +wb->header_parse = 0;\
  +filter->wbucket  = wb;   \
   }
   
   #define FILTER_FREE(filter)\
  -if (filter->wbucket) { \
  -safefree(filter->wbucket); \
  -}  \
  -safefree(filter);
  +apr_pool_destroy(filter->temp_pool);
   
   /* Save the value of $@ if it was set */
   #define MP_FILTER_SAVE_ERRSV(tmpsv) \
  @@ -306,17 +306,26 @@
apr_off_t readbytes)
   {
   apr_pool_t *p = MP_FILTER_POOL(f);
  +apr_pool_t *temp_pool;
   modperl_filter_t *filter;
   
   /* we can't allocate memory from the pool here, since potentially
* a filter can be called hundreds of times during the same
* request/connection resulting in enormous memory demands
  - * (sizeof(*filter)*number of invocations)
  + * (sizeof(*filter)*number of invocations). so we use a sub-pool
  + * which will get destroyed at the end of each modperl_filter
  + * invocation.
*/
  -Newz(0, filter, 1, modperl_filter_t);
  -
  +apr_status_t rv = apr_pool_create(&temp_pool, p);
  +if (rv != APR_SUCCESS) {
  +/* XXX: how do we handle the error? assert? */
  +return NULL;
  +}
  +filter = (modperl_filter_t *)apr_pcalloc(temp_pool, sizeof(*filter));
  +
   filter->mode = mode;
   filter->f = f;
  +filter->temp_pool = temp_pool;
   filter->pool = p;
   filter->wbucket = NULL;
   
  @@ -808,7 +817,7 @@
   filter->flush = 0;
   }
   
  -WBUCKET_INIT(filter->wbucket, filter->pool, filter->f->next);
  +WBUCKET_INIT(filter);
   filter->rc = modperl_wbucket_flush(filter->wbucket, add_flush_bucket);
   if (filter->rc != APR_SUCCESS) {
   return filter->rc;
  @@ -848,7 +857,8 @@
  const char *buf,
  apr_size_t *len)
   {
  -WBUCKET_INIT(filter->w

cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2004-06-01 Thread stas
stas2004/06/01 13:16:46

  Modified:src/modules/perl modperl_filter.c
  Log:
  check the return status in input filter read ap_get_brigade and throw
  exception if failed
  
  Revision  ChangesPath
  1.91  +7 -2  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.90
  retrieving revision 1.91
  diff -u -u -r1.90 -r1.91
  --- modperl_filter.c  19 May 2004 06:44:46 -  1.90
  +++ modperl_filter.c  1 Jun 2004 20:16:46 -   1.91
  @@ -692,11 +692,16 @@
   apr_size_t len = 0;
   
   if (!filter->bb_in) {
  +apr_status_t rc;
   /* This should be read only once per handler invocation! */
   filter->bb_in = apr_brigade_create(filter->pool,
  filter->f->c->bucket_alloc);
  -ap_get_brigade(filter->f->next, filter->bb_in,
  -   filter->input_mode, filter->block, filter->readbytes);
  +rc = ap_get_brigade(filter->f->next, filter->bb_in,
  +filter->input_mode, filter->block,
  +filter->readbytes);
  +if (!(rc == APR_SUCCESS || rc == APR_EOF)) {
  +modperl_croak(aTHX_ rc, "Apache::Filter::read"); 
  +}
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  "retrieving bb: 0x%lx\n",
  MP_FILTER_NAME(filter->f),
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2004-05-18 Thread stas
stas2004/05/18 23:44:46

  Modified:src/modules/perl modperl_filter.c
  Log:
  looks like we may have to explain to module writers how to write
  proper filters
  
  Revision  ChangesPath
  1.90  +8 -1  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.89
  retrieving revision 1.90
  diff -u -u -r1.89 -r1.90
  --- modperl_filter.c  13 May 2004 01:45:30 -  1.89
  +++ modperl_filter.c  19 May 2004 06:44:46 -  1.90
  @@ -164,8 +164,15 @@
   buf = body;
   }
   
  -bb = apr_brigade_create(wb->pool, ba);
  +/* this is a note for filter writers who may decide that there is
  + * a bug in mod_perl. We send a transient bucket. That means that
  + * this bucket can't be stored inside a filter without copying the
  + * data in it. This is done automatically by apr_bucket_setaside,
  + * which is written exactly for the purpose to make setaside
  + * operation transparent to the kind of bucket.
  + */
   bucket = apr_bucket_transient_create(buf, len, ba);
  +bb = apr_brigade_create(wb->pool, ba);
   APR_BRIGADE_INSERT_TAIL(bb, bucket);
   
   if (add_flush_bucket) {
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2004-05-12 Thread stas
stas2004/05/12 18:45:30

  Modified:src/modules/perl modperl_filter.c
  Log:
  - better tracing (show the actual data as in modperl_io_apache.c)
  - extra comments
  
  Revision  ChangesPath
  1.89  +28 -17modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.88
  retrieving revision 1.89
  diff -u -u -r1.88 -r1.89
  --- modperl_filter.c  4 May 2004 06:19:11 -   1.88
  +++ modperl_filter.c  13 May 2004 01:45:30 -  1.89
  @@ -139,8 +139,8 @@
   const char *body;
   int status;
   
  -MP_TRACE_f(MP_FUNC, "\n\n\tparsing headers: %d bytes [%s]\n", len,
  -   apr_pstrmemdup(wb->pool, buf, len));
  +MP_TRACE_f(MP_FUNC, "\n\n\tparsing headers: %db [%s]\n", len,
  +   MP_TRACE_STR_TRUNC(wb->pool, buf, len));
   
   status = modperl_cgi_header_parse(r, (char *)buf, &len, &body);
   
  @@ -176,9 +176,10 @@
   APR_BRIGADE_INSERT_TAIL(bb, bucket);
   }
   
  -MP_TRACE_f(MP_FUNC, "\n\n\twrite out: %d bytes\n"
  +MP_TRACE_f(MP_FUNC, "\n\n\twrite out: %db [%s]\n"
  "\t\tfrom %s\n\t\tto %s filter handler\n",
  len, 
  +   MP_TRACE_STR_TRUNC(wb->pool, buf, len),
  ((wb->r && wb->filters == &wb->r->output_filters)
  ? "response handler" : "current filter handler"),
  MP_FILTER_NAME(*(wb->filters)));
  @@ -589,17 +590,19 @@
   /*modperl_brigade_dump(filter->bb_in, stderr);*/
   
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  -   "wanted: %d bytes\n",
  +   "wanted: %db\n",
  MP_FILTER_NAME(filter->f),
  wanted);
   
   if (filter->remaining) {
   if (filter->remaining >= wanted) {
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  -   "eating and returning %d of "
  -   "remaining %d leftover bytes\n",
  +   "eating and returning %d [%s]\n\tof "
  +   "remaining %db\n",
  MP_FILTER_NAME(filter->f),
  -   wanted, filter->remaining);
  +   wanted,
  +   MP_TRACE_STR_TRUNC(filter->pool, filter->leftover, wanted),
  +   filter->remaining);
   sv_catpvn(buffer, filter->leftover, wanted);
   filter->leftover += wanted;
   filter->remaining -= wanted;
  @@ -607,7 +610,7 @@
   }
   else {
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  -   "eating remaining %d leftover bytes\n",
  +   "eating remaining %db\n",
  MP_FILTER_NAME(filter->f),
  filter->remaining);
   sv_catpvn(buffer, filter->leftover, filter->remaining);
  @@ -632,7 +635,7 @@
   if (filter->rc == APR_SUCCESS) {
   MP_TRACE_f(MP_FUNC,
  MP_FILTER_NAME_FORMAT
  -   "read in: %s bucket with %d bytes (0x%lx)\n",
  +   "read in: %s bucket with %db (0x%lx)\n",
  MP_FILTER_NAME(filter->f),
  filter->bucket->type->name,
  buf_len,
  @@ -665,9 +668,10 @@
   
   MP_TRACE_f(MP_FUNC,
  MP_FILTER_NAME_FORMAT
  -   "return: %d bytes from %d bucket%s (%d bytes leftover)\n",
  +   "return: %db from %d bucket%s [%s]\n\t(%db leftover)\n",
  MP_FILTER_NAME(filter->f),
  len, num_buckets, ((num_buckets == 1) ? "" : "s"),
  +   MP_TRACE_STR_TRUNC(filter->pool, SvPVX(buffer), len),
  filter->remaining);
   
   return len;
  @@ -785,11 +789,10 @@
   apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc;
   char *copy = apr_pmemdup(filter->pool, buf, *len);
   apr_bucket *bucket = apr_bucket_transient_create(copy, *len, ba);
  -/* MP_TRACE_f(MP_FUNC, "writing %d bytes: %s\n", *len, copy); */
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  -   "write out: %d bytes:\n",
  -   MP_FILTER_NAME(filter->f),
  -   *len);
  +   "write out: %db [%s]:\n",
  +   MP_FILTER_NAME(filter->f), *len,
  +   MP_TRACE_STR_TRUNC(filter->pool, copy, *len));
   APR_BRIGADE_INSERT_TAIL(filter->bb_out, bucket);
   /* modperl_brigade_dump(filter->bb_out, stderr); */
   return APR_SUCCESS;
  @@ -882,11 +885,12 @@
   if ((av = dcfg->handlers_per_dir[idx])) {
   modperl_handler_t **handlers = (modperl_handler_t **)av->elts;
   int i;
  -ap_filter_t *f;
   
   for (i=0; inelts; i++) {
 

cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2004-03-03 Thread stas
stas2004/03/03 01:08:19

  Modified:src/modules/perl modperl_filter.c
  Log:
  the new modperl_cgi_header_parse version now takes care of using only the
  'len' bytes of the passed buffer, so we no longer need to copy those bytes
  into a new buffer.
  
  Revision  ChangesPath
  1.85  +4 -22 modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.84
  retrieving revision 1.85
  diff -u -u -r1.84 -r1.85
  --- modperl_filter.c  3 Mar 2004 06:05:30 -   1.84
  +++ modperl_filter.c  3 Mar 2004 09:08:19 -   1.85
  @@ -112,7 +112,6 @@
   apr_bucket_alloc_t *ba = (*wb->filters)->c->bucket_alloc;
   apr_bucket_brigade *bb;
   apr_bucket *bucket;
  -const char *work_buf = buf;
   
   /* reset the counter to 0 as early as possible and in one place,
* since this function will always either pass the data out (and
  @@ -125,27 +124,10 @@
   const char *body;
   int status;
   
  -/*
  - * since wb->outbuf is persistent between requests, if the
  - * current response is shorter than the size of wb->outbuf
  - * it may include data from the previous request at the
  - * end. When this function receives a pointer to
  - * wb->outbuf as 'buf', modperl_cgi_header_parse may
  - * return that irrelevant data as part of 'body'. So
  - * to avoid this risk, we create a new buffer of size 'len'
  - * XXX: if buf wasn't 'const char *buf' we could simply do
  - * buf[len] = '\0'
  - */
  -/* MP_IOBUFSIZE is the size of wb->outbuf */
  -if (buf == wb->outbuf && len < MP_IOBUFSIZE) {
  -work_buf = (char *)apr_pcalloc(wb->pool, sizeof(char*)*len);
  -memcpy((void*)work_buf, buf, len);
  -}
  -
   MP_TRACE_f(MP_FUNC, "\n\n\tparsing headers: %d bytes [%s]\n", len,
  -   apr_pstrmemdup(wb->pool, work_buf, len));
  +   apr_pstrmemdup(wb->pool, buf, len));
   
  -status = modperl_cgi_header_parse(r, (char *)work_buf, &len, &body);
  +status = modperl_cgi_header_parse(r, (char *)buf, &len, &body);
   
   wb->header_parse = 0; /* only once per-request */
   
  @@ -164,11 +146,11 @@
   return APR_SUCCESS;
   }
   
  -work_buf = body;
  +buf = body;
   }
   
   bb = apr_brigade_create(wb->pool, ba);
  -bucket = apr_bucket_transient_create(work_buf, len, ba);
  +bucket = apr_bucket_transient_create(buf, len, ba);
   APR_BRIGADE_INSERT_TAIL(bb, bucket);
   
   if (add_flush_bucket) {
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2004-03-02 Thread stas
stas2004/03/02 22:05:30

  Modified:src/modules/perl modperl_filter.c
  Log:
  use modperl_handler_name wrapper and not directly access  handler->name to
  handle anon subs handlers.
  
  Revision  ChangesPath
  1.84  +9 -7  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.83
  retrieving revision 1.84
  diff -u -u -r1.83 -r1.84
  --- modperl_filter.c  3 Mar 2004 06:03:10 -   1.83
  +++ modperl_filter.c  3 Mar 2004 06:05:30 -   1.84
  @@ -6,7 +6,7 @@
   
   #define MP_FILTER_NAME(f) \
   (is_modperl_filter(f) \
  -? ((modperl_filter_ctx_t *)(f)->ctx)->handler->name \
  +? modperl_handler_name(((modperl_filter_ctx_t *)(f)->ctx)->handler) \
   : (f)->frec->name)
   
   #define MP_FILTER_TYPE(filter) \
  @@ -393,7 +393,8 @@
   
   MP_dINTERP_SELECT(r, c, s);
   
  -MP_TRACE_h(MP_FUNC, "running filter init handler %s\n", handler->name);
  +MP_TRACE_h(MP_FUNC, "running filter init handler %s\n",
  +   modperl_handler_name(handler));
   
   modperl_handler_make_args(aTHX_ &args,
 "Apache::Filter", f,
  @@ -417,7 +418,7 @@
   MP_INTERP_PUTBACK(interp);
   
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  -   "return: %d\n", handler->name, status);
  +   "return: %d\n", modperl_handler_name(handler), status);
   
   return status;  
   }
  @@ -493,7 +494,7 @@
   MP_INTERP_PUTBACK(interp);
   
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  -   "return: %d\n", handler->name, status);
  +   "return: %d\n", modperl_handler_name(handler), status);
   
   return status;
   }
  @@ -1105,7 +1106,8 @@
   
   /* has to resolve early so we can check for init functions */ 
   if (!modperl_mgv_resolve(aTHX_ handler, pool, handler->name, TRUE)) {
  -Perl_croak(aTHX_ "unable to resolve handler %s\n", handler->name);
  +Perl_croak(aTHX_ "unable to resolve handler %s\n",
  +   modperl_handler_name(handler));
   }
   
   /* verify that the filter handler is of the right kind */
  @@ -1115,7 +1117,7 @@
   Perl_croak(aTHX_ "Can't add connection filter handler '%s' "
  "since it doesn't have the "
  "FilterConnectionHandler attribute set",
  -   handler->name);
  +   modperl_handler_name(handler));
   }
   }
   else {
  @@ -1129,7 +1131,7 @@
   Perl_croak(aTHX_ "Can't add request filter handler '%s' "
  "since it doesn't have the "
  "FilterRequestHandler attribute set",
  -   handler->name);
  +   modperl_handler_name(handler));
   }
   }
   
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2003-12-23 Thread geoff
geoff   2003/12/23 07:56:01

  Modified:src/modules/perl modperl_filter.c
  Log:
  note filter_init implementation issue
  
  Revision  ChangesPath
  1.80  +6 -1  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.79
  retrieving revision 1.80
  diff -u -r1.79 -r1.80
  --- modperl_filter.c  23 Dec 2003 03:02:34 -  1.79
  +++ modperl_filter.c  23 Dec 2003 15:56:01 -  1.80
  @@ -405,7 +405,12 @@
   
   modperl_filter_mg_set(aTHX_ AvARRAY(args)[0], filter);
   
  -/* XXX filters are VOID handlers.  should we ignore the status? */
  +/* XXX filter_init return status is propagated back to Apache over
  + * in C land, making it possible to use filter_init to return, say,
  + * BAD_REQUEST.  this implementation, however, ignores the return status
  + * even though we're trapping it here - modperl_filter_add_request sees
  + * the error and propagates it, but modperl_output_filter_add_request
  + * is void so the error is lost  */
   if ((status = modperl_callback(aTHX_ handler, p, r, s, args)) != OK) {
   status = modperl_errsv(aTHX_ status, r, s);
   }
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2003-12-11 Thread stas
stas2003/12/10 23:38:41

  Modified:src/modules/perl modperl_filter.c
  Log:
  cleanup
  
  Revision  ChangesPath
  1.77  +0 -1  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.76
  retrieving revision 1.77
  diff -u -u -r1.76 -r1.77
  --- modperl_filter.c  11 Dec 2003 07:35:09 -  1.76
  +++ modperl_filter.c  11 Dec 2003 07:38:41 -  1.77
  @@ -251,7 +251,6 @@
apr_read_type_e block,
apr_off_t readbytes)
   {
  -
   apr_pool_t *p = MP_FILTER_POOL(f);
   modperl_filter_t *filter;
   
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2003-11-22 Thread stas
stas2003/11/22 02:21:54

  Modified:src/modules/perl modperl_filter.c
  Log:
  modperl_wbucket_pass() wasn't always followed by the code to reset wbucket
  counter. move it inside that function, to fix the current bug and avoid
  future problems
  
  Revision  ChangesPath
  1.74  +6 -1  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.73
  retrieving revision 1.74
  diff -u -u -r1.73 -r1.74
  --- modperl_filter.c  16 Nov 2003 03:32:21 -  1.73
  +++ modperl_filter.c  22 Nov 2003 10:21:53 -  1.74
  @@ -95,6 +95,12 @@
   apr_bucket *bucket;
   const char *work_buf = buf;
   
  +/* reset the counter to 0 as early as possible and in one place,
  + * since this function will always either path the data out (and
  + * it has 'len' already) or return an error.
  + */
  + wb->outcnt = 0;
  +
   if (wb->header_parse) {
   request_rec *r = wb->r;
   const char *bodytext = NULL;
  @@ -181,7 +187,6 @@
   if (wb->outcnt) {
   rv = modperl_wbucket_pass(wb, wb->outbuf, wb->outcnt,
 add_flush_bucket);
  -wb->outcnt = 0;
   }
   else if (add_flush_bucket) {
   rv = send_output_flush(*(wb->filters));
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2003-11-15 Thread geoff
geoff   2003/11/15 19:32:21

  Modified:src/modules/perl modperl_filter.c
  Log:
  remove call to deprecated APR_BRIGADE_FOREACH
  see apr_buckets.h
  
  Revision  ChangesPath
  1.73  +4 -1  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.72
  retrieving revision 1.73
  diff -u -r1.72 -r1.73
  --- modperl_filter.c  7 Oct 2003 01:04:13 -   1.72
  +++ modperl_filter.c  16 Nov 2003 03:32:21 -  1.73
  @@ -1088,7 +1088,10 @@
   fprintf(fp, "dump of brigade 0x%lx\n",
   (unsigned long)bb);
   
  -APR_BRIGADE_FOREACH(bucket, bb) {
  +for (bucket = APR_BRIGADE_FIRST(bb);
  + bucket != APR_BRIGADE_SENTINEL(bb);
  + bucket = APR_BUCKET_NEXT(bucket))
  +{
   fprintf(fp, "   %d: bucket=%s(0x%lx), length=%ld, data=0x%lx\n",
   i, bucket->type->name,
   (unsigned long)bucket,
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2003-10-06 Thread stas
stas2003/10/06 18:01:52

  Modified:src/modules/perl modperl_filter.c
  Log:
  printout filter->f in the trace, plus some comments
  
  Revision  ChangesPath
  1.71  +10 -3 modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.70
  retrieving revision 1.71
  diff -u -u -r1.70 -r1.71
  --- modperl_filter.c  23 Sep 2003 23:52:49 -  1.70
  +++ modperl_filter.c  7 Oct 2003 01:01:52 -   1.71
  @@ -153,7 +153,7 @@
   apr_bucket *bucket = apr_bucket_flush_create(ba);
   APR_BRIGADE_INSERT_TAIL(bb, bucket);
   }
  -
  +
   MP_TRACE_f(MP_FUNC, "\n\n\twrite out: %d bytes\n"
  "\t\tfrom %s\n\t\tto %s filter handler\n",
  len, 
  @@ -248,11 +248,13 @@
   }
   
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  -   "new: %s %s filter (0x%lx)\n",
  +   "new: %s %s filter (modperl_filter_t *0x%lx), "
  +   "f (ap_filter_t *0x%lx)\n",
  MP_FILTER_NAME(f),
  MP_FILTER_TYPE(filter),
  MP_FILTER_MODE(filter),
  -   (unsigned long)filter);
  +   (unsigned long)filter,
  +   (unsigned long)filter->f);
   
   return filter;
   }
  @@ -898,6 +900,11 @@
   continue;
   }
   
  +/* XXX: I fail to see where this feature is used, since
  + * modperl_filter_add_connection doesn't register request
  + * filters. may be it'll be still useful when the same
  + * filter handler is configured to run more than once?
  + * e.g. snooping filter [stas] */
   f = filters;
   while (f) {
   const char *fname = f->frec->name;
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2003-09-18 Thread stas
stas2003/09/18 00:34:21

  Modified:src/modules/perl modperl_filter.c
  Log:
  it is invalid to return HTTP_INTERNAL_SERVER_ERROR or any other HTTP
  response code from modperl_wbucket_pass, therefore set the error code into
  r->status and return APR_SUCCESS. Untill now response handler with messed
  up response headers, were causing no response what so ever to the client.
  LWP was assuming 500, and it was all fine, testing without LWP has
  immediately revealed that there was a problem in the handling of this case.
  
  Revision  ChangesPath
  1.68  +2 -1  modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.67
  retrieving revision 1.68
  diff -u -u -r1.67 -r1.68
  --- modperl_filter.c  13 Sep 2003 20:35:33 -  1.67
  +++ modperl_filter.c  18 Sep 2003 07:34:21 -  1.68
  @@ -130,8 +130,9 @@
   ap_log_error(APLOG_MARK, APLOG_WARNING,
0, r->server, "%s did not send an HTTP header",
r->uri);
  +r->status = status;
   /* XXX: bodytext == NULL here */
  -return status;
  +return APR_SUCCESS;
   }
   else if (!bodytext) {
   return APR_SUCCESS;
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2003-08-20 Thread stas
stas2003/08/20 16:10:09

  Modified:src/modules/perl modperl_filter.c
  Log:
  - more tracing to help io debugging
  - prevent segfaults when tracing, need to check whether the filter is a
  mod_perl one, before trying to retrieve the perl callback function name
  
  Revision  ChangesPath
  1.66  +29 -18modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.65
  retrieving revision 1.66
  diff -u -r1.65 -r1.66
  --- modperl_filter.c  11 Aug 2003 20:34:22 -  1.65
  +++ modperl_filter.c  20 Aug 2003 23:10:09 -  1.66
  @@ -5,11 +5,15 @@
   #define MP_FILTER_NAME_FORMAT "   %s\n\n\t"
   
   #define MP_FILTER_NAME(f) \
  -((modperl_filter_ctx_t *)f->ctx)->handler->name
  +(is_modperl_filter(f) \
  +? ((modperl_filter_ctx_t *)(f)->ctx)->handler->name \
  +: (f)->frec->name)
   
   #define MP_FILTER_TYPE(filter) \
  -((modperl_filter_ctx_t *)filter->f->ctx)->handler->attrs & \
  -MP_FILTER_CONNECTION_HANDLER  ? "connection" : "request"
  +(is_modperl_filter(filter->f) \
  +? ((modperl_filter_ctx_t *)(filter)->f->ctx)->handler->attrs & \
  +MP_FILTER_CONNECTION_HANDLER  ? "connection" : "request" \
  +: "unknown")
   
   #define MP_FILTER_MODE(filter) \
   (filter->mode == MP_INPUT_FILTER_MODE ? "input" : "output")
  @@ -17,7 +21,7 @@
   #define MP_FILTER_POOL(f) f->r ? f->r->pool : f->c->pool
   
   /* this function is for tracing only, it's not optimized for performance */
  -static const char* next_filter_name(ap_filter_t *f)
  +static int is_modperl_filter(ap_filter_t *f)
   {
   const char *name = f->frec->name;
   
  @@ -26,13 +30,14 @@
   !strcasecmp(name, MP_FILTER_CONNECTION_OUTPUT_NAME) ||
   !strcasecmp(name, MP_FILTER_REQUEST_INPUT_NAME) ||
   !strcasecmp(name, MP_FILTER_REQUEST_OUTPUT_NAME) ) {
  -return ((modperl_filter_ctx_t *)f->ctx)->handler->name;
  +return 1;
   }
   else {
  -return name;
  +return 0;
   }
   }
   
  +
   MP_INLINE static apr_status_t send_input_eos(modperl_filter_t *filter)
   {
   apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc;
  @@ -110,6 +115,10 @@
   work_buf = (char *)apr_pcalloc(wb->pool, sizeof(char*)*len);
   memcpy((void*)work_buf, buf, len);
   }
  +
  +MP_TRACE_f(MP_FUNC, "\n\n\tparsing headers: %d bytes [%s]\n", len,
  +   apr_pstrmemdup(wb->pool, work_buf, len));
  +
   status = modperl_cgi_header_parse(r, (char *)work_buf, &bodytext);
   
   wb->header_parse = 0; /* only once per-request */
  @@ -147,18 +156,21 @@
   MP_TRACE_f(MP_FUNC, "\n\n\twrite out: %d bytes\n"
  "\t\tfrom %s\n\t\tto %s filter handler\n",
  len, 
  -   (wb->r && wb->filters == &wb->r->output_filters)
  -   ? "response handler" : "current filter handler",
  -   next_filter_name(*(wb->filters)));
  +   ((wb->r && wb->filters == &wb->r->output_filters)
  +   ? "response handler" : "current filter handler"),
  +   MP_FILTER_NAME(*(wb->filters)));
   
   return ap_pass_brigade(*(wb->filters), bb);
   }
   
  -/* if add_flush_bucket is TRUE
  - *  and there is data to flush,
  - *   a flush bucket is added to the tail of bb with data
  - * otherwise
  - *   a flush bucket is sent in its own bb
  +/* flush data if any,
  + * if add_flush_bucket is TRUE
  + * if there is data to flush
  + * a flush bucket is added to the tail of bb with data
  + * else
  + * a flush bucket is sent in its own bb
  + * else
  + * nothing is sent
*/
   MP_INLINE apr_status_t modperl_wbucket_flush(modperl_wbucket_t *wb,
int add_flush_bucket)
  @@ -173,7 +185,7 @@
   else if (add_flush_bucket) {
   rv = send_output_flush(*(wb->filters));
   }
  -
  +
   return rv;
   }
   
  @@ -184,8 +196,6 @@
   apr_size_t len = *wlen;
   *wlen = 0;
   
  -MP_TRACE_f(MP_FUNC, "\n\n\tbuffer out: %d bytes\n", len);
  -
   if ((len + wb->outcnt) > sizeof(wb->outbuf)) {
   apr_status_t rv;
   if ((rv = modperl_wbucket_flush(wb, FALSE)) != APR_SUCCESS) {
  @@ -239,7 +249,8 @@
   MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  "new: %s %s filter (0x%lx)\n",
  MP_FILTER_NAME(f),
  -   MP_FILTER_TYPE(filter), MP_FILTER_MODE(filter),
  +   MP_FILTER_TYPE(filter),
  +   MP_FILTER_MODE(filter),
  (unsigned long)filter);
   
   return filter;
  
  
  


cvs commit: modperl-2.0/src/modules/perl modperl_filter.c

2003-04-02 Thread stas
stas2003/04/02 22:21:43

  Modified:xs   modperl_xs_util.h
   xs/Apache/Filter Apache__Filter.h
   src/modules/perl modperl_filter.c
  Log:
  - filters tracing readability is now mucho improved
  - a small bug fix with eos bucket
  
  Revision  ChangesPath
  1.14  +4 -1  modperl-2.0/xs/modperl_xs_util.h
  
  Index: modperl_xs_util.h
  ===
  RCS file: /home/cvs/modperl-2.0/xs/modperl_xs_util.h,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- modperl_xs_util.h 17 Jan 2003 03:08:31 -  1.13
  +++ modperl_xs_util.h 3 Apr 2003 06:21:42 -   1.14
  @@ -80,10 +80,13 @@
   arg = *MARK++
   
   /* XXX: we probably shouldn't croak here */
  -#define mpxs_write_loop(func,obj) \
  +#define mpxs_write_loop(func, obj) \
   while (MARK <= SP) { \
   apr_ssize_t wlen; \
   char *buf = SvPV(*MARK, wlen); \
  +MP_TRACE_f(MP_FUNC, "   %s\n\n\tbuffer out: %d bytes\n", \
  +  ((modperl_filter_ctx_t *)obj->f->ctx)->handler->name, \
  +  wlen); \
   apr_status_t rv = func(aTHX_ obj, buf, &wlen); \
   if (rv != APR_SUCCESS) { \
   Perl_croak(aTHX_ modperl_apr_strerror(rv)); \
  
  
  
  1.27  +2 -6  modperl-2.0/xs/Apache/Filter/Apache__Filter.h
  
  Index: Apache__Filter.h
  ===
  RCS file: /home/cvs/modperl-2.0/xs/Apache/Filter/Apache__Filter.h,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- Apache__Filter.h  1 Apr 2003 05:20:50 -   1.26
  +++ Apache__Filter.h  3 Apr 2003 06:21:43 -   1.27
  @@ -193,12 +193,8 @@
   mpxs_usage_va_1(modperl_filter, "$filter->remove()");
   f = modperl_filter->f;
   
  -#ifdef MP_TRACE
  -{
  -modperl_filter_ctx_t *ctx = (modperl_filter_ctx_t *)(f->ctx);
  -MP_TRACE_f(MP_FUNC, "removing filter %s\n", ctx->handler->name);
  -}
  -#endif
  +MP_TRACE_f(MP_FUNC, "   %s\n\n\tfilter removes itself\n",
  +   ((modperl_filter_ctx_t *)f->ctx)->handler->name);
   
   if (modperl_filter->mode == MP_INPUT_FILTER_MODE) {
   ap_remove_input_filter(f);
  
  
  
  1.57  +100 -37   modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -r1.56 -r1.57
  --- modperl_filter.c  14 Mar 2003 05:33:18 -  1.56
  +++ modperl_filter.c  3 Apr 2003 06:21:43 -   1.57
  @@ -2,8 +2,37 @@
   
   /* helper funcs */
   
  +#define MP_FILTER_NAME_FORMAT "   %s\n\n\t"
  +
  +#define MP_FILTER_NAME(f) \
  +((modperl_filter_ctx_t *)f->ctx)->handler->name
  +
  +#define MP_FILTER_TYPE(filter) \
  +((modperl_filter_ctx_t *)filter->f->ctx)->handler->attrs & \
  +MP_FILTER_CONNECTION_HANDLER  ? "connection" : "request"
  +
  +#define MP_FILTER_MODE(filter) \
  +(filter->mode == MP_INPUT_FILTER_MODE ? "input" : "output")
  +
   #define MP_FILTER_POOL(f) f->r ? f->r->pool : f->c->pool
   
  +/* this function is for tracing only, it's not optimized for performance */
  +static const char* next_filter_name(ap_filter_t *f)
  +{
  +const char *name = f->frec->name;
  +
  +/* frec->name is always lowercased */ 
  +if (ap_strcasecmp_match(name, MP_FILTER_CONNECTION_INPUT_NAME)  ||
  +ap_strcasecmp_match(name, MP_FILTER_CONNECTION_OUTPUT_NAME) ||
  +ap_strcasecmp_match(name, MP_FILTER_REQUEST_INPUT_NAME) ||
  +ap_strcasecmp_match(name, MP_FILTER_REQUEST_OUTPUT_NAME) ) {
  +return ((modperl_filter_ctx_t *)f->ctx)->handler->name;
  +}
  +else {
  +return name;
  +}
  +}
  +
   MP_INLINE static apr_status_t send_input_eos(modperl_filter_t *filter)
   {
   apr_bucket_alloc_t *ba = filter->f->c->bucket_alloc;
  @@ -29,8 +58,9 @@
   apr_bucket *b = apr_bucket_eos_create(ba);
   APR_BRIGADE_INSERT_TAIL(bb, b);
   ((modperl_filter_ctx_t *)f->ctx)->sent_eos = 1;
  -MP_TRACE_f(MP_FUNC, "sending EOS bucket in separate bb\n");
  -return ap_pass_brigade(f, bb);
  +MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  +   "write out: EOS bucket in separate bb\n", MP_FILTER_NAME(f));
  +return ap_pass_brigade(f->next, bb);
   }
   
   MP_INLINE static apr_status_t send_output_flush(ap_filter_t *f)
  @@ -40,7 +70,8 @@
   ba);
   apr_bucket *b = apr_bucket_flush_create(ba);
   APR_BRIGADE_INSERT_TAIL(bb, b);
  -MP_TRACE_f(MP_FUNC, "sending FLUSH bucket in separate bb\n");
  +MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
  +   "write out: FLUSH bucket in separate bb\n", MP_FILTER_NAME(f));
   retur