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
| 1722 | * a protocol error: in such a case the client structure is setup to reply |
| 1723 | * with the error and close the connection. */ |
| 1724 | int processInlineBuffer(client *c) { |
| 1725 | char *newline; |
| 1726 | int argc, j, linefeed_chars = 1; |
| 1727 | sds *argv, aux; |
| 1728 | size_t querylen; |
| 1729 | |
| 1730 | /* Search for end of line */ |
| 1731 | newline = strchr(c->querybuf+c->qb_pos,'\n'); |
| 1732 | |
| 1733 | /* Nothing to do without a \r\n */ |
| 1734 | if (newline == NULL) { |
| 1735 | if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) { |
| 1736 | addReplyError(c,"Protocol error: too big inline request"); |
| 1737 | setProtocolError("too big inline request",c); |
| 1738 | } |
| 1739 | return C_ERR; |
| 1740 | } |
| 1741 | |
| 1742 | /* Handle the \r\n case. */ |
| 1743 | if (newline != c->querybuf+c->qb_pos && *(newline-1) == '\r') |
| 1744 | newline--, linefeed_chars++; |
| 1745 | |
| 1746 | /* Split the input buffer up to the \r\n */ |
| 1747 | querylen = newline-(c->querybuf+c->qb_pos); |
| 1748 | aux = sdsnewlen(c->querybuf+c->qb_pos,querylen); |
| 1749 | argv = sdssplitargs(aux,&argc); |
| 1750 | sdsfree(aux); |
| 1751 | if (argv == NULL) { |
| 1752 | addReplyError(c,"Protocol error: unbalanced quotes in request"); |
| 1753 | setProtocolError("unbalanced quotes in inline request",c); |
| 1754 | return C_ERR; |
| 1755 | } |
| 1756 | |
| 1757 | /* Newline from slaves can be used to refresh the last ACK time. |
| 1758 | * This is useful for a slave to ping back while loading a big |
| 1759 | * RDB file. */ |
| 1760 | if (querylen == 0 && getClientType(c) == CLIENT_TYPE_SLAVE) |
| 1761 | c->repl_ack_time = server.unixtime; |
| 1762 | |
| 1763 | /* Masters should never send us inline protocol to run actual |
| 1764 | * commands. If this happens, it is likely due to a bug in Redis where |
| 1765 | * we got some desynchronization in the protocol, for example |
| 1766 | * beause of a PSYNC gone bad. |
| 1767 | * |
| 1768 | * However the is an exception: masters may send us just a newline |
| 1769 | * to keep the connection active. */ |
| 1770 | if (querylen != 0 && c->flags & CLIENT_MASTER) { |
| 1771 | sdsfreesplitres(argv,argc); |
| 1772 | serverLog(LL_WARNING,"WARNING: Receiving inline protocol from master, master stream corruption? Closing the master connection and discarding the cached master."); |
| 1773 | setProtocolError("Master using the inline protocol. Desync?",c); |
| 1774 | return C_ERR; |
| 1775 | } |
| 1776 | |
| 1777 | /* Move querybuffer position to the next query in the buffer. */ |
| 1778 | c->qb_pos += querylen+linefeed_chars; |
| 1779 | |
| 1780 | /* Setup argv array on client structure */ |
| 1781 | if (argc) { |
no test coverage detected