Like processMultibulkBuffer(), but for the inline protocol instead of RESP, * this function consumes the client query buffer and creates a command ready * to be executed inside the client structure. Returns C_OK if the command * is ready to be executed, or C_ERR if there is still protocol to read to * have a well formed command. The function also returns C_ERR when there is * a protocol error
| 2198 | * a protocol error: in such a case the client structure is setup to reply |
| 2199 | * with the error and close the connection. */ |
| 2200 | int processInlineBuffer(client *c) { |
| 2201 | char *newline; |
| 2202 | int argc, j, linefeed_chars = 1; |
| 2203 | sds *argv, aux; |
| 2204 | size_t querylen; |
| 2205 | |
| 2206 | /* Search for end of line */ |
| 2207 | newline = strchr(c->querybuf+c->qb_pos,'\n'); |
| 2208 | |
| 2209 | /* Nothing to do without a \r\n */ |
| 2210 | if (newline == NULL) { |
| 2211 | if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) { |
| 2212 | addReplyError(c,"Protocol error: too big inline request"); |
| 2213 | setProtocolError("too big inline request",c); |
| 2214 | } |
| 2215 | return C_ERR; |
| 2216 | } |
| 2217 | |
| 2218 | /* Handle the \r\n case. */ |
| 2219 | if (newline != c->querybuf+c->qb_pos && *(newline-1) == '\r') |
| 2220 | newline--, linefeed_chars++; |
| 2221 | |
| 2222 | /* Split the input buffer up to the \r\n */ |
| 2223 | querylen = newline-(c->querybuf+c->qb_pos); |
| 2224 | aux = sdsnewlen(c->querybuf+c->qb_pos,querylen); |
| 2225 | argv = sdssplitargs(aux,&argc); |
| 2226 | sdsfree(aux); |
| 2227 | if (argv == NULL) { |
| 2228 | addReplyError(c,"Protocol error: unbalanced quotes in request"); |
| 2229 | setProtocolError("unbalanced quotes in inline request",c); |
| 2230 | return C_ERR; |
| 2231 | } |
| 2232 | |
| 2233 | /* Newline from slaves can be used to refresh the last ACK time. |
| 2234 | * This is useful for a replica to ping back while loading a big |
| 2235 | * RDB file. */ |
| 2236 | if (querylen == 0 && getClientType(c) == CLIENT_TYPE_SLAVE) |
| 2237 | c->repl_ack_time = g_pserver->unixtime; |
| 2238 | |
| 2239 | /* Masters should never send us inline protocol to run actual |
| 2240 | * commands. If this happens, it is likely due to a bug in Redis where |
| 2241 | * we got some desynchronization in the protocol, for example |
| 2242 | * beause of a PSYNC gone bad. |
| 2243 | * |
| 2244 | * However the is an exception: masters may send us just a newline |
| 2245 | * to keep the connection active. */ |
| 2246 | if (querylen != 0 && c->flags & CLIENT_MASTER) { |
| 2247 | sdsfreesplitres(argv,argc); |
| 2248 | serverLog(LL_WARNING,"WARNING: Receiving inline protocol from master, master stream corruption? Closing the master connection and discarding the cached master."); |
| 2249 | setProtocolError("Master using the inline protocol. Desync?",c); |
| 2250 | return C_ERR; |
| 2251 | } |
| 2252 | |
| 2253 | /* Move querybuffer position to the next query in the buffer. */ |
| 2254 | c->qb_pos += querylen+linefeed_chars; |
| 2255 | |
| 2256 | /* Setup argv array on client structure */ |
| 2257 | if (argc) { |
no test coverage detected