| @@ -12,15 +12,8 @@ | ||
| 12 | 12 | defined( 'ABSPATH' ) || exit; |
| 13 | 13 | |
| 14 | 14 | /** |
| 15 | 15 | * HTTP Stream class. |
| 16 | - * | |
| 17 | - * This class writes the `text/event-stream` wire format, not HTML. HTML | |
| 18 | - * escaping would corrupt SSE framing. Event names are reduced to the | |
| 19 | - * characters permitted by this implementation, non-string payloads are JSON | |
| 20 | - * encoded, and every payload line is emitted as a separate `data:` field. | |
| 21 | - * Content Control uses this only from capability- and nonce-protected | |
| 22 | - * administrative upgrade handlers. | |
| 23 | 16 | */ |
| 24 | 17 | class Stream { |
| 25 | 18 | |
| 26 | 19 | /** |
| @@ -42,13 +35,9 @@ | ||
| 42 | 35 | * |
| 43 | 36 | * @param string $stream_name Stream name. |
| 44 | 37 | */ |
| 45 | 38 | public function __construct( $stream_name = 'stream' ) { |
| 46 | - $this->stream_name = sanitize_key( $stream_name ); | |
| 47 | - | |
| 48 | - if ( empty( $this->stream_name ) ) { | |
| 49 | - $this->stream_name = 'stream'; | |
| 50 | - } | |
| 39 | + $this->stream_name = $stream_name; | |
| 51 | 40 | } |
| 52 | 41 | |
| 53 | 42 | /** |
| 54 | 43 | * Start SSE stream. |
| @@ -66,8 +55,9 @@ | ||
| 66 | 55 | |
| 67 | 56 | // phpcs:disable WordPress.PHP.IniSet.Risky, WordPress.PHP.NoSilencedErrors.Discouraged |
| 68 | 57 | @ini_set( 'zlib.output_compression', '0' ); |
| 69 | 58 | @ini_set( 'implicit_flush', '1' ); |
| 59 | + @ini_set( 'log_limit', '8096' ); | |
| 70 | 60 | |
| 71 | 61 | @ob_end_clean(); |
| 72 | 62 | set_time_limit( 0 ); |
| 73 | 63 | // phpcs:enable WordPress.PHP.IniSet.Risky, WordPress.PHP.NoSilencedErrors.Discouraged |
| @@ -116,10 +106,12 @@ | ||
| 116 | 106 | * |
| 117 | 107 | * @return void |
| 118 | 108 | */ |
| 119 | 109 | public function send_data( $data ) { |
| 110 | + $data = is_string( $data ) ? $data : \wp_json_encode( $data ); | |
| 111 | + | |
| 120 | 112 | // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 121 | - echo $this->format_data( $data ); | |
| 113 | + echo "data: {$data}" . PHP_EOL; | |
| 122 | 114 | echo PHP_EOL; |
| 123 | 115 | |
| 124 | 116 | $this->flush_buffers(); |
| 125 | 117 | } |
| @@ -132,36 +124,17 @@ | ||
| 132 | 124 | * |
| 133 | 125 | * @return void |
| 134 | 126 | */ |
| 135 | 127 | public function send_event( $event, $data = '' ) { |
| 136 | - $event = preg_replace( '/[^a-zA-Z0-9_.:-]/', '', (string) $event ); | |
| 137 | - $event = empty( $event ) ? 'message' : $event; | |
| 128 | + $data = is_string( $data ) ? $data : \wp_json_encode( $data ); | |
| 138 | 129 | |
| 139 | 130 | // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 140 | - echo 'event: ' . $event . PHP_EOL; | |
| 131 | + echo "event: {$event}" . PHP_EOL; | |
| 141 | 132 | // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 142 | - echo $this->format_data( $data ); | |
| 133 | + echo "data: {$data}" . PHP_EOL; | |
| 143 | 134 | echo PHP_EOL; |
| 144 | 135 | |
| 145 | 136 | $this->flush_buffers(); |
| 146 | - } | |
| 147 | - | |
| 148 | - /** | |
| 149 | - * Format a value as one or more SSE data fields. | |
| 150 | - * | |
| 151 | - * @param mixed $data Data to format. | |
| 152 | - * | |
| 153 | - * @return string | |
| 154 | - */ | |
| 155 | - protected function format_data( $data ) { | |
| 156 | - $data = is_string( $data ) ? $data : \wp_json_encode( $data ); | |
| 157 | - $data = is_string( $data ) ? $data : ''; | |
| 158 | - $data = str_replace( [ "\r\n", "\r" ], "\n", $data ); | |
| 159 | - $lines = explode( "\n", $data ); | |
| 160 | - | |
| 161 | - return implode( PHP_EOL, array_map( static function ( $line ) { | |
| 162 | - return 'data: ' . $line; | |
| 163 | - }, $lines ) ) . PHP_EOL; | |
| 164 | 137 | } |
| 165 | 138 | |
| 166 | 139 | /** |
| 167 | 140 | * Send an error to the client. |