static int apreq_access_checker(request_rec *r) { apreq_handle_t *handle; apreq_param_t *param; struct access_test_cfg *cfg = (struct access_test_cfg *) ap_get_module_config(r->per_dir_config, &apreq_access_test_module); if (!cfg || !cfg->param) return DECLINED; handle = apreq_handle_apache2(r); param = apreq_param(handle, cfg->param); if (param != NULL) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, "ACCESS GRANTED: %s => %s", cfg->param, param->v.data); return OK; } else { const apr_table_t *t = apreq_params(handle, r->pool); if (t != NULL) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, r, "%s not found: parsing error detected (%d params)", cfg->param, apr_table_elts(t)->nelts); } else { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_EGENERAL, r, "%s not found: paring error detected (no param table)", cfg->param); } return HTTP_FORBIDDEN; } }
// This is the method which does all the work handling the uploads. It's only // triggered by the fixup filter if +porter_should_rewrite_body+ returns true. apr_status_t porter_process_upload(request_rec *r) { porter_server_conf *config = (porter_server_conf *) ap_get_module_config(r->server->module_config, &porter_module); // Prepare the apreq objects. apreq_handle_t *req = apreq_handle_apache2(r); const apr_table_t *request_body = apreq_params(req, r->pool); // Create our upload request object, this is fleshed out by the rest of this method porter_upload_request_t *upload_request = porter_create_request(req, r, config); // This happens with malformed requests. apreq_params should never return null // when the content-length is > 0 and it's a multipart request. So just assume // it's broken and return bad request. Otherwise subsequent method calls will // cause a segfault if (request_body == NULL) { PORTER_LOG_REQUEST_ERROR("Invalid request body"); return HTTP_BAD_REQUEST; } // loop over each parameter provided by the user (see porter_each_parameter) apr_table_do(porter_each_parameter, upload_request, request_body, NULL); // If any of the parameter handlers return an error, they save the error code // in the upload_request. So return that same error code. if (upload_request->status != APR_SUCCESS) { return upload_request->status; } // Just because the content type is multipart and the content-length was > 0 doesn't // mean that the user actually uploaded any files. If they didn't, just return success // and let the original body be passed upstream. if (!apr_is_empty_array(upload_request->param_names)) { // Write the parameter names to the X-Uploads header (comma seperated) const char *upload_parameters = apr_array_pstrcat(r->pool, upload_request->param_names, ','); apr_off_t len; apr_table_setn(r->headers_in, HTTP_X_UPLOADS, upload_parameters); // figure out the length of the newly rewritten body and set it in the request // along with the right content type. apr_brigade_length(upload_request->bucket_brigade, 0, &len); apr_table_setn(r->headers_in, "Content-Length", apr_itoa(r->pool, len)); apr_table_setn(r->headers_in, "Content-Type", "application/x-www-form-urlencoded"); // Add our input filter to the filter chain, this allows // us to replace the request body with our own one, and ensure that // gets passed down to the handler. ap_add_input_filter_handle(porter_input_filter_handle, upload_request, r, r->connection); } return APR_SUCCESS; }