Re: ap_custom_response content type 'text/xml'

Top Page

Reply to this message
Author: Brian J. France
Date:  
To: dev
Subject: Re: ap_custom_response content type 'text/xml'

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@???
> > >>> | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office
> > >>
> > > --
> > > Kiffin Gish | Desktop & Services Development | TomTom | kiffin.gish@???
> > > | +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@???
> | +31 (0) 6 15529214 mobile | +31 (0) 20 757 5000 office