| 3071 | } |
| 3072 | |
| 3073 | static int handle_multi(request_rec *r) |
| 3074 | { |
| 3075 | negotiation_state *neg; |
| 3076 | var_rec *best, *avail_recs; |
| 3077 | request_rec *sub_req; |
| 3078 | int res; |
| 3079 | int j; |
| 3080 | |
| 3081 | if (r->finfo.filetype != APR_NOFILE |
| 3082 | || !(ap_allow_options(r) & OPT_MULTI)) { |
| 3083 | return DECLINED; |
| 3084 | } |
| 3085 | |
| 3086 | neg = parse_accept_headers(r); |
| 3087 | |
| 3088 | if ((res = read_types_multi(neg))) { |
| 3089 | return_from_multi: |
| 3090 | /* free all allocated memory from subrequests */ |
| 3091 | avail_recs = (var_rec *) neg->avail_vars->elts; |
| 3092 | for (j = 0; j < neg->avail_vars->nelts; ++j) { |
| 3093 | var_rec *variant = &avail_recs[j]; |
| 3094 | if (variant->sub_req) { |
| 3095 | ap_destroy_sub_req(variant->sub_req); |
| 3096 | } |
| 3097 | } |
| 3098 | return res; |
| 3099 | } |
| 3100 | if (neg->avail_vars->nelts == 0) { |
| 3101 | return DECLINED; |
| 3102 | } |
| 3103 | |
| 3104 | res = do_negotiation(r, neg, &best, |
| 3105 | (r->method_number != M_GET) || r->args || |
| 3106 | (r->path_info && *r->path_info)); |
| 3107 | if (res != 0) |
| 3108 | goto return_from_multi; |
| 3109 | |
| 3110 | if (!(sub_req = best->sub_req)) { |
| 3111 | /* We got this out of a map file, so we don't actually have |
| 3112 | * a sub_req structure yet. Get one now. |
| 3113 | */ |
| 3114 | |
| 3115 | sub_req = ap_sub_req_lookup_file(best->file_name, r, r->output_filters); |
| 3116 | if (sub_req->status != HTTP_OK) { |
| 3117 | res = sub_req->status; |
| 3118 | ap_destroy_sub_req(sub_req); |
| 3119 | goto return_from_multi; |
| 3120 | } |
| 3121 | } |
| 3122 | if (sub_req->args == NULL) { |
| 3123 | sub_req->args = r->args; |
| 3124 | } |
| 3125 | |
| 3126 | /* now do a "fast redirect" ... promotes the sub_req into the main req */ |
| 3127 | ap_internal_fast_redirect(sub_req, r); |
| 3128 | |
| 3129 | /* give no advise for time on this subrequest. Perhaps we |
| 3130 | * should tally the last mtime among all variants, and date |
nothing calls this directly
no test coverage detected