@@ -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 size_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
+ size_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
/*
@@ -91,53 +142,27 @@ MYSQLND_METHOD(mysqlnd_pfc, send)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const v
91
142
DBG_INF_FMT ("packet_no=%u" , pfc -> data -> packet_no );
92
143
#ifdef MYSQLND_COMPRESSION_ENABLED
93
144
if (pfc -> data -> compressed == TRUE) {
94
- /* here we need to compress the data and then write it, first comes the compressed header */
95
- size_t tmp_complen = to_be_sent ;
96
- size_t payload_size ;
97
145
zend_uchar * uncompressed_payload = p ; /* should include the header */
98
-
99
146
STORE_HEADER_SIZE (safe_storage , uncompressed_payload );
100
147
int3store (uncompressed_payload , to_be_sent );
101
148
int1store (uncompressed_payload + 3 , pfc -> data -> packet_no );
102
- if (PASS == pfc -> data -> m .encode ((compress_buf + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE ), & tmp_complen ,
103
- uncompressed_payload , to_be_sent + MYSQLND_HEADER_SIZE ))
104
- {
105
- int3store (compress_buf + MYSQLND_HEADER_SIZE , to_be_sent + MYSQLND_HEADER_SIZE );
106
- payload_size = tmp_complen ;
149
+ if (to_be_sent <= MYSQLND_MAX_PACKET_SIZE - MYSQLND_HEADER_SIZE ) {
150
+ bytes_sent = write_compressed_packet (
151
+ pfc , vio , conn_stats , error_info ,
152
+ uncompressed_payload , to_be_sent + MYSQLND_HEADER_SIZE , compress_buf );
107
153
} else {
108
- int3store (compress_buf + MYSQLND_HEADER_SIZE , 0 );
109
- memcpy (compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , uncompressed_payload , to_be_sent + MYSQLND_HEADER_SIZE );
110
- payload_size = to_be_sent + MYSQLND_HEADER_SIZE ;
154
+ /* The uncompressed size including the header would overflow. Split into two
155
+ * compressed packets. The size of the first one is relatively arbitrary here. */
156
+ const size_t split_off_bytes = 8192 ;
157
+ bytes_sent = write_compressed_packet (
158
+ pfc , vio , conn_stats , error_info ,
159
+ uncompressed_payload , split_off_bytes , compress_buf );
160
+ bytes_sent = write_compressed_packet (
161
+ pfc , vio , conn_stats , error_info ,
162
+ uncompressed_payload + split_off_bytes ,
163
+ to_be_sent + MYSQLND_HEADER_SIZE - split_off_bytes , compress_buf );
111
164
}
112
165
RESTORE_HEADER_SIZE (uncompressed_payload , safe_storage );
113
-
114
- int3store (compress_buf , payload_size );
115
- int1store (compress_buf + 3 , pfc -> data -> packet_no );
116
- DBG_INF_FMT ("writing " MYSQLND_SZ_T_SPEC " bytes to the network" , payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE );
117
- bytes_sent = vio -> data -> m .network_write (vio , compress_buf , payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , conn_stats , error_info );
118
- pfc -> data -> compressed_envelope_packet_no ++ ;
119
- #if WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY
120
- if (res == Z_OK ) {
121
- size_t decompressed_size = left + MYSQLND_HEADER_SIZE ;
122
- zend_uchar * decompressed_data = mnd_malloc (decompressed_size );
123
- int error = pfc -> data -> m .decode (decompressed_data , decompressed_size ,
124
- compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE , payload_size );
125
- if (error == Z_OK ) {
126
- int i ;
127
- DBG_INF ("success decompressing" );
128
- for (i = 0 ; i < decompressed_size ; i ++ ) {
129
- if (i && (i % 30 == 0 )) {
130
- printf ("\n\t\t" );
131
- }
132
- printf ("%.2X " , (int )* ((char * )& (decompressed_data [i ])));
133
- DBG_INF_FMT ("%.2X " , (int )* ((char * )& (decompressed_data [i ])));
134
- }
135
- } else {
136
- DBG_INF ("error decompressing" );
137
- }
138
- mnd_free (decompressed_data );
139
- }
140
- #endif /* WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY */
141
166
} else
142
167
#endif /* MYSQLND_COMPRESSION_ENABLED */
143
168
{
0 commit comments