You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Kiffin Gish <Ki...@tomtom.com> on 2008/06/26 09:33:57 UTC

ap_custom_response content type 'text/xml'

Hi there.

In order to reply with my own xml error, I want to use
ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);

However, default content type is "text/html". If I try to change it by
using ap_set_content_type(r, "text/xml"), this has no effect.

Is there anyone out there who can help me?

-- 
Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office

Re: ap_custom_response content type 'text/xml'

Posted by Kiffin Gish <Ki...@tomtom.com>.
Thanks so much Brian, it now works!

On Fri, 2008-06-27 at 11:45 -0400, Brian J. France wrote:
> On Jun 27, 2008, at 11:04 AM, Kiffin Gish wrote:
> > Sorry to keep bugging you, but where does this -1 belong?
> 
> In my example there was this line:
> 
> /* split off after value */
> apr_bucket_split(b, end - ct_header + 14 + 1);
> 
> + 14 is to skip the "Content-Type: "
> + 1 is to skip the "\r"
> 
> This is where you want to change that to -1 instead to keep the \n (or  
> the ; if you scan for ; instead of ;).
> 
> Brian
> 
-- 
Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office


This e-mail message contains information which is confidential and may be privileged. It is intended for use by the addressee only. If you are not the intended addressee, we request that you notify the sender immediately and delete or destroy this e-mail message and any attachment(s), without copying, saving, forwarding, disclosing or using its contents in any other way. TomTom N.V., TomTom International BV or any other company belonging to the TomTom group of companies will not be liable for damage relating to the communication by e-mail of data, documents or any other information.

Re: ap_custom_response content type 'text/xml'

Posted by "Brian J. France" <li...@firehawksystems.com>.
On Jun 27, 2008, at 11:04 AM, Kiffin Gish wrote:
> Sorry to keep bugging you, but where does this -1 belong?

In my example there was this line:

/* split off after value */
apr_bucket_split(b, end - ct_header + 14 + 1);

+ 14 is to skip the "Content-Type: "
+ 1 is to skip the "\r"

This is where you want to change that to -1 instead to keep the \n (or  
the ; if you scan for ; instead of ;).

Brian


Re: ap_custom_response content type 'text/xml'

Posted by Kiffin Gish <Ki...@tomtom.com>.
Sorry to keep bugging you, but where does this -1 belong?

On Fri, 2008-06-27 at 09:59 -0400, Brian J. France wrote:
> On Jun 27, 2008, at 9:28 AM, Kiffin Gish wrote:
> 
> > I tried your suggestion but it doesn't help. To be more specific, I  
> > want
> > to convert:
> >
> > HTTP/1.1 500 Internal Server Error
> > Date: Fri, 27 Jun 2008 13:25:56 GMT
> > Server: Apache/2.2.3 (Unix)
> > Content-Length: 1066
> > Connection: close
> > Content-Type: text/html; charset=iso-8859-1
> >
> > <?xml version='1.0' encoding="UTF-8" standalone="no" ?>
> > ...
> >
> > to:
> >
> > HTTP/1.1 500 Internal Server Error
> > Date: Fri, 27 Jun 2008 13:25:56 GMT
> > Server: Apache/2.2.3 (Unix)
> > Content-Length: 1066
> > Connection: close
> > Content-Type: text/xml; charset=iso-8859-1
> >
> > <?xml version='1.0' encoding="UTF-8" standalone="no" ?>
> > ...
> >
> > Thanks in advance for your help.
> >
> 
> Looks like you need to look for ; and do the -1 or make you insert  
> string "text/xml; charset=iso-8859-1" and still do the -1.
> 
> Biran
> 
> 
> 
> >
> >
> >
> > On Fri, 2008-06-27 at 09:02 -0400, Brian J. France wrote:
> > > On Jun 27, 2008, at 4:00 AM, Kiffin Gish wrote:
> > >
> > > > Brian,
> > > >
> > > > This is great, thanks alot!
> > > >
> > > > I've 'almost' got it working correctly, the only problem being  
> > that
> > > > the
> > > > Content-Type is not getting truncated correctly, e.g. instead of:
> > > >
> > > > Content-Type: text/xml\n
> > > > \n
> > > > <?xml version='1.0' encoding="UTF-8" standalone="no" ?>\n
> > > >
> > > >
> > > > I'm getting this:
> > > >
> > > > Content-Type: text/xml<?xml version='1.0' encoding="UTF-8"
> > > > standalone="no" ?>\n
> > > >
> > > > Any tips would be greatly appreciated.
> > >
> > >
> > > In my example it looks for \n for the end of the line and to  
> > calculate
> > > the split it add +1 to the value (to grab the \r).
> > >
> > > I think you can change +1 to -1 and it should keep the \n\r at the  
> > end
> > > of the header.
> > >
> > > Brian
> > >
> > >
> > >
> > >
> > > >
> > > >
> > > >
> > > > On Thu, 2008-06-26 at 10:29 -0400, Brian J. France wrote:
> > > >> On Jun 26, 2008, at 9:48 AM, Kiffin Gish wrote:
> > > >>> Thanks Brian, I've tried what you suggested but it doesn't  
> > seem to
> > > >>> work.
> > > >>> Could you be more specific? Here's what I've tried:
> > > >>>
> > > >>> void register_hooks(apr_pool_t *p)
> > > >>> {
> > > >>>    ap_hook_translate_name(hook_translate_name, NULL, NULL,
> > > >>> APR_HOOK_REALLY_FIRST);
> > > >>>    ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
> > > >>> APR_HOOK_MIDDLE);
> > > >>>    ap_register_output_filter("wms-error-http-header",
> > > >>> wmserror_ofilter,
> > > >>>            NULL, AP_FTYPE_CONNECTION) ;
> > > >>> }
> > > >>>
> > > >>> static int hook_translate_name (request_rec *r)
> > > >>> {
> > > >>>    apr_table_setn(r->notes, "MY_NOTE", ".");
> > > >>>    ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> > > >>>    return HTTP_INTERNAL_SERVER_ERROR;
> > > >>> }
> > > >>>
> > > >>> static int hook_pre_connection(conn_rec *c, void *csd)
> > > >>> {
> > > >>>    ap_add_output_filter("wms-error-httpd-header", NULL, NULL,  
> > c);
> > > >>>    return OK;
> > > >>> }
> > > >>>
> > > >>> int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
> > > >>> {
> > > >>>    const char *t = apr_table_get(f->r->notes, "MY_NOTE");
> > > >>>    if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
> > > >>>    return ap_pass_brigade(f->next, bb) ;
> > > >>> }
> > > >>>
> > > >>
> > > >> My guess would be you can't use ap_set_content_type in your  
> > filter,
> > > >> you will have to examine the buckets, find Conetent-Type and  
> > change
> > > >> it
> > > >> to text/xml.
> > > >>
> > > >> Below is a quick hack I created from code we use to remove the  
> > server
> > > >> header and insert the host comment.  It may not work perfectly  
> > out of
> > > >> the box, but by adding some log lines you should be able to get  
> > it
> > > >> working.
> > > >>
> > > >> This also assume the headers will fit in a 8k brigade.
> > > >>
> > > >> Brian
> > > >>
> > > >>
> > > >>
> > > >> /* Because strnstr is not on RHEL4 */
> > > >> static char *__strnstr(const char *big, const char *little,  
> > size_t
> > > >> len)
> > > >> {
> > > >>     size_t little_len = strlen(little);
> > > >>     size_t i;
> > > >>     for (i = 0; i <= len - little_len; i++) {
> > > >>         if (memcmp(big + i, little, little_len) == 0) {
> > > >>             return (char *)(big + i);
> > > >>         }
> > > >>     }
> > > >>
> > > >>     return 0;
> > > >> }
> > > >>
> > > >> static apr_status_t wmserror_output_filter(ap_filter_t *f,
> > > >> apr_bucket_brigade *in)
> > > >> {
> > > >>   if (f->r != NULL && apr_table_get(f->r->notes, "MY_NOTE") !=
> > > >> NULL) {
> > > >>
> > > >>     apr_bucket *b;
> > > >>
> > > >>     for (b = APR_BRIGADE_FIRST(in); b !=  
> > APR_BRIGADE_SENTINEL(in) &&
> > > >> done == 0; b = APR_BUCKET_NEXT(b)) {
> > > >>       const char *buf;
> > > >>       size_t bytes ;
> > > >>
> > > >>       if (!(APR_BUCKET_IS_METADATA(b))) {
> > > >>         if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) ==
> > > >> APR_SUCCESS) {
> > > >>           char *ct_header = __strnstr(buf, "Content-Type: ",  
> > bytes);
> > > >>           char *end;
> > > >>           if (cl_header != NULL && (end = strstr(ct_header,  
> > "\n")) !=
> > > >> NULL) {
> > > >>             apr_bucket *newb = NULL;
> > > >>             apr_bucket *new_ct;
> > > >>
> > > >>             /* split off buffer at the ct header */
> > > >>             apr_bucket_split(b, ct_header +  14 - buf);
> > > >>
> > > >>             /* skip to the ct value bucket */
> > > >>             b = APR_BUCKET_NEXT(b);
> > > >>
> > > >>             /* split off after value */
> > > >>             apr_bucket_split(b, end - ct_header + 14 + 1);
> > > >>
> > > >>             /* skip to the next one */
> > > >>             newb = APR_BUCKET_NEXT(b);
> > > >>
> > > >>             /* remove it */
> > > >>             APR_BUCKET_REMOVE(b);
> > > >>
> > > >>             /* nuke it */
> > > >>             apr_bucket_destroy(b);
> > > >>
> > > >>             b = newb;
> > > >>
> > > >>             /* I think this is the right function */
> > > >>             new_ct = apr_bucket_immortal_create("text/xml",
> > > >> sizeof("text/xml"), f->c->bucket_alloc);
> > > >>
> > > >>             APR_BUCKET_INSERT_BEFORE(b, new_ct);
> > > >>
> > > >>             apr_table_unset(f->r->notes, "MY_NOTE");
> > > >>             break;
> > > >>           }
> > > >>         }
> > > >>       }
> > > >>     }
> > > >>   }
> > > >>
> > > >>   /* send the data up the stack */
> > > >>   return ap_pass_brigade(f->next,in);
> > > >> }
> > > >>
> > > >>
> > > >>
> > > >> static void wmserror_insert_output_filter(request_rec *r)
> > > >> {
> > > >>     ap_add_output_filter("WMSERROR_OUTPUT_FILTER", NULL, r, r-
> > > >>> connection);
> > > >> }
> > > >>
> > > >> static void register_hooks(apr_pool_t *p)
> > > >> {
> > > >>     ap_register_output_filter("WMSERROR_OUTPUT_FILTER",
> > > >> wmserror_output_filter, NULL, AP_FTYPE_PROTOCOL);
> > > >>
> > > >>     ap_hook_insert_filter(wmserror_insert_output_filter, NULL,  
> > NULL,
> > > >> APR_HOOK_REALLY_LAST);
> > > >> }
> > > >>
> > > >>
> > > >>
> > > >>
> > > >>>
> > > >>>
> > > >>> On Thu, 2008-06-26 at 08:35 -0400, Brian J. France wrote:
> > > >>>> On Jun 26, 2008, at 3:33 AM, Kiffin Gish wrote:
> > > >>>>> In order to reply with my own xml error, I want to use
> > > >>>>> ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> > > >>>>>
> > > >>>>> However, default content type is "text/html". If I try to  
> > change
> > > >>> it by
> > > >>>>> using ap_set_content_type(r, "text/xml"), this has no effect.
> > > >>>>>
> > > >>>>> Is there anyone out there who can help me?
> > > >>>>>
> > > >>>>
> > > >>>> Ran into the same thing with apache 1.3.  We have a patch that
> > > >>> adds a
> > > >>>> custom hook that is called before headers are sent and we can  
> > re-
> > > >>>> set
> > > >>>> it back to text/xml there (remember this is 1.3).
> > > >>>>
> > > >>>> You could call ap_custom_response, set a flag in r->notes,  
> > have a
> > > >>>> output filter in your module that checks r->notes and if the  
> > flag
> > > >>> set
> > > >>>> it scans for Content-type and resets it to text/xml.
> > > >>>>
> > > >>>> Brian
> > > >>>>
> > > >>> --
> > > >>> Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com
> > > >>> | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> > > >>
> > > > --
> > > > Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com
> > > >  | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> > > >
> > > >
> > > > This e-mail message contains information which is confidential and
> > > > may be privileged. It is intended for use by the addressee only.  
> > If
> > > > you are not the intended addressee, we request that you notify the
> > > > sender immediately and delete or destroy this e-mail message and  
> > any
> > > > attachment(s), without copying, saving, forwarding, disclosing or
> > > > using its contents in any other way. TomTom N.V., TomTom
> > > > International BV or any other company belonging to the TomTom  
> > group
> > > > of companies will not be liable for damage relating to the
> > > > communication by e-mail of data, documents or any other  
> > information.
> > >
> > --
> > Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com 
> >  | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> 
-- 
Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office


This e-mail message contains information which is confidential and may be privileged. It is intended for use by the addressee only. If you are not the intended addressee, we request that you notify the sender immediately and delete or destroy this e-mail message and any attachment(s), without copying, saving, forwarding, disclosing or using its contents in any other way. TomTom N.V., TomTom International BV or any other company belonging to the TomTom group of companies will not be liable for damage relating to the communication by e-mail of data, documents or any other information.

Re: ap_custom_response content type 'text/xml'

Posted by "Brian J. France" <li...@firehawksystems.com>.
On Jun 27, 2008, at 9:28 AM, Kiffin Gish wrote:

> I tried your suggestion but it doesn't help. To be more specific, I  
> want
> to convert:
>
> HTTP/1.1 500 Internal Server Error
> Date: Fri, 27 Jun 2008 13:25:56 GMT
> Server: Apache/2.2.3 (Unix)
> Content-Length: 1066
> Connection: close
> Content-Type: text/html; charset=iso-8859-1
>
> <?xml version='1.0' encoding="UTF-8" standalone="no" ?>
> ...
>
> to:
>
> HTTP/1.1 500 Internal Server Error
> Date: Fri, 27 Jun 2008 13:25:56 GMT
> Server: Apache/2.2.3 (Unix)
> Content-Length: 1066
> Connection: close
> Content-Type: text/xml; charset=iso-8859-1
>
> <?xml version='1.0' encoding="UTF-8" standalone="no" ?>
> ...
>
> Thanks in advance for your help.
>

Looks like you need to look for ; and do the -1 or make you insert  
string "text/xml; charset=iso-8859-1" and still do the -1.

Biran



>
>
>
> On Fri, 2008-06-27 at 09:02 -0400, Brian J. France wrote:
> > On Jun 27, 2008, at 4:00 AM, Kiffin Gish wrote:
> >
> > > Brian,
> > >
> > > This is great, thanks alot!
> > >
> > > I've 'almost' got it working correctly, the only problem being  
> that
> > > the
> > > Content-Type is not getting truncated correctly, e.g. instead of:
> > >
> > > Content-Type: text/xml\n
> > > \n
> > > <?xml version='1.0' encoding="UTF-8" standalone="no" ?>\n
> > >
> > >
> > > I'm getting this:
> > >
> > > Content-Type: text/xml<?xml version='1.0' encoding="UTF-8"
> > > standalone="no" ?>\n
> > >
> > > Any tips would be greatly appreciated.
> >
> >
> > In my example it looks for \n for the end of the line and to  
> calculate
> > the split it add +1 to the value (to grab the \r).
> >
> > I think you can change +1 to -1 and it should keep the \n\r at the  
> end
> > of the header.
> >
> > Brian
> >
> >
> >
> >
> > >
> > >
> > >
> > > On Thu, 2008-06-26 at 10:29 -0400, Brian J. France wrote:
> > >> On Jun 26, 2008, at 9:48 AM, Kiffin Gish wrote:
> > >>> Thanks Brian, I've tried what you suggested but it doesn't  
> seem to
> > >>> work.
> > >>> Could you be more specific? Here's what I've tried:
> > >>>
> > >>> void register_hooks(apr_pool_t *p)
> > >>> {
> > >>>    ap_hook_translate_name(hook_translate_name, NULL, NULL,
> > >>> APR_HOOK_REALLY_FIRST);
> > >>>    ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
> > >>> APR_HOOK_MIDDLE);
> > >>>    ap_register_output_filter("wms-error-http-header",
> > >>> wmserror_ofilter,
> > >>>            NULL, AP_FTYPE_CONNECTION) ;
> > >>> }
> > >>>
> > >>> static int hook_translate_name (request_rec *r)
> > >>> {
> > >>>    apr_table_setn(r->notes, "MY_NOTE", ".");
> > >>>    ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> > >>>    return HTTP_INTERNAL_SERVER_ERROR;
> > >>> }
> > >>>
> > >>> static int hook_pre_connection(conn_rec *c, void *csd)
> > >>> {
> > >>>    ap_add_output_filter("wms-error-httpd-header", NULL, NULL,  
> c);
> > >>>    return OK;
> > >>> }
> > >>>
> > >>> int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
> > >>> {
> > >>>    const char *t = apr_table_get(f->r->notes, "MY_NOTE");
> > >>>    if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
> > >>>    return ap_pass_brigade(f->next, bb) ;
> > >>> }
> > >>>
> > >>
> > >> My guess would be you can't use ap_set_content_type in your  
> filter,
> > >> you will have to examine the buckets, find Conetent-Type and  
> change
> > >> it
> > >> to text/xml.
> > >>
> > >> Below is a quick hack I created from code we use to remove the  
> server
> > >> header and insert the host comment.  It may not work perfectly  
> out of
> > >> the box, but by adding some log lines you should be able to get  
> it
> > >> working.
> > >>
> > >> This also assume the headers will fit in a 8k brigade.
> > >>
> > >> Brian
> > >>
> > >>
> > >>
> > >> /* Because strnstr is not on RHEL4 */
> > >> static char *__strnstr(const char *big, const char *little,  
> size_t
> > >> len)
> > >> {
> > >>     size_t little_len = strlen(little);
> > >>     size_t i;
> > >>     for (i = 0; i <= len - little_len; i++) {
> > >>         if (memcmp(big + i, little, little_len) == 0) {
> > >>             return (char *)(big + i);
> > >>         }
> > >>     }
> > >>
> > >>     return 0;
> > >> }
> > >>
> > >> static apr_status_t wmserror_output_filter(ap_filter_t *f,
> > >> apr_bucket_brigade *in)
> > >> {
> > >>   if (f->r != NULL && apr_table_get(f->r->notes, "MY_NOTE") !=
> > >> NULL) {
> > >>
> > >>     apr_bucket *b;
> > >>
> > >>     for (b = APR_BRIGADE_FIRST(in); b !=  
> APR_BRIGADE_SENTINEL(in) &&
> > >> done == 0; b = APR_BUCKET_NEXT(b)) {
> > >>       const char *buf;
> > >>       size_t bytes ;
> > >>
> > >>       if (!(APR_BUCKET_IS_METADATA(b))) {
> > >>         if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) ==
> > >> APR_SUCCESS) {
> > >>           char *ct_header = __strnstr(buf, "Content-Type: ",  
> bytes);
> > >>           char *end;
> > >>           if (cl_header != NULL && (end = strstr(ct_header,  
> "\n")) !=
> > >> NULL) {
> > >>             apr_bucket *newb = NULL;
> > >>             apr_bucket *new_ct;
> > >>
> > >>             /* split off buffer at the ct header */
> > >>             apr_bucket_split(b, ct_header +  14 - buf);
> > >>
> > >>             /* skip to the ct value bucket */
> > >>             b = APR_BUCKET_NEXT(b);
> > >>
> > >>             /* split off after value */
> > >>             apr_bucket_split(b, end - ct_header + 14 + 1);
> > >>
> > >>             /* skip to the next one */
> > >>             newb = APR_BUCKET_NEXT(b);
> > >>
> > >>             /* remove it */
> > >>             APR_BUCKET_REMOVE(b);
> > >>
> > >>             /* nuke it */
> > >>             apr_bucket_destroy(b);
> > >>
> > >>             b = newb;
> > >>
> > >>             /* I think this is the right function */
> > >>             new_ct = apr_bucket_immortal_create("text/xml",
> > >> sizeof("text/xml"), f->c->bucket_alloc);
> > >>
> > >>             APR_BUCKET_INSERT_BEFORE(b, new_ct);
> > >>
> > >>             apr_table_unset(f->r->notes, "MY_NOTE");
> > >>             break;
> > >>           }
> > >>         }
> > >>       }
> > >>     }
> > >>   }
> > >>
> > >>   /* send the data up the stack */
> > >>   return ap_pass_brigade(f->next,in);
> > >> }
> > >>
> > >>
> > >>
> > >> static void wmserror_insert_output_filter(request_rec *r)
> > >> {
> > >>     ap_add_output_filter("WMSERROR_OUTPUT_FILTER", NULL, r, r-
> > >>> connection);
> > >> }
> > >>
> > >> static void register_hooks(apr_pool_t *p)
> > >> {
> > >>     ap_register_output_filter("WMSERROR_OUTPUT_FILTER",
> > >> wmserror_output_filter, NULL, AP_FTYPE_PROTOCOL);
> > >>
> > >>     ap_hook_insert_filter(wmserror_insert_output_filter, NULL,  
> NULL,
> > >> APR_HOOK_REALLY_LAST);
> > >> }
> > >>
> > >>
> > >>
> > >>
> > >>>
> > >>>
> > >>> On Thu, 2008-06-26 at 08:35 -0400, Brian J. France wrote:
> > >>>> On Jun 26, 2008, at 3:33 AM, Kiffin Gish wrote:
> > >>>>> In order to reply with my own xml error, I want to use
> > >>>>> ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> > >>>>>
> > >>>>> However, default content type is "text/html". If I try to  
> change
> > >>> it by
> > >>>>> using ap_set_content_type(r, "text/xml"), this has no effect.
> > >>>>>
> > >>>>> Is there anyone out there who can help me?
> > >>>>>
> > >>>>
> > >>>> Ran into the same thing with apache 1.3.  We have a patch that
> > >>> adds a
> > >>>> custom hook that is called before headers are sent and we can  
> re-
> > >>>> set
> > >>>> it back to text/xml there (remember this is 1.3).
> > >>>>
> > >>>> You could call ap_custom_response, set a flag in r->notes,  
> have a
> > >>>> output filter in your module that checks r->notes and if the  
> flag
> > >>> set
> > >>>> it scans for Content-type and resets it to text/xml.
> > >>>>
> > >>>> Brian
> > >>>>
> > >>> --
> > >>> Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com
> > >>> | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> > >>
> > > --
> > > Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com
> > >  | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> > >
> > >
> > > This e-mail message contains information which is confidential and
> > > may be privileged. It is intended for use by the addressee only.  
> If
> > > you are not the intended addressee, we request that you notify the
> > > sender immediately and delete or destroy this e-mail message and  
> any
> > > attachment(s), without copying, saving, forwarding, disclosing or
> > > using its contents in any other way. TomTom N.V., TomTom
> > > International BV or any other company belonging to the TomTom  
> group
> > > of companies will not be liable for damage relating to the
> > > communication by e-mail of data, documents or any other  
> information.
> >
> --
> Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com 
>  | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office


Re: ap_custom_response content type 'text/xml'

Posted by Kiffin Gish <Ki...@tomtom.com>.
I tried your suggestion but it doesn't help. To be more specific, I want
to convert:

HTTP/1.1 500 Internal Server Error
Date: Fri, 27 Jun 2008 13:25:56 GMT
Server: Apache/2.2.3 (Unix)
Content-Length: 1066
Connection: close
Content-Type: text/html; charset=iso-8859-1

<?xml version='1.0' encoding="UTF-8" standalone="no" ?>
...

to:

HTTP/1.1 500 Internal Server Error
Date: Fri, 27 Jun 2008 13:25:56 GMT
Server: Apache/2.2.3 (Unix)
Content-Length: 1066
Connection: close
Content-Type: text/xml; charset=iso-8859-1

<?xml version='1.0' encoding="UTF-8" standalone="no" ?>
...

Thanks in advance for your help.


On Fri, 2008-06-27 at 09:02 -0400, Brian J. France wrote:
> On Jun 27, 2008, at 4:00 AM, Kiffin Gish wrote:
> 
> > Brian,
> >
> > This is great, thanks alot!
> >
> > I've 'almost' got it working correctly, the only problem being that  
> > the
> > Content-Type is not getting truncated correctly, e.g. instead of:
> >
> > Content-Type: text/xml\n
> > \n
> > <?xml version='1.0' encoding="UTF-8" standalone="no" ?>\n
> >
> >
> > I'm getting this:
> >
> > Content-Type: text/xml<?xml version='1.0' encoding="UTF-8"
> > standalone="no" ?>\n
> >
> > Any tips would be greatly appreciated.
> 
> 
> In my example it looks for \n for the end of the line and to calculate  
> the split it add +1 to the value (to grab the \r).
> 
> I think you can change +1 to -1 and it should keep the \n\r at the end  
> of the header.
> 
> Brian
> 
> 
> 
> 
> >
> >
> >
> > On Thu, 2008-06-26 at 10:29 -0400, Brian J. France wrote:
> >> On Jun 26, 2008, at 9:48 AM, Kiffin Gish wrote:
> >>> Thanks Brian, I've tried what you suggested but it doesn't seem to
> >>> work.
> >>> Could you be more specific? Here's what I've tried:
> >>>
> >>> void register_hooks(apr_pool_t *p)
> >>> {
> >>>    ap_hook_translate_name(hook_translate_name, NULL, NULL,
> >>> APR_HOOK_REALLY_FIRST);
> >>>    ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
> >>> APR_HOOK_MIDDLE);
> >>>    ap_register_output_filter("wms-error-http-header",
> >>> wmserror_ofilter,
> >>>            NULL, AP_FTYPE_CONNECTION) ;
> >>> }
> >>>
> >>> static int hook_translate_name (request_rec *r)
> >>> {
> >>>    apr_table_setn(r->notes, "MY_NOTE", ".");
> >>>    ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> >>>    return HTTP_INTERNAL_SERVER_ERROR;
> >>> }
> >>>
> >>> static int hook_pre_connection(conn_rec *c, void *csd)
> >>> {
> >>>    ap_add_output_filter("wms-error-httpd-header", NULL, NULL, c);
> >>>    return OK;
> >>> }
> >>>
> >>> int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
> >>> {
> >>>    const char *t = apr_table_get(f->r->notes, "MY_NOTE");
> >>>    if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
> >>>    return ap_pass_brigade(f->next, bb) ;
> >>> }
> >>>
> >>
> >> My guess would be you can't use ap_set_content_type in your filter,
> >> you will have to examine the buckets, find Conetent-Type and change  
> >> it
> >> to text/xml.
> >>
> >> Below is a quick hack I created from code we use to remove the server
> >> header and insert the host comment.  It may not work perfectly out of
> >> the box, but by adding some log lines you should be able to get it
> >> working.
> >>
> >> This also assume the headers will fit in a 8k brigade.
> >>
> >> Brian
> >>
> >>
> >>
> >> /* Because strnstr is not on RHEL4 */
> >> static char *__strnstr(const char *big, const char *little, size_t  
> >> len)
> >> {
> >>     size_t little_len = strlen(little);
> >>     size_t i;
> >>     for (i = 0; i <= len - little_len; i++) {
> >>         if (memcmp(big + i, little, little_len) == 0) {
> >>             return (char *)(big + i);
> >>         }
> >>     }
> >>
> >>     return 0;
> >> }
> >>
> >> static apr_status_t wmserror_output_filter(ap_filter_t *f,
> >> apr_bucket_brigade *in)
> >> {
> >>   if (f->r != NULL && apr_table_get(f->r->notes, "MY_NOTE") !=  
> >> NULL) {
> >>
> >>     apr_bucket *b;
> >>
> >>     for (b = APR_BRIGADE_FIRST(in); b != APR_BRIGADE_SENTINEL(in) &&
> >> done == 0; b = APR_BUCKET_NEXT(b)) {
> >>       const char *buf;
> >>       size_t bytes ;
> >>
> >>       if (!(APR_BUCKET_IS_METADATA(b))) {
> >>         if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) ==
> >> APR_SUCCESS) {
> >>           char *ct_header = __strnstr(buf, "Content-Type: ", bytes);
> >>           char *end;
> >>           if (cl_header != NULL && (end = strstr(ct_header, "\n")) !=
> >> NULL) {
> >>             apr_bucket *newb = NULL;
> >>             apr_bucket *new_ct;
> >>
> >>             /* split off buffer at the ct header */
> >>             apr_bucket_split(b, ct_header +  14 - buf);
> >>
> >>             /* skip to the ct value bucket */
> >>             b = APR_BUCKET_NEXT(b);
> >>
> >>             /* split off after value */
> >>             apr_bucket_split(b, end - ct_header + 14 + 1);
> >>
> >>             /* skip to the next one */
> >>             newb = APR_BUCKET_NEXT(b);
> >>
> >>             /* remove it */
> >>             APR_BUCKET_REMOVE(b);
> >>
> >>             /* nuke it */
> >>             apr_bucket_destroy(b);
> >>
> >>             b = newb;
> >>
> >>             /* I think this is the right function */
> >>             new_ct = apr_bucket_immortal_create("text/xml",
> >> sizeof("text/xml"), f->c->bucket_alloc);
> >>
> >>             APR_BUCKET_INSERT_BEFORE(b, new_ct);
> >>
> >>             apr_table_unset(f->r->notes, "MY_NOTE");
> >>             break;
> >>           }
> >>         }
> >>       }
> >>     }
> >>   }
> >>
> >>   /* send the data up the stack */
> >>   return ap_pass_brigade(f->next,in);
> >> }
> >>
> >>
> >>
> >> static void wmserror_insert_output_filter(request_rec *r)
> >> {
> >>     ap_add_output_filter("WMSERROR_OUTPUT_FILTER", NULL, r, r-
> >>> connection);
> >> }
> >>
> >> static void register_hooks(apr_pool_t *p)
> >> {
> >>     ap_register_output_filter("WMSERROR_OUTPUT_FILTER",
> >> wmserror_output_filter, NULL, AP_FTYPE_PROTOCOL);
> >>
> >>     ap_hook_insert_filter(wmserror_insert_output_filter, NULL, NULL,
> >> APR_HOOK_REALLY_LAST);
> >> }
> >>
> >>
> >>
> >>
> >>>
> >>>
> >>> On Thu, 2008-06-26 at 08:35 -0400, Brian J. France wrote:
> >>>> On Jun 26, 2008, at 3:33 AM, Kiffin Gish wrote:
> >>>>> In order to reply with my own xml error, I want to use
> >>>>> ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> >>>>>
> >>>>> However, default content type is "text/html". If I try to change
> >>> it by
> >>>>> using ap_set_content_type(r, "text/xml"), this has no effect.
> >>>>>
> >>>>> Is there anyone out there who can help me?
> >>>>>
> >>>>
> >>>> Ran into the same thing with apache 1.3.  We have a patch that
> >>> adds a
> >>>> custom hook that is called before headers are sent and we can re- 
> >>>> set
> >>>> it back to text/xml there (remember this is 1.3).
> >>>>
> >>>> You could call ap_custom_response, set a flag in r->notes, have a
> >>>> output filter in your module that checks r->notes and if the flag
> >>> set
> >>>> it scans for Content-type and resets it to text/xml.
> >>>>
> >>>> Brian
> >>>>
> >>> --
> >>> Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com
> >>> | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> >>
> > -- 
> > Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com 
> >  | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> >
> >
> > This e-mail message contains information which is confidential and  
> > may be privileged. It is intended for use by the addressee only. If  
> > you are not the intended addressee, we request that you notify the  
> > sender immediately and delete or destroy this e-mail message and any  
> > attachment(s), without copying, saving, forwarding, disclosing or  
> > using its contents in any other way. TomTom N.V., TomTom  
> > International BV or any other company belonging to the TomTom group  
> > of companies will not be liable for damage relating to the  
> > communication by e-mail of data, documents or any other information.
> 
-- 
Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office

Re: ap_custom_response content type 'text/xml'

Posted by "Brian J. France" <li...@firehawksystems.com>.
On Jun 27, 2008, at 4:00 AM, Kiffin Gish wrote:

> Brian,
>
> This is great, thanks alot!
>
> I've 'almost' got it working correctly, the only problem being that  
> the
> Content-Type is not getting truncated correctly, e.g. instead of:
>
> Content-Type: text/xml\n
> \n
> <?xml version='1.0' encoding="UTF-8" standalone="no" ?>\n
>
>
> I'm getting this:
>
> Content-Type: text/xml<?xml version='1.0' encoding="UTF-8"
> standalone="no" ?>\n
>
> Any tips would be greatly appreciated.


In my example it looks for \n for the end of the line and to calculate  
the split it add +1 to the value (to grab the \r).

I think you can change +1 to -1 and it should keep the \n\r at the end  
of the header.

Brian




>
>
>
> On Thu, 2008-06-26 at 10:29 -0400, Brian J. France wrote:
>> On Jun 26, 2008, at 9:48 AM, Kiffin Gish wrote:
>>> Thanks Brian, I've tried what you suggested but it doesn't seem to
>>> work.
>>> Could you be more specific? Here's what I've tried:
>>>
>>> void register_hooks(apr_pool_t *p)
>>> {
>>>    ap_hook_translate_name(hook_translate_name, NULL, NULL,
>>> APR_HOOK_REALLY_FIRST);
>>>    ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
>>> APR_HOOK_MIDDLE);
>>>    ap_register_output_filter("wms-error-http-header",
>>> wmserror_ofilter,
>>>            NULL, AP_FTYPE_CONNECTION) ;
>>> }
>>>
>>> static int hook_translate_name (request_rec *r)
>>> {
>>>    apr_table_setn(r->notes, "MY_NOTE", ".");
>>>    ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
>>>    return HTTP_INTERNAL_SERVER_ERROR;
>>> }
>>>
>>> static int hook_pre_connection(conn_rec *c, void *csd)
>>> {
>>>    ap_add_output_filter("wms-error-httpd-header", NULL, NULL, c);
>>>    return OK;
>>> }
>>>
>>> int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
>>> {
>>>    const char *t = apr_table_get(f->r->notes, "MY_NOTE");
>>>    if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
>>>    return ap_pass_brigade(f->next, bb) ;
>>> }
>>>
>>
>> My guess would be you can't use ap_set_content_type in your filter,
>> you will have to examine the buckets, find Conetent-Type and change  
>> it
>> to text/xml.
>>
>> Below is a quick hack I created from code we use to remove the server
>> header and insert the host comment.  It may not work perfectly out of
>> the box, but by adding some log lines you should be able to get it
>> working.
>>
>> This also assume the headers will fit in a 8k brigade.
>>
>> Brian
>>
>>
>>
>> /* Because strnstr is not on RHEL4 */
>> static char *__strnstr(const char *big, const char *little, size_t  
>> len)
>> {
>>     size_t little_len = strlen(little);
>>     size_t i;
>>     for (i = 0; i <= len - little_len; i++) {
>>         if (memcmp(big + i, little, little_len) == 0) {
>>             return (char *)(big + i);
>>         }
>>     }
>>
>>     return 0;
>> }
>>
>> static apr_status_t wmserror_output_filter(ap_filter_t *f,
>> apr_bucket_brigade *in)
>> {
>>   if (f->r != NULL && apr_table_get(f->r->notes, "MY_NOTE") !=  
>> NULL) {
>>
>>     apr_bucket *b;
>>
>>     for (b = APR_BRIGADE_FIRST(in); b != APR_BRIGADE_SENTINEL(in) &&
>> done == 0; b = APR_BUCKET_NEXT(b)) {
>>       const char *buf;
>>       size_t bytes ;
>>
>>       if (!(APR_BUCKET_IS_METADATA(b))) {
>>         if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) ==
>> APR_SUCCESS) {
>>           char *ct_header = __strnstr(buf, "Content-Type: ", bytes);
>>           char *end;
>>           if (cl_header != NULL && (end = strstr(ct_header, "\n")) !=
>> NULL) {
>>             apr_bucket *newb = NULL;
>>             apr_bucket *new_ct;
>>
>>             /* split off buffer at the ct header */
>>             apr_bucket_split(b, ct_header +  14 - buf);
>>
>>             /* skip to the ct value bucket */
>>             b = APR_BUCKET_NEXT(b);
>>
>>             /* split off after value */
>>             apr_bucket_split(b, end - ct_header + 14 + 1);
>>
>>             /* skip to the next one */
>>             newb = APR_BUCKET_NEXT(b);
>>
>>             /* remove it */
>>             APR_BUCKET_REMOVE(b);
>>
>>             /* nuke it */
>>             apr_bucket_destroy(b);
>>
>>             b = newb;
>>
>>             /* I think this is the right function */
>>             new_ct = apr_bucket_immortal_create("text/xml",
>> sizeof("text/xml"), f->c->bucket_alloc);
>>
>>             APR_BUCKET_INSERT_BEFORE(b, new_ct);
>>
>>             apr_table_unset(f->r->notes, "MY_NOTE");
>>             break;
>>           }
>>         }
>>       }
>>     }
>>   }
>>
>>   /* send the data up the stack */
>>   return ap_pass_brigade(f->next,in);
>> }
>>
>>
>>
>> static void wmserror_insert_output_filter(request_rec *r)
>> {
>>     ap_add_output_filter("WMSERROR_OUTPUT_FILTER", NULL, r, r-
>>> connection);
>> }
>>
>> static void register_hooks(apr_pool_t *p)
>> {
>>     ap_register_output_filter("WMSERROR_OUTPUT_FILTER",
>> wmserror_output_filter, NULL, AP_FTYPE_PROTOCOL);
>>
>>     ap_hook_insert_filter(wmserror_insert_output_filter, NULL, NULL,
>> APR_HOOK_REALLY_LAST);
>> }
>>
>>
>>
>>
>>>
>>>
>>> On Thu, 2008-06-26 at 08:35 -0400, Brian J. France wrote:
>>>> On Jun 26, 2008, at 3:33 AM, Kiffin Gish wrote:
>>>>> In order to reply with my own xml error, I want to use
>>>>> ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
>>>>>
>>>>> However, default content type is "text/html". If I try to change
>>> it by
>>>>> using ap_set_content_type(r, "text/xml"), this has no effect.
>>>>>
>>>>> Is there anyone out there who can help me?
>>>>>
>>>>
>>>> Ran into the same thing with apache 1.3.  We have a patch that
>>> adds a
>>>> custom hook that is called before headers are sent and we can re- 
>>>> set
>>>> it back to text/xml there (remember this is 1.3).
>>>>
>>>> You could call ap_custom_response, set a flag in r->notes, have a
>>>> output filter in your module that checks r->notes and if the flag
>>> set
>>>> it scans for Content-type and resets it to text/xml.
>>>>
>>>> Brian
>>>>
>>> --
>>> Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com
>>> | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
>>
> -- 
> Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com 
>  | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
>
>
> This e-mail message contains information which is confidential and  
> may be privileged. It is intended for use by the addressee only. If  
> you are not the intended addressee, we request that you notify the  
> sender immediately and delete or destroy this e-mail message and any  
> attachment(s), without copying, saving, forwarding, disclosing or  
> using its contents in any other way. TomTom N.V., TomTom  
> International BV or any other company belonging to the TomTom group  
> of companies will not be liable for damage relating to the  
> communication by e-mail of data, documents or any other information.


Re: ap_custom_response content type 'text/xml'

Posted by Kiffin Gish <Ki...@tomtom.com>.
Brian,

This is great, thanks alot!

I've 'almost' got it working correctly, the only problem being that the
Content-Type is not getting truncated correctly, e.g. instead of:

Content-Type: text/xml\n
\n
<?xml version='1.0' encoding="UTF-8" standalone="no" ?>\n


I'm getting this:

Content-Type: text/xml<?xml version='1.0' encoding="UTF-8"
standalone="no" ?>\n

Any tips would be greatly appreciated.


On Thu, 2008-06-26 at 10:29 -0400, Brian J. France wrote:
> On Jun 26, 2008, at 9:48 AM, Kiffin Gish wrote:
> > Thanks Brian, I've tried what you suggested but it doesn't seem to  
> > work.
> > Could you be more specific? Here's what I've tried:
> >
> > void register_hooks(apr_pool_t *p)
> > {
> >     ap_hook_translate_name(hook_translate_name, NULL, NULL,
> > APR_HOOK_REALLY_FIRST);
> >     ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
> > APR_HOOK_MIDDLE);
> >     ap_register_output_filter("wms-error-http-header",  
> > wmserror_ofilter,
> >             NULL, AP_FTYPE_CONNECTION) ;
> > }
> >
> > static int hook_translate_name (request_rec *r)
> > {
> >     apr_table_setn(r->notes, "MY_NOTE", ".");
> >     ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> >     return HTTP_INTERNAL_SERVER_ERROR;
> > }
> >
> > static int hook_pre_connection(conn_rec *c, void *csd)
> > {
> >     ap_add_output_filter("wms-error-httpd-header", NULL, NULL, c);
> >     return OK;
> > }
> >
> > int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
> > {
> >     const char *t = apr_table_get(f->r->notes, "MY_NOTE");
> >     if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
> >     return ap_pass_brigade(f->next, bb) ;
> > }
> >
> 
> My guess would be you can't use ap_set_content_type in your filter,  
> you will have to examine the buckets, find Conetent-Type and change it  
> to text/xml.
> 
> Below is a quick hack I created from code we use to remove the server  
> header and insert the host comment.  It may not work perfectly out of  
> the box, but by adding some log lines you should be able to get it  
> working.
> 
> This also assume the headers will fit in a 8k brigade.
> 
> Brian
> 
> 
> 
> /* Because strnstr is not on RHEL4 */
> static char *__strnstr(const char *big, const char *little, size_t len)
> {
>      size_t little_len = strlen(little);
>      size_t i;
>      for (i = 0; i <= len - little_len; i++) {
>          if (memcmp(big + i, little, little_len) == 0) {
>              return (char *)(big + i);
>          }
>      }
> 
>      return 0;
> }
> 
> static apr_status_t wmserror_output_filter(ap_filter_t *f,  
> apr_bucket_brigade *in)
> {
>    if (f->r != NULL && apr_table_get(f->r->notes, "MY_NOTE") != NULL) {
> 
>      apr_bucket *b;
> 
>      for (b = APR_BRIGADE_FIRST(in); b != APR_BRIGADE_SENTINEL(in) &&  
> done == 0; b = APR_BUCKET_NEXT(b)) {
>        const char *buf;
>        size_t bytes ;
> 
>        if (!(APR_BUCKET_IS_METADATA(b))) {
>          if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) ==  
> APR_SUCCESS) {
>            char *ct_header = __strnstr(buf, "Content-Type: ", bytes);
>            char *end;
>            if (cl_header != NULL && (end = strstr(ct_header, "\n")) !=  
> NULL) {
>              apr_bucket *newb = NULL;
>              apr_bucket *new_ct;
> 
>              /* split off buffer at the ct header */
>              apr_bucket_split(b, ct_header +  14 - buf);
> 
>              /* skip to the ct value bucket */
>              b = APR_BUCKET_NEXT(b);
> 
>              /* split off after value */
>              apr_bucket_split(b, end - ct_header + 14 + 1);
> 
>              /* skip to the next one */
>              newb = APR_BUCKET_NEXT(b);
> 
>              /* remove it */
>              APR_BUCKET_REMOVE(b);
> 
>              /* nuke it */
>              apr_bucket_destroy(b);
> 
>              b = newb;
> 
>              /* I think this is the right function */
>              new_ct = apr_bucket_immortal_create("text/xml",  
> sizeof("text/xml"), f->c->bucket_alloc);
> 
>              APR_BUCKET_INSERT_BEFORE(b, new_ct);
> 
>              apr_table_unset(f->r->notes, "MY_NOTE");
>              break;
>            }
>          }
>        }
>      }
>    }
> 
>    /* send the data up the stack */
>    return ap_pass_brigade(f->next,in);
> }
> 
> 
> 
> static void wmserror_insert_output_filter(request_rec *r)
> {
>      ap_add_output_filter("WMSERROR_OUTPUT_FILTER", NULL, r, r- 
>  >connection);
> }
> 
> static void register_hooks(apr_pool_t *p)
> {
>      ap_register_output_filter("WMSERROR_OUTPUT_FILTER",  
> wmserror_output_filter, NULL, AP_FTYPE_PROTOCOL);
> 
>      ap_hook_insert_filter(wmserror_insert_output_filter, NULL, NULL,  
> APR_HOOK_REALLY_LAST);
> }
> 
> 
> 
> 
> >
> >
> > On Thu, 2008-06-26 at 08:35 -0400, Brian J. France wrote:
> > > On Jun 26, 2008, at 3:33 AM, Kiffin Gish wrote:
> > > > In order to reply with my own xml error, I want to use
> > > > ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> > > >
> > > > However, default content type is "text/html". If I try to change  
> > it by
> > > > using ap_set_content_type(r, "text/xml"), this has no effect.
> > > >
> > > > Is there anyone out there who can help me?
> > > >
> > >
> > > Ran into the same thing with apache 1.3.  We have a patch that  
> > adds a
> > > custom hook that is called before headers are sent and we can re-set
> > > it back to text/xml there (remember this is 1.3).
> > >
> > > You could call ap_custom_response, set a flag in r->notes, have a
> > > output filter in your module that checks r->notes and if the flag  
> > set
> > > it scans for Content-type and resets it to text/xml.
> > >
> > > Brian
> > >
> > --
> > Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com 
> >  | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> 
-- 
Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office


This e-mail message contains information which is confidential and may be privileged. It is intended for use by the addressee only. If you are not the intended addressee, we request that you notify the sender immediately and delete or destroy this e-mail message and any attachment(s), without copying, saving, forwarding, disclosing or using its contents in any other way. TomTom N.V., TomTom International BV or any other company belonging to the TomTom group of companies will not be liable for damage relating to the communication by e-mail of data, documents or any other information.

Re: ap_custom_response content type 'text/xml'

Posted by Ruediger Pluem <rp...@apache.org>.

On 06/26/2008 08:13 PM, Kiffin Gish wrote:
> Don't see filter type HTTP_HEADER, is this also part of apache 2.2.x?
> 

It is not a type but a concrete filter. Can be found in modules/http/http_filters.c
and modules/http/http_core.c

Regards

Rüdiger


Re: ap_custom_response content type 'text/xml'

Posted by Kiffin Gish <Ki...@tomtom.com>.
Don't see filter type HTTP_HEADER, is this also part of apache 2.2.x?

On Thu, 2008-06-26 at 16:36 +0200, "Plüm, Rüdiger, VF-Group" wrote:
> 
> > -----Ursprüngliche Nachricht-----
> > Von: Brian J. France 
> > Gesendet: Donnerstag, 26. Juni 2008 16:29
> > An: dev@httpd.apache.org
> > Betreff: Re: ap_custom_response content type 'text/xml'
> > 
> > 
> > On Jun 26, 2008, at 9:48 AM, Kiffin Gish wrote:
> > > Thanks Brian, I've tried what you suggested but it doesn't seem to  
> > > work.
> > > Could you be more specific? Here's what I've tried:
> > >
> > > void register_hooks(apr_pool_t *p)
> > > {
> > >     ap_hook_translate_name(hook_translate_name, NULL, NULL,
> > > APR_HOOK_REALLY_FIRST);
> > >     ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
> > > APR_HOOK_MIDDLE);
> > >     ap_register_output_filter("wms-error-http-header",  
> > > wmserror_ofilter,
> > >             NULL, AP_FTYPE_CONNECTION) ;
> > > }
> > >
> > > static int hook_translate_name (request_rec *r)
> > > {
> > >     apr_table_setn(r->notes, "MY_NOTE", ".");
> > >     ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> > >     return HTTP_INTERNAL_SERVER_ERROR;
> > > }
> > >
> > > static int hook_pre_connection(conn_rec *c, void *csd)
> > > {
> > >     ap_add_output_filter("wms-error-httpd-header", NULL, NULL, c);
> > >     return OK;
> > > }
> > >
> > > int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
> > > {
> > >     const char *t = apr_table_get(f->r->notes, "MY_NOTE");
> > >     if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
> > >     return ap_pass_brigade(f->next, bb) ;
> > > }
> > >
> > 
> > My guess would be you can't use ap_set_content_type in your filter,  
> > you will have to examine the buckets, find Conetent-Type and 
> > change it  
> > to text/xml.
> 
> You can, but you must ensure that your filter runs before the http header
> filter (HTTP_HEADER).
> 
> Regards
> 
> Rüdiger
> 
-- 
Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office


This e-mail message contains information which is confidential and may be privileged. It is intended for use by the addressee only. If you are not the intended addressee, we request that you notify the sender immediately and delete or destroy this e-mail message and any attachment(s), without copying, saving, forwarding, disclosing or using its contents in any other way. TomTom N.V., TomTom International BV or any other company belonging to the TomTom group of companies will not be liable for damage relating to the communication by e-mail of data, documents or any other information.

Re: ap_custom_response content type 'text/xml'

Posted by "Plüm, Rüdiger, VF-Group" <ru...@vodafone.com>.
 

> -----Ursprüngliche Nachricht-----
> Von: Brian J. France 
> Gesendet: Donnerstag, 26. Juni 2008 16:29
> An: dev@httpd.apache.org
> Betreff: Re: ap_custom_response content type 'text/xml'
> 
> 
> On Jun 26, 2008, at 9:48 AM, Kiffin Gish wrote:
> > Thanks Brian, I've tried what you suggested but it doesn't seem to  
> > work.
> > Could you be more specific? Here's what I've tried:
> >
> > void register_hooks(apr_pool_t *p)
> > {
> >     ap_hook_translate_name(hook_translate_name, NULL, NULL,
> > APR_HOOK_REALLY_FIRST);
> >     ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
> > APR_HOOK_MIDDLE);
> >     ap_register_output_filter("wms-error-http-header",  
> > wmserror_ofilter,
> >             NULL, AP_FTYPE_CONNECTION) ;
> > }
> >
> > static int hook_translate_name (request_rec *r)
> > {
> >     apr_table_setn(r->notes, "MY_NOTE", ".");
> >     ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> >     return HTTP_INTERNAL_SERVER_ERROR;
> > }
> >
> > static int hook_pre_connection(conn_rec *c, void *csd)
> > {
> >     ap_add_output_filter("wms-error-httpd-header", NULL, NULL, c);
> >     return OK;
> > }
> >
> > int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
> > {
> >     const char *t = apr_table_get(f->r->notes, "MY_NOTE");
> >     if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
> >     return ap_pass_brigade(f->next, bb) ;
> > }
> >
> 
> My guess would be you can't use ap_set_content_type in your filter,  
> you will have to examine the buckets, find Conetent-Type and 
> change it  
> to text/xml.

You can, but you must ensure that your filter runs before the http header
filter (HTTP_HEADER).

Regards

Rüdiger


Re: ap_custom_response content type 'text/xml'

Posted by "Brian J. France" <li...@firehawksystems.com>.
On Jun 26, 2008, at 9:48 AM, Kiffin Gish wrote:
> Thanks Brian, I've tried what you suggested but it doesn't seem to  
> work.
> Could you be more specific? Here's what I've tried:
>
> void register_hooks(apr_pool_t *p)
> {
>     ap_hook_translate_name(hook_translate_name, NULL, NULL,
> APR_HOOK_REALLY_FIRST);
>     ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
> APR_HOOK_MIDDLE);
>     ap_register_output_filter("wms-error-http-header",  
> wmserror_ofilter,
>             NULL, AP_FTYPE_CONNECTION) ;
> }
>
> static int hook_translate_name (request_rec *r)
> {
>     apr_table_setn(r->notes, "MY_NOTE", ".");
>     ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
>     return HTTP_INTERNAL_SERVER_ERROR;
> }
>
> static int hook_pre_connection(conn_rec *c, void *csd)
> {
>     ap_add_output_filter("wms-error-httpd-header", NULL, NULL, c);
>     return OK;
> }
>
> int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
> {
>     const char *t = apr_table_get(f->r->notes, "MY_NOTE");
>     if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
>     return ap_pass_brigade(f->next, bb) ;
> }
>

My guess would be you can't use ap_set_content_type in your filter,  
you will have to examine the buckets, find Conetent-Type and change it  
to text/xml.

Below is a quick hack I created from code we use to remove the server  
header and insert the host comment.  It may not work perfectly out of  
the box, but by adding some log lines you should be able to get it  
working.

This also assume the headers will fit in a 8k brigade.

Brian



/* Because strnstr is not on RHEL4 */
static char *__strnstr(const char *big, const char *little, size_t len)
{
     size_t little_len = strlen(little);
     size_t i;
     for (i = 0; i <= len - little_len; i++) {
         if (memcmp(big + i, little, little_len) == 0) {
             return (char *)(big + i);
         }
     }

     return 0;
}

static apr_status_t wmserror_output_filter(ap_filter_t *f,  
apr_bucket_brigade *in)
{
   if (f->r != NULL && apr_table_get(f->r->notes, "MY_NOTE") != NULL) {

     apr_bucket *b;

     for (b = APR_BRIGADE_FIRST(in); b != APR_BRIGADE_SENTINEL(in) &&  
done == 0; b = APR_BUCKET_NEXT(b)) {
       const char *buf;
       size_t bytes ;

       if (!(APR_BUCKET_IS_METADATA(b))) {
         if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) ==  
APR_SUCCESS) {
           char *ct_header = __strnstr(buf, "Content-Type: ", bytes);
           char *end;
           if (cl_header != NULL && (end = strstr(ct_header, "\n")) !=  
NULL) {
             apr_bucket *newb = NULL;
             apr_bucket *new_ct;

             /* split off buffer at the ct header */
             apr_bucket_split(b, ct_header +  14 - buf);

             /* skip to the ct value bucket */
             b = APR_BUCKET_NEXT(b);

             /* split off after value */
             apr_bucket_split(b, end - ct_header + 14 + 1);

             /* skip to the next one */
             newb = APR_BUCKET_NEXT(b);

             /* remove it */
             APR_BUCKET_REMOVE(b);

             /* nuke it */
             apr_bucket_destroy(b);

             b = newb;

             /* I think this is the right function */
             new_ct = apr_bucket_immortal_create("text/xml",  
sizeof("text/xml"), f->c->bucket_alloc);

             APR_BUCKET_INSERT_BEFORE(b, new_ct);

             apr_table_unset(f->r->notes, "MY_NOTE");
             break;
           }
         }
       }
     }
   }

   /* send the data up the stack */
   return ap_pass_brigade(f->next,in);
}



static void wmserror_insert_output_filter(request_rec *r)
{
     ap_add_output_filter("WMSERROR_OUTPUT_FILTER", NULL, r, r- 
 >connection);
}

static void register_hooks(apr_pool_t *p)
{
     ap_register_output_filter("WMSERROR_OUTPUT_FILTER",  
wmserror_output_filter, NULL, AP_FTYPE_PROTOCOL);

     ap_hook_insert_filter(wmserror_insert_output_filter, NULL, NULL,  
APR_HOOK_REALLY_LAST);
}




>
>
> On Thu, 2008-06-26 at 08:35 -0400, Brian J. France wrote:
> > On Jun 26, 2008, at 3:33 AM, Kiffin Gish wrote:
> > > In order to reply with my own xml error, I want to use
> > > ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> > >
> > > However, default content type is "text/html". If I try to change  
> it by
> > > using ap_set_content_type(r, "text/xml"), this has no effect.
> > >
> > > Is there anyone out there who can help me?
> > >
> >
> > Ran into the same thing with apache 1.3.  We have a patch that  
> adds a
> > custom hook that is called before headers are sent and we can re-set
> > it back to text/xml there (remember this is 1.3).
> >
> > You could call ap_custom_response, set a flag in r->notes, have a
> > output filter in your module that checks r->notes and if the flag  
> set
> > it scans for Content-type and resets it to text/xml.
> >
> > Brian
> >
> --
> Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com 
>  | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office


Re: ap_custom_response content type 'text/xml'

Posted by Kiffin Gish <Ki...@tomtom.com>.
Thanks Brian, I've tried what you suggested but it doesn't seem to work.
Could you be more specific? Here's what I've tried:

void register_hooks(apr_pool_t *p)
{
    ap_hook_translate_name(hook_translate_name, NULL, NULL,
APR_HOOK_REALLY_FIRST);
    ap_hook_pre_connection(hook_pre_connection, NULL, NULL,
APR_HOOK_MIDDLE);
    ap_register_output_filter("wms-error-http-header", wmserror_ofilter,
	    NULL, AP_FTYPE_CONNECTION) ;
}

static int hook_translate_name (request_rec *r)
{
    apr_table_setn(r->notes, "MY_NOTE", ".");
    ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
    return HTTP_INTERNAL_SERVER_ERROR;
}

static int hook_pre_connection(conn_rec *c, void *csd)
{
    ap_add_output_filter("wms-error-httpd-header", NULL, NULL, c);
    return OK;
}

int wmserror_ofilter(ap_filter_t* f, apr_bucket_brigade* bb)
{
    const char *t = apr_table_get(f->r->notes, "MY_NOTE");
    if (t != NULL) { ap_set_content_type(f->r, "text/xml"); }
    return ap_pass_brigade(f->next, bb) ;
}

On Thu, 2008-06-26 at 08:35 -0400, Brian J. France wrote:
> On Jun 26, 2008, at 3:33 AM, Kiffin Gish wrote:
> > In order to reply with my own xml error, I want to use
> > ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
> >
> > However, default content type is "text/html". If I try to change it by
> > using ap_set_content_type(r, "text/xml"), this has no effect.
> >
> > Is there anyone out there who can help me?
> >
> 
> Ran into the same thing with apache 1.3.  We have a patch that adds a  
> custom hook that is called before headers are sent and we can re-set  
> it back to text/xml there (remember this is 1.3).
> 
> You could call ap_custom_response, set a flag in r->notes, have a  
> output filter in your module that checks r->notes and if the flag set  
> it scans for Content-type and resets it to text/xml.
> 
> Brian
> 
-- 
Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office

Re: ap_custom_response content type 'text/xml'

Posted by "Brian J. France" <li...@firehawksystems.com>.
On Jun 26, 2008, at 3:33 AM, Kiffin Gish wrote:
> In order to reply with my own xml error, I want to use
> ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
>
> However, default content type is "text/html". If I try to change it by
> using ap_set_content_type(r, "text/xml"), this has no effect.
>
> Is there anyone out there who can help me?
>

Ran into the same thing with apache 1.3.  We have a patch that adds a  
custom hook that is called before headers are sent and we can re-set  
it back to text/xml there (remember this is 1.3).

You could call ap_custom_response, set a flag in r->notes, have a  
output filter in your module that checks r->notes and if the flag set  
it scans for Content-type and resets it to text/xml.

Brian


Re: ap_custom_response content type 'text/xml'

Posted by Jeff Trawick <tr...@gmail.com>.
On Thu, Jun 26, 2008 at 8:30 AM, Kiffin Gish <Ki...@tomtom.com> wrote:

> What do you mean by a special uri space? You're not referring to
> something like a separate cgi-script are you? That's exactly what I was
> trying top get away from by implementing ap_custom_response() in the
> first place...


e.g., /myapp/errordoc/this_particular_error.xml

It can be handled by a handler in your module; you don't need a CGI.  This
would potentially lend itself to letting users customize error responses by
mapping the special error URI to an alternate filesystem path.

The output filter idea from Brian would also be fine.

Re: ap_custom_response content type 'text/xml'

Posted by Kiffin Gish <Ki...@tomtom.com>.
What do you mean by a special uri space? You're not referring to
something like a separate cgi-script are you? That's exactly what I was
trying top get away from by implementing ap_custom_response() in the
first place...

On Thu, 2008-06-26 at 06:56 -0400, Jeff Trawick wrote:
> On Thu, Jun 26, 2008 at 3:33 AM, Kiffin Gish <Ki...@tomtom.com>
> wrote:
>         In order to reply with my own xml error, I want to use
>         ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
>         
>         However, default content type is "text/html". If I try to
>         change it by
>         using ap_set_content_type(r, "text/xml"), this has no effect.
>         
>         
>         
> (The ap_custom_response() API is busted and needs to allow (FORCE) the
> caller to pass in the content type/charset to associate with the
> response text.)
> 
> You can pass a URI to ap_custom_response (as on the ErrorDocument
> directive) to redirect error requests to a special uri space, and
> implement a handler for those which can control the response more
> fully.
> 
> 
> (Hopefully there are some better ideas out there.)
> 
-- 
Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@tomtom.com | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office


This e-mail message contains information which is confidential and may be privileged. It is intended for use by the addressee only. If you are not the intended addressee, we request that you notify the sender immediately and delete or destroy this e-mail message and any attachment(s), without copying, saving, forwarding, disclosing or using its contents in any other way. TomTom N.V., TomTom International BV or any other company belonging to the TomTom group of companies will not be liable for damage relating to the communication by e-mail of data, documents or any other information.

Re: ap_custom_response content type 'text/xml'

Posted by Jeff Trawick <tr...@gmail.com>.
On Thu, Jun 26, 2008 at 3:33 AM, Kiffin Gish <Ki...@tomtom.com> wrote:

>  In order to reply with my own xml error, I want to use
> ap_custom_response(r, HTTP_INTERNAL_SERVER_ERROR, xml);
>
> However, default content type is "text/html". If I try to change it by
> using ap_set_content_type(r, "text/xml"), this has no effect.
>
(The ap_custom_response() API is busted and needs to allow (FORCE) the
caller to pass in the content type/charset to associate with the response
text.)

You can pass a URI to ap_custom_response (as on the ErrorDocument directive)
to redirect error requests to a special uri space, and implement a handler
for those which can control the response more fully.

(Hopefully there are some better ideas out there.)