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