fts-backend-solr.c revision 0685853771a658d42174ed82763acc1626222032
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2006-2015 Dovecot authors, see the included COPYING file */
bdb026e2dc8a7c77585ed5ba489f0056df8074d4Timo Sirainen#define SOLR_CMDBUF_FLUSH_SIZE (SOLR_CMDBUF_SIZE-128)
bdb026e2dc8a7c77585ed5ba489f0056df8074d4Timo Sirainen/* If header is larger than this, truncate it. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen/* If SOLR_HEADER_MAX_SIZE was already reached, write still to individual
9393445a6dabd17ce62ebfc12fd73545b0065824Timo Sirainen header fields as long as they're smaller than this */
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen /* Valid characters in XML:
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] |
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen [#x10000-#x10FFFF]
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen This function gets called only for #x80 and higher */
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenstatic unsigned int
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainenxml_encode_data_max(string_t *dest, const unsigned char *data, unsigned int len,
0b25846ba794ce19536a24d4065beaf2a0bd9464Timo Sirainen unsigned int max_len)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen unsigned int i;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen for (i = 0; i < max_len; i++) {
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen switch (data[i]) {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* exceptions to the following control char check */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* SOLR doesn't like control characters.
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen replace them with spaces. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* make sure the character is valid for XML
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen so we don't get XML parser errors */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned int char_len =
8ca217bf3aa23c7922d0d4aa44fcd2320416d61cMartti Rannanjärvixml_encode_data(string_t *dest, const unsigned char *data, unsigned int len)
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen (void)xml_encode_data_max(dest, data, len, len);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void xml_encode(string_t *dest, const char *str)
4d84348ffcbb60de566108562c95ad64629e7a53Timo Sirainen xml_encode_data(dest, (const unsigned char *)str, strlen(str));
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenstatic void solr_quote_http(string_t *dest, const char *str)
9f46aa48a9982567a37bb08dd95af8bee5100c7eTimo Sirainenstatic struct fts_backend *fts_backend_solr_alloc(void)
eb1572d7c44ebc7b0b039d085c3dbab2ef7043ddTimo Sirainenfts_backend_solr_init(struct fts_backend *_backend, const char **error_r)
9f46aa48a9982567a37bb08dd95af8bee5100c7eTimo Sirainen struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT(_backend->ns->user);
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen /* change our flags so we get proper input */
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen _backend->flags &= ~FTS_BACKEND_FLAG_FUZZY_SEARCH;
4366a21968093172d9b757fe6894b1ee8916434eTimo Sirainen _backend->flags |= FTS_BACKEND_FLAG_TOKENIZED_INPUT;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen return solr_connection_init(fuser->set.url, fuser->set.debug,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void fts_backend_solr_deinit(struct fts_backend *_backend)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
4645cc6c911a95991d7af43b40f88e99506ea5e9Timo Sirainenget_last_uid_fallback(struct fts_backend *_backend, struct mailbox *box,
d3e5a14ea363264dcc7640ca7226249d0c27a793Timo Sirainen struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen unsigned int count;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen str_append(str, "fl=uid&rows=1&sort=uid+desc&q=");
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen str_printfa(str, "box:%s+AND+user:", box_guid);
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen solr_quote_http(str, _backend->ns->owner->username);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen pool = pool_alloconly_create("solr last uid lookup", 1024);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (solr_connection_select(backend->solr_conn, str_c(str),
34b724d1d7e50b1ab24267a3b6fc089b1147c1abAki Tuomi /* no UIDs */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uidvals = array_get(&results[0]->uids, &count);
77b5fd56e5a06d624f3ab92198272287333114f4Timo Sirainen if (count == 1 && uidvals[0].seq1 == uidvals[0].seq2) {
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen i_error("fts_solr: Last UID lookup returned multiple rows");
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainenfts_backend_solr_get_last_uid(struct fts_backend *_backend,
b5c6ce2ab8dc1a5817e8adc989d21a9f603a6673Aki Tuomi /* either nothing has been indexed, or the index was corrupted.
b5c6ce2ab8dc1a5817e8adc989d21a9f603a6673Aki Tuomi do it the slow way. */
b5c6ce2ab8dc1a5817e8adc989d21a9f603a6673Aki Tuomi if (get_last_uid_fallback(_backend, box, last_uid_r) < 0)
static struct fts_backend_update_context *
static string_t *
const char *str;
return ret;
const char *box_guid;
i_unreached();
return TRUE;
unsigned int len;
return TRUE;
return FALSE;
case SEARCH_TEXT: {
case SEARCH_BODY:
case SEARCH_HEADER:
case SEARCH_HEADER_ADDRESS:
return FALSE;
return FALSE;
return TRUE;
bool and_args)
unsigned int last_len;
if (and_args)
return FALSE;
return TRUE;
case SEARCH_HEADER:
case SEARCH_HEADER_ADDRESS:
return FALSE;
return FALSE;
return FALSE;
return TRUE;
bool and_args)
unsigned int last_len;
if (and_args)
return FALSE;
return TRUE;
int ret;
return ret;
const char *box_guid;
unsigned int prefix_len;
const char *box_guid;
unsigned int i, len;
bool search_all_mailboxes;
if (!search_all_mailboxes)
if (!search_all_mailboxes) {
boxes[i]);
if (!search_all_mailboxes)
if (!search_all_mailboxes) {