Skip to content
This repository
Browse code

fix escaped key/attachment parsing in dumbproxy

  • Loading branch information...
commit 3dfb4ede54d39725461f57fe44d88090d0363b40 1 parent 53a02a3
Randall Leeds authored
2  dumbproxy/dumbproxy.spec
... ...
@@ -1,7 +1,7 @@
1 1
 Summary: Lounge Dumb Proxy
2 2
 Name: lounge-dumbproxy
3 3
 Version: 1.2.2
4  
-Release: 1%{?dist}
  4
+Release: 6%{?dist}
5 5
 URL: http://tilgovi.github.com/couchdb-lounge
6 6
 License: None
7 7
 Group: Lounge
131  dumbproxy/nginx_lounge_module/lounge.c
@@ -137,100 +137,6 @@ ngx_module_t lounge_module = {
137 137
     NGX_MODULE_V1_PADDING
138 138
 };
139 139
 
140  
-/* This is the code from ngx_unescape_uri, but modified so that it doesn't
141  
- * unescape %2f and ensures that the 'f' is consistently lowercased.  This 
142  
- * is needed so that document name portion of the uri can contain slashes
143  
- * and still be hashed correctly.
144  
- */
145  
-static void
146  
-normalize_uri(u_char **dst, u_char **src, size_t size)
147  
-{
148  
-    u_char  *d, *s, ch, c, decoded;
149  
-    enum {
150  
-        sw_usual = 0,
151  
-        sw_quoted,
152  
-        sw_quoted_second
153  
-    } state;
154  
-
155  
-    d = *dst;
156  
-    s = *src;
157  
-
158  
-    state = 0;
159  
-    decoded = 0;
160  
-
161  
-    while (size--) {
162  
-
163  
-        ch = *s++;
164  
-
165  
-        switch (state) {
166  
-        case sw_usual:
167  
-            if (ch == '%') {
168  
-                state = sw_quoted;
169  
-                break;
170  
-            }
171  
-
172  
-			if (ch == '?') goto done;
173  
-
174  
-            *d++ = ch;
175  
-            break;
176  
-
177  
-        case sw_quoted:
178  
-
179  
-            if (ch >= '0' && ch <= '9') {
180  
-                decoded = (u_char) (ch - '0');
181  
-                state = sw_quoted_second;
182  
-                break;
183  
-            }
184  
-
185  
-            c = (u_char) (ch | 0x20);
186  
-            if (c >= 'a' && c <= 'f') {
187  
-                decoded = (u_char) (c - 'a' + 10);
188  
-                state = sw_quoted_second;
189  
-                break;
190  
-            }
191  
-
192  
-            /* the invalid quoted character */
193  
-
194  
-            state = sw_usual;
195  
-
196  
-            *d++ = ch;
197  
-
198  
-            break;
199  
-
200  
-        case sw_quoted_second:
201  
-
202  
-            state = sw_usual;
203  
-
204  
-            if (ch >= '0' && ch <= '9') {
205  
-                ch = (u_char) ((decoded << 4) + ch - '0');
206  
-                *d++ = ch;
207  
-                break;
208  
-            }
209  
-
210  
-            c = (u_char) (ch | 0x20);
211  
-            if (c >= 'a' && c <= 'f') {
212  
-                ch = (u_char) ((decoded << 4) + c - 'a' + 10);
213  
-
214  
-				if (ch == '/') {
215  
-                	*d++ = '%'; *d++ = '2'; *d++ = 'f';
216  
-                	break;
217  
-				}
218  
-
219  
-                *d++ = ch;
220  
-                break;
221  
-            }
222  
-
223  
-            /* the invalid quoted character */
224  
-
225  
-            break;
226  
-        }
227  
-    }
228  
-done:
229  
-    *dst = d;
230  
-    *src = s;
231  
-}
232  
-
233  
-
234 140
 static ngx_int_t
235 141
 lounge_handler(ngx_http_request_t *r)
236 142
 {
@@ -243,11 +149,8 @@ lounge_handler(ngx_http_request_t *r)
243 149
 	                    key[buffer_size], 
244 150
 	                    extra[buffer_size];
245 151
 	u_char             *uri,
246  
-					   *uri_last,
247  
-                       *orig_uri_last,
248 152
                        *unescaped_key,
249 153
                        *unescaped_key_end;
250  
-	int                 uri_len;
251 154
 
252 155
     rlcf = ngx_http_get_module_loc_conf(r, lounge_module);
253 156
 	if (!rlcf->enabled) {
@@ -265,16 +168,11 @@ lounge_handler(ngx_http_request_t *r)
265 168
 	if (ctx->uri_sharded) return NGX_DECLINED;
266 169
 
267 170
 	/* allocate enough room for a null-termed uri */
268  
-	uri = ngx_palloc(r->pool, r->unparsed_uri.len+1);
269  
-
270  
-	/* unescape everything except for slashes */
271  
-	uri_last = uri;
272  
-	orig_uri_last = r->unparsed_uri.data;
273  
-	normalize_uri(&uri_last, &orig_uri_last, r->unparsed_uri.len);
  171
+	uri = ngx_palloc(r->pool, r->unparsed_uri.len + 1);
274 172
 	
275 173
 	/* null term so we can use sscanf */
276  
-	*uri_last = '\0';
277  
-	uri_len = uri_last - uri;
  174
+	ngx_cpystrn(uri, r->unparsed_uri.data, r->unparsed_uri.len + 1);
  175
+	uri[r->unparsed_uri.len + 1] = '\0';
278 176
 
279 177
 	lmcf = ngx_http_get_module_main_conf(r, lounge_module);
280 178
 
@@ -287,7 +185,8 @@ lounge_handler(ngx_http_request_t *r)
287 185
 	 * e.g. 	/targeting/some_key
288 186
 	 *  		/targeting/some_key?vijay=hobbit
289 187
 	 */
290  
-	n = sscanf((char*)uri, "/%1024[^/]/%1024[^?/]%1024[^\n]", db, key, extra);
  188
+	*db = *key = *extra = '\0';
  189
+	n = sscanf((char*)uri, "/%1024[^/]/%1024[^?/]%1024[^?\n]", db, key, extra);
291 190
 
292 191
 	ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
293 192
 			"db: %s\nkey: %s\n", db, key);
@@ -305,35 +204,25 @@ lounge_handler(ngx_http_request_t *r)
305 204
 		return NGX_ERROR;
306 205
 	}
307 206
 
  207
+	/* unescape the key and hash it */
308 208
 	u_char* unparsed_key;
309  
-	u_char* unparsed_uri_end = r->unparsed_uri.data + r->unparsed_uri.len;
310  
-	unparsed_key = ngx_strlchr(r->unparsed_uri.data+1, unparsed_uri_end, '/');
311  
-	if (!unparsed_key) return NGX_ERROR;
312  
-	unparsed_key++;
313  
-	if (unparsed_key >= unparsed_uri_end) return NGX_ERROR;
314  
-
315  
-	u_char *qs_start = ngx_strlchr(unparsed_key, unparsed_uri_end, '?');
316  
-	u_char *unparsed_key_end = qs_start ? qs_start : unparsed_uri_end;
317  
-
318  
-	int unparsed_key_len = unparsed_key_end - unparsed_key;
319  
-
320  
-	/* hash the key to figure out which db shard it lives on */
321 209
 	unescaped_key = ngx_pcalloc(r->pool, strlen(key) + 1);
322 210
 	if (!unescaped_key) {
323 211
 		return NGX_ERROR;
324 212
 	}
325 213
 	unescaped_key_end = unescaped_key;
326  
-	ngx_cpystrn((u_char *)key, unparsed_key, unparsed_key_len + 1);
  214
+	unparsed_key = (u_char *)key;
327 215
 	ngx_unescape_uri(&unescaped_key_end, &unparsed_key,
328  
-	                 unparsed_key_end - unparsed_key,
  216
+	                 ngx_strlen(unparsed_key),
329 217
 	                 NGX_UNESCAPE_URI);
330 218
 	ngx_uint_t crc32 = (ngx_crc32_short(unescaped_key, 
331 219
 				unescaped_key_end - unescaped_key) >> 16) & 0x7fff;
332 220
 	shard_id = crc32 % lmcf->num_shards;
333 221
 	ctx->shard_id = shard_id;
334 222
 
  223
+	/* assemble the upstream uri */
335 224
 	r->uri.len = snprintf((char*)r->uri.data, 
336  
-			new_uri_len, "/%s%d/%s", db, shard_id, key);
  225
+	                      new_uri_len, "/%s%d/%s%s", db, shard_id, key, extra);
337 226
 
338 227
 	if (r->uri.len >= new_uri_len) {
339 228
 		return NGX_ERROR;

0 notes on commit 3dfb4ed

Please sign in to comment.
Something went wrong with that request. Please try again.