403 ) ); // Files hang off applications and standalone upload records. if ( ! Repository::exists( $id ) && Store::UPLOAD_POST_TYPE !== get_post_type( $id ) ) { return $denied; } $files = Store::files_for( $id ); if ( ! isset( $files[ $file_id ] ) ) { return $denied; } $by_admin = is_user_logged_in() && current_user_can( 'edit_post', $id ); if ( ! $by_admin ) { $exp = (int) $request->get_param( 'exp' ); $purpose = (string) $request->get_param( 'p' ); $sig = (string) $request->get_param( 'sig' ); if ( $exp < time() || ! hash_equals( Store::signature( $id, $file_id, $exp, $purpose ), $sig ) ) { return $denied; } $limit = Store::download_limit(); if ( $limit > 0 && (int) $files[ $file_id ]['downloads'] >= $limit ) { return new \WP_Error( 'mapp_file_limit', __( 'This file has reached its download limit. Ask for a new link.', '1003-mortgage-application' ), array( 'status' => 403 ) ); } if ( ! RateLimiter::hit( 'download', RateLimiter::client_ip(), 60, HOUR_IN_SECONDS ) ) { return new \WP_Error( 'mapp_rate_limited', __( 'Too many downloads. Please try again later.', '1003-mortgage-application' ), array( 'status' => 429 ) ); } } $bytes = Store::read( $id, $file_id ); if ( null === $bytes ) { return new \WP_Error( 'mapp_file_gone', __( 'This file is no longer available.', '1003-mortgage-application' ), array( 'status' => 410 ) ); } Store::mark( $id, $file_id, 'downloads', (int) $files[ $file_id ]['downloads'] + 1 ); Access::log( $id, 'download', $file_id, $by_admin ? 'user:' . get_current_user_id() : 'link:' . sanitize_key( (string) $request->get_param( 'p' ) ) ); $name = str_replace( array( '"', "\r", "\n" ), '', $files[ $file_id ]['name'] ); if ( ! headers_sent() ) { nocache_headers(); header( 'Content-Type: ' . $files[ $file_id ]['mime'] ); header( 'Content-Disposition: attachment; filename="' . $name . '"' ); header( 'Content-Length: ' . strlen( $bytes ) ); header( 'X-Content-Type-Options: nosniff' ); header( 'Referrer-Policy: no-referrer' ); } echo $bytes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- binary file. exit; } }