@@ -50,6 +50,57 @@ MYSQLND_METHOD(mysqlnd_pfc, reset)(MYSQLND_PFC * const pfc, MYSQLND_STATS * cons
50
50
#define STORE_HEADER_SIZE (safe_storage , buffer ) COPY_HEADER((safe_storage), (buffer))
51
51
#define RESTORE_HEADER_SIZE (buffer , safe_storage ) STORE_HEADER_SIZE((safe_storage), (buffer))
52
52
53
+ #ifdef MYSQLND_COMPRESSION_ENABLED
54
+ static ssize_t write_compressed_packet (
55
+ const MYSQLND_PFC * pfc , MYSQLND_VIO * vio ,
56
+ MYSQLND_STATS * conn_stats , MYSQLND_ERROR_INFO * error_info ,
57
+ zend_uchar * uncompressed_payload , size_t to_be_sent , zend_uchar * compress_buf ) {
58
+ DBG_ENTER ("write_compressed_packet" );
59
+ /* here we need to compress the data and then write it, first comes the compressed header */
60
+ size_t tmp_complen = to_be_sent ;
61
+ size_t payload_size ;
62
+ if (PASS == pfc -> data -> m .encode ((compress_buf + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE ), & tmp_complen ,
63
+ uncompressed_payload , to_be_sent ))
64
+ {
65
+ int3store (compress_buf + MYSQLND_HEADER_SIZE , to_be_sent );
66
+ payload_size = tmp_complen ;
67
+ } else {
68
+ int3store (compress_buf + MYSQLND_HEADER_SIZE , 0 );
69
+ memcpy (compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , uncompressed_payload , to_be_sent );
70
+ payload_size = to_be_sent ;
71
+ }
72
+
73
+ int3store (compress_buf , payload_size );
74
+ int1store (compress_buf + 3 , pfc -> data -> compressed_envelope_packet_no );
75
+ DBG_INF_FMT ("writing " MYSQLND_SZ_T_SPEC " bytes to the network" , payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE );
76
+
77
+ ssize_t bytes_sent = vio -> data -> m .network_write (vio , compress_buf , payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , conn_stats , error_info );
78
+ pfc -> data -> compressed_envelope_packet_no ++ ;
79
+ #ifdef WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY
80
+ if (res == Z_OK ) {
81
+ size_t decompressed_size = left + MYSQLND_HEADER_SIZE ;
82
+ zend_uchar * decompressed_data = mnd_malloc (decompressed_size );
83
+ int error = pfc -> data -> m .decode (decompressed_data , decompressed_size ,
84
+ compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , payload_size );
85
+ if (error == Z_OK ) {
86
+ int i ;
87
+ DBG_INF ("success decompressing" );
88
+ for (i = 0 ; i < decompressed_size ; i ++ ) {
89
+ if (i && (i % 30 == 0 )) {
90
+ printf ("\n\t\t" );
91
+ }
92
+ printf ("%.2X " , (int )* ((char * )& (decompressed_data [i ])));
93
+ DBG_INF_FMT ("%.2X " , (int )* ((char * )& (decompressed_data [i ])));
94
+ }
95
+ } else {
96
+ DBG_INF ("error decompressing" );
97
+ }
98
+ mnd_free (decompressed_data );
99
+ }
100
+ #endif /* WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY */
101
+ DBG_RETURN (bytes_sent );
102
+ }
103
+ #endif
53
104
54
105
/* {{{ mysqlnd_pfc::send */
55
106
/*
@@ -92,53 +143,27 @@ MYSQLND_METHOD(mysqlnd_pfc, send)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const v
92
143
DBG_INF_FMT ("packet_no=%u" , pfc -> data -> packet_no );
93
144
#ifdef MYSQLND_COMPRESSION_ENABLED
94
145
if (pfc -> data -> compressed == TRUE) {
95
- /* here we need to compress the data and then write it, first comes the compressed header */
96
- size_t tmp_complen = to_be_sent ;
97
- size_t payload_size ;
98
146
zend_uchar * uncompressed_payload = p ; /* should include the header */
99
-
100
147
STORE_HEADER_SIZE (safe_storage , uncompressed_payload );
101
148
int3store (uncompressed_payload , to_be_sent );
102
149
int1store (uncompressed_payload + 3 , pfc -> data -> packet_no );
103
- if (PASS == pfc -> data -> m .encode ((compress_buf + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE ), & tmp_complen ,
104
- uncompressed_payload , to_be_sent + MYSQLND_HEADER_SIZE ))
105
- {
106
- int3store (compress_buf + MYSQLND_HEADER_SIZE , to_be_sent + MYSQLND_HEADER_SIZE );
107
- payload_size = tmp_complen ;
150
+ if (to_be_sent <= MYSQLND_MAX_PACKET_SIZE - MYSQLND_HEADER_SIZE ) {
151
+ bytes_sent = write_compressed_packet (
152
+ pfc , vio , conn_stats , error_info ,
153
+ uncompressed_payload , to_be_sent + MYSQLND_HEADER_SIZE , compress_buf );
108
154
} else {
109
- int3store (compress_buf + MYSQLND_HEADER_SIZE , 0 );
110
- memcpy (compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , uncompressed_payload , to_be_sent + MYSQLND_HEADER_SIZE );
111
- payload_size = to_be_sent + MYSQLND_HEADER_SIZE ;
155
+ /* The uncompressed size including the header would overflow. Split into two
156
+ * compressed packets. The size of the first one is relatively arbitrary here. */
157
+ const size_t split_off_bytes = 8192 ;
158
+ bytes_sent = write_compressed_packet (
159
+ pfc , vio , conn_stats , error_info ,
160
+ uncompressed_payload , split_off_bytes , compress_buf );
161
+ bytes_sent = write_compressed_packet (
162
+ pfc , vio , conn_stats , error_info ,
163
+ uncompressed_payload + split_off_bytes ,
164
+ to_be_sent + MYSQLND_HEADER_SIZE - split_off_bytes , compress_buf );
112
165
}
113
166
RESTORE_HEADER_SIZE (uncompressed_payload , safe_storage );
114
-
115
- int3store (compress_buf , payload_size );
116
- int1store (compress_buf + 3 , pfc -> data -> packet_no );
117
- DBG_INF_FMT ("writing " MYSQLND_SZ_T_SPEC " bytes to the network" , payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE );
118
- bytes_sent = vio -> data -> m .network_write (vio , compress_buf , payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , conn_stats , error_info );
119
- pfc -> data -> compressed_envelope_packet_no ++ ;
120
- #if WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY
121
- if (res == Z_OK ) {
122
- size_t decompressed_size = left + MYSQLND_HEADER_SIZE ;
123
- zend_uchar * decompressed_data = mnd_malloc (decompressed_size );
124
- int error = pfc -> data -> m .decode (decompressed_data , decompressed_size ,
125
- compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , payload_size );
126
- if (error == Z_OK ) {
127
- int i ;
128
- DBG_INF ("success decompressing" );
129
- for (i = 0 ; i < decompressed_size ; i ++ ) {
130
- if (i && (i % 30 == 0 )) {
131
- printf ("\n\t\t" );
132
- }
133
- printf ("%.2X " , (int )* ((char * )& (decompressed_data [i ])));
134
- DBG_INF_FMT ("%.2X " , (int )* ((char * )& (decompressed_data [i ])));
135
- }
136
- } else {
137
- DBG_INF ("error decompressing" );
138
- }
139
- mnd_free (decompressed_data );
140
- }
141
- #endif /* WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY */
142
167
} else
143
168
#endif /* MYSQLND_COMPRESSION_ENABLED */
144
169
{
0 commit comments