comparison src/plugins/fts-solr/fts-backend-solr.c @ 8493:149c6ccc3df4 HEAD

fts-solr: Use '!' as escape character in usernames. Escape '/' and '!'.
author Timo Sirainen <tss@iki.fi>
date Sat, 29 Nov 2008 19:24:59 +0200
parents ee1ecdda8a6b
children ffb37c392166
comparison
equal deleted inserted replaced
8492:ee1ecdda8a6b 8493:149c6ccc3df4
11 #include <curl/curl.h> 11 #include <curl/curl.h>
12 12
13 #define SOLR_CMDBUF_SIZE (1024*64) 13 #define SOLR_CMDBUF_SIZE (1024*64)
14 #define SOLR_MAX_ROWS 100000 14 #define SOLR_MAX_ROWS 100000
15 15
16 struct solr_fts_backend {
17 struct fts_backend backend;
18 char *id_username;
19 };
20
16 struct solr_fts_backend_build_context { 21 struct solr_fts_backend_build_context {
17 struct fts_backend_build_context ctx; 22 struct fts_backend_build_context ctx;
18 23
19 struct solr_connection_post *post; 24 struct solr_connection_post *post;
20 uint32_t prev_uid, uid_validity; 25 uint32_t prev_uid, uid_validity;
55 static void xml_encode(string_t *dest, const char *str) 60 static void xml_encode(string_t *dest, const char *str)
56 { 61 {
57 xml_encode_data(dest, (const unsigned char *)str, strlen(str)); 62 xml_encode_data(dest, (const unsigned char *)str, strlen(str));
58 } 63 }
59 64
65 static const char *solr_escape_id_str(const char *str)
66 {
67 string_t *tmp;
68 const char *p;
69
70 for (p = str; *p != '\0'; p++) {
71 if (*p == '/' || *p == '!')
72 break;
73 }
74 if (*p == '\0')
75 return str;
76
77 tmp = t_str_new(64);
78 for (p = str; *p != '\0'; p++) {
79 switch (*p) {
80 case '/':
81 str_append(tmp, "!\\");
82 break;
83 case '!':
84 str_append(tmp, "!!");
85 break;
86 default:
87 str_append_c(tmp, *p);
88 break;
89 }
90 }
91 return str_c(tmp);
92 }
93
60 static struct fts_backend * 94 static struct fts_backend *
61 fts_backend_solr_init(struct mailbox *box ATTR_UNUSED) 95 fts_backend_solr_init(struct mailbox *box)
62 { 96 {
63 const struct fts_solr_settings *set = &fts_solr_settings; 97 const struct fts_solr_settings *set = &fts_solr_settings;
64 struct fts_backend *backend; 98 struct solr_fts_backend *backend;
99 const char *username = box->storage->ns->user->username;
65 100
66 if (solr_conn == NULL) 101 if (solr_conn == NULL)
67 solr_conn = solr_connection_init(set->url, set->debug); 102 solr_conn = solr_connection_init(set->url, set->debug);
68 103
69 backend = i_new(struct fts_backend, 1); 104 backend = i_new(struct solr_fts_backend, 1);
70 *backend = fts_backend_solr; 105 backend->id_username = i_strdup(solr_escape_id_str(username));
106 backend->backend = fts_backend_solr;
71 107
72 if (set->substring_search) 108 if (set->substring_search)
73 backend->flags |= FTS_BACKEND_FLAG_SUBSTRING_LOOKUPS; 109 backend->backend.flags |= FTS_BACKEND_FLAG_SUBSTRING_LOOKUPS;
74 return backend; 110 return &backend->backend;
75 } 111 }
76 112
77 static void fts_backend_solr_deinit(struct fts_backend *backend) 113 static void fts_backend_solr_deinit(struct fts_backend *_backend)
78 { 114 {
115 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
116
117 i_free(backend->id_username);
79 i_free(backend); 118 i_free(backend);
119 }
120
121 static const char *fts_backend_solr_username(struct fts_backend *_backend)
122 {
123 struct solr_fts_backend *backend = (struct solr_fts_backend *)_backend;
124
125 return backend->id_username;
80 } 126 }
81 127
82 static int fts_backend_solr_get_last_uid_fallback(struct fts_backend *backend, 128 static int fts_backend_solr_get_last_uid_fallback(struct fts_backend *backend,
83 uint32_t *last_uid_r) 129 uint32_t *last_uid_r)
84 { 130 {
212 ctx->prev_uid = uid; 258 ctx->prev_uid = uid;
213 259
214 fts_backend_solr_add_doc_prefix(ctx, uid); 260 fts_backend_solr_add_doc_prefix(ctx, uid);
215 str_printfa(cmd, "<field name=\"id\">%u/%u/", 261 str_printfa(cmd, "<field name=\"id\">%u/%u/",
216 uid, ctx->uid_validity); 262 uid, ctx->uid_validity);
217 xml_encode(cmd, box->storage->ns->user->username); 263 xml_encode(cmd, fts_backend_solr_username(ctx->ctx.backend));
218 str_append_c(cmd, '/'); 264 str_append_c(cmd, '/');
219 xml_encode(cmd, box->name); 265 xml_encode(cmd, box->name);
220 str_append(cmd, "</field>"); 266 str_append(cmd, "</field>");
221 267
222 ctx->headers = headers; 268 ctx->headers = headers;
257 may shrink. This doesn't really matter, we'll simply do more work 303 may shrink. This doesn't really matter, we'll simply do more work
258 in future by reindexing some messages. */ 304 in future by reindexing some messages. */
259 fts_backend_solr_add_doc_prefix(ctx, ctx->prev_uid); 305 fts_backend_solr_add_doc_prefix(ctx, ctx->prev_uid);
260 str_printfa(ctx->cmd, "<field name=\"last_uid\">TRUE</field>" 306 str_printfa(ctx->cmd, "<field name=\"last_uid\">TRUE</field>"
261 "<field name=\"id\">L/%u/", ctx->uid_validity); 307 "<field name=\"id\">L/%u/", ctx->uid_validity);
262 xml_encode(ctx->cmd, box->storage->ns->user->username); 308 xml_encode(ctx->cmd, fts_backend_solr_username(ctx->ctx.backend));
263 str_append_c(ctx->cmd, '/'); 309 str_append_c(ctx->cmd, '/');
264 xml_encode(ctx->cmd, box->name); 310 xml_encode(ctx->cmd, box->name);
265 str_append(ctx->cmd, "</field></doc></add>"); 311 str_append(ctx->cmd, "</field></doc></add>");
266 312
267 solr_connection_post_more(ctx->post, str_data(ctx->cmd), 313 solr_connection_post_more(ctx->post, str_data(ctx->cmd),
287 i_free(ctx); 333 i_free(ctx);
288 return ret; 334 return ret;
289 } 335 }
290 336
291 static void 337 static void
292 fts_backend_solr_expunge(struct fts_backend *backend ATTR_UNUSED, 338 fts_backend_solr_expunge(struct fts_backend *backend, struct mail *mail)
293 struct mail *mail)
294 { 339 {
295 struct mailbox_status status; 340 struct mailbox_status status;
296 341
297 mailbox_get_status(mail->box, STATUS_UIDVALIDITY, &status); 342 mailbox_get_status(mail->box, STATUS_UIDVALIDITY, &status);
298 343
300 string_t *cmd; 345 string_t *cmd;
301 346
302 cmd = t_str_new(256); 347 cmd = t_str_new(256);
303 str_printfa(cmd, "<delete><id>%u/%u/", 348 str_printfa(cmd, "<delete><id>%u/%u/",
304 mail->uid, status.uidvalidity); 349 mail->uid, status.uidvalidity);
305 xml_encode(cmd, mail->box->storage->ns->user->username); 350 xml_encode(cmd, fts_backend_solr_username(backend));
306 str_append_c(cmd, '/'); 351 str_append_c(cmd, '/');
307 xml_encode(cmd, mail->box->name); 352 xml_encode(cmd, mail->box->name);
308 str_append(cmd, "</id></delete>"); 353 str_append(cmd, "</id></delete>");
309 354
310 (void)solr_connection_post(solr_conn, str_c(cmd)); 355 (void)solr_connection_post(solr_conn, str_c(cmd));