httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Brian J. France" <l...@firehawksystems.com>
Subject Re: ap_custom_response content type 'text/xml'
Date Fri, 27 Jun 2008 13:02:48 GMT

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.


Mime
View raw message