@@ -372,6 +372,8 @@ conn *conn_new(const int sfd, const int init_state, const int event_flags,
372
372
c -> bucket = -1 ;
373
373
c -> gen = 0 ;
374
374
375
+ c -> noreply = false;
376
+
375
377
event_set (& c -> event , sfd , event_flags , event_handler , (void * )c );
376
378
event_base_set (base , & c -> event );
377
379
c -> ev_flags = event_flags ;
@@ -733,6 +735,12 @@ static void out_string(conn *c, const char *str) {
733
735
734
736
assert (c != NULL );
735
737
738
+ if (c -> noreply ) {
739
+ c -> noreply = false;
740
+ conn_set_state (c , conn_read );
741
+ return ;
742
+ }
743
+
736
744
if (settings .verbose > 1 )
737
745
fprintf (stderr , ">%d %s\n" , c -> sfd , str );
738
746
@@ -898,7 +906,7 @@ typedef struct token_s {
898
906
#define KEY_TOKEN 1
899
907
#define KEY_MAX_LENGTH 250
900
908
901
- #define MAX_TOKENS 7
909
+ #define MAX_TOKENS 8
902
910
903
911
/*
904
912
* Tokenize the command string by replacing whitespace with '\0' and update
@@ -968,6 +976,23 @@ static void write_and_free(conn *c, char *buf, int bytes) {
968
976
}
969
977
}
970
978
979
+ static inline void set_noreply_maybe (conn * c , token_t * tokens , size_t ntokens )
980
+ {
981
+ int noreply_index = ntokens - 2 ;
982
+
983
+ /*
984
+ NOTE: this function is not the first place where we are going to
985
+ send the reply. We could send it instead from process_command()
986
+ if the request line has wrong number of tokens. However parsing
987
+ malformed line for "noreply" option is not reliable anyway, so
988
+ it can't be helped.
989
+ */
990
+ if (tokens [noreply_index ].value
991
+ && strcmp (tokens [noreply_index ].value , "noreply" ) == 0 ) {
992
+ c -> noreply = true;
993
+ }
994
+ }
995
+
971
996
inline static void process_stats_detail (conn * c , const char * command ) {
972
997
assert (c != NULL );
973
998
@@ -1347,6 +1372,8 @@ static void process_update_command(conn *c, token_t *tokens, const size_t ntoken
1347
1372
1348
1373
assert (c != NULL );
1349
1374
1375
+ set_noreply_maybe (c , tokens , ntokens );
1376
+
1350
1377
if (tokens [KEY_TOKEN ].length > KEY_MAX_LENGTH ) {
1351
1378
out_string (c , "CLIENT_ERROR bad command line format" );
1352
1379
return ;
@@ -1418,6 +1445,8 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt
1418
1445
1419
1446
assert (c != NULL );
1420
1447
1448
+ set_noreply_maybe (c , tokens , ntokens );
1449
+
1421
1450
if (tokens [KEY_TOKEN ].length > KEY_MAX_LENGTH ) {
1422
1451
out_string (c , "CLIENT_ERROR bad command line format" );
1423
1452
return ;
@@ -1514,6 +1543,8 @@ static void process_delete_command(conn *c, token_t *tokens, const size_t ntoken
1514
1543
1515
1544
assert (c != NULL );
1516
1545
1546
+ set_noreply_maybe (c , tokens , ntokens );
1547
+
1517
1548
if (settings .managed ) {
1518
1549
int bucket = c -> bucket ;
1519
1550
if (bucket == -1 ) {
@@ -1535,7 +1566,7 @@ static void process_delete_command(conn *c, token_t *tokens, const size_t ntoken
1535
1566
return ;
1536
1567
}
1537
1568
1538
- if (ntokens == 4 ) {
1569
+ if (ntokens == ( c -> noreply ? 5 : 4 ) ) {
1539
1570
exptime = strtol (tokens [2 ].value , NULL , 10 );
1540
1571
1541
1572
if (errno == ERANGE ) {
@@ -1598,6 +1629,8 @@ static void process_verbosity_command(conn *c, token_t *tokens, const size_t nto
1598
1629
1599
1630
assert (c != NULL );
1600
1631
1632
+ set_noreply_maybe (c , tokens , ntokens );
1633
+
1601
1634
level = strtoul (tokens [1 ].value , NULL , 10 );
1602
1635
settings .verbose = level > MAX_VERBOSITY_LEVEL ? MAX_VERBOSITY_LEVEL : level ;
1603
1636
out_string (c , "OK" );
@@ -1635,7 +1668,7 @@ static void process_command(conn *c, char *command) {
1635
1668
1636
1669
process_get_command (c , tokens , ntokens , false);
1637
1670
1638
- } else if (ntokens == 6 &&
1671
+ } else if (( ntokens == 6 || ntokens == 7 ) &&
1639
1672
((strcmp (tokens [COMMAND_TOKEN ].value , "add" ) == 0 && (comm = NREAD_ADD )) ||
1640
1673
(strcmp (tokens [COMMAND_TOKEN ].value , "set" ) == 0 && (comm = NREAD_SET )) ||
1641
1674
(strcmp (tokens [COMMAND_TOKEN ].value , "replace" ) == 0 && (comm = NREAD_REPLACE )) ||
@@ -1644,23 +1677,23 @@ static void process_command(conn *c, char *command) {
1644
1677
1645
1678
process_update_command (c , tokens , ntokens , comm , false);
1646
1679
1647
- } else if (ntokens == 7 && (strcmp (tokens [COMMAND_TOKEN ].value , "cas" ) == 0 && (comm = NREAD_CAS ))) {
1680
+ } else if (( ntokens == 7 || ntokens == 8 ) && (strcmp (tokens [COMMAND_TOKEN ].value , "cas" ) == 0 && (comm = NREAD_CAS ))) {
1648
1681
1649
1682
process_update_command (c , tokens , ntokens , comm , true);
1650
1683
1651
- } else if (ntokens == 4 && (strcmp (tokens [COMMAND_TOKEN ].value , "incr" ) == 0 )) {
1684
+ } else if (( ntokens == 4 || ntokens == 5 ) && (strcmp (tokens [COMMAND_TOKEN ].value , "incr" ) == 0 )) {
1652
1685
1653
1686
process_arithmetic_command (c , tokens , ntokens , 1 );
1654
1687
1655
1688
} else if (ntokens >= 3 && (strcmp (tokens [COMMAND_TOKEN ].value , "gets" ) == 0 )) {
1656
1689
1657
1690
process_get_command (c , tokens , ntokens , true);
1658
1691
1659
- } else if (ntokens == 4 && (strcmp (tokens [COMMAND_TOKEN ].value , "decr" ) == 0 )) {
1692
+ } else if (( ntokens == 4 || ntokens == 5 ) && (strcmp (tokens [COMMAND_TOKEN ].value , "decr" ) == 0 )) {
1660
1693
1661
1694
process_arithmetic_command (c , tokens , ntokens , 0 );
1662
1695
1663
- } else if (ntokens >= 3 && ntokens <= 4 && (strcmp (tokens [COMMAND_TOKEN ].value , "delete" ) == 0 )) {
1696
+ } else if (ntokens >= 3 && ntokens <= 5 && (strcmp (tokens [COMMAND_TOKEN ].value , "delete" ) == 0 )) {
1664
1697
1665
1698
process_delete_command (c , tokens , ntokens );
1666
1699
@@ -1729,11 +1762,13 @@ static void process_command(conn *c, char *command) {
1729
1762
1730
1763
process_stat (c , tokens , ntokens );
1731
1764
1732
- } else if (ntokens >= 2 && ntokens <= 3 && (strcmp (tokens [COMMAND_TOKEN ].value , "flush_all" ) == 0 )) {
1765
+ } else if (ntokens >= 2 && ntokens <= 4 && (strcmp (tokens [COMMAND_TOKEN ].value , "flush_all" ) == 0 )) {
1733
1766
time_t exptime = 0 ;
1734
1767
set_current_time ();
1735
1768
1736
- if (ntokens == 2 ) {
1769
+ set_noreply_maybe (c , tokens , ntokens );
1770
+
1771
+ if (ntokens == (c -> noreply ? 3 : 2 )) {
1737
1772
settings .oldest_live = current_time - 1 ;
1738
1773
item_flush_expired ();
1739
1774
out_string (c , "OK" );
@@ -1798,7 +1833,7 @@ static void process_command(conn *c, char *command) {
1798
1833
#else
1799
1834
out_string (c , "CLIENT_ERROR Slab reassignment not supported" );
1800
1835
#endif
1801
- } else if (ntokens == 3 && (strcmp (tokens [COMMAND_TOKEN ].value , "verbosity" ) == 0 )) {
1836
+ } else if (( ntokens == 3 || ntokens == 4 ) && (strcmp (tokens [COMMAND_TOKEN ].value , "verbosity" ) == 0 )) {
1802
1837
process_verbosity_command (c , tokens , ntokens );
1803
1838
} else {
1804
1839
out_string (c , "ERROR" );
0 commit comments