-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Reetesh Ranjan
committed
Dec 5, 2013
1 parent
b3b503a
commit 8f6f3d7
Showing
10 changed files
with
2,475 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
Name | ||
|
||
nginx-sphinx-module - Nginx upstream module for Sphinx 2.0 search daemon | ||
|
||
*This module is not distributed with the Nginx source.* See the installation | ||
instructions. | ||
|
||
Status | ||
|
||
Alpha | ||
|
||
Version | ||
|
||
0.1 | ||
|
||
Synopsis | ||
|
||
# Search | ||
# /search?&offset=0&nres=20&match=all | ||
# &ranker=proxbm25&rankexpr= | ||
# &sort=relevance&sortby=myattr | ||
# &keywords=Anna+Hazare | ||
# &index=myidx | ||
# &filters=a1,in,range,10,20;a2,ex,range,10,20;a3,in,frange,10.00,20.00 | ||
# &group=day,attr,@group desc,attr2 | ||
# &maxres=1000 | ||
# &geo=latattr,lonattr,10.00,10.00 | ||
# &idxweights=myidx:50;othidx:10 | ||
# &fldweights=content:100;title:0 | ||
# &format=json | ||
location /search { | ||
set_unescape_uri $sphinx2_command "search"; | ||
set_unescape_uri $sphx_offset $arg_offset; | ||
set_unescape_uri $sphx_numresults $arg_nres; | ||
set_unescape_uri $sphx_matchmode $arg_match; | ||
set_unescape_uri $sphx_ranker $arg_ranker; | ||
set_unescape_uri $sphx_rankexpr $arg_rankexpr; | ||
set_unescape_uri $sphx_sortmode $arg_sort; | ||
set_unescape_uri $sphx_sortby $arg_sortby; | ||
set_unescape_uri $sphx_keywords $arg_keywords; | ||
set_unescape_uri $sphx_index $arg_index; | ||
set_unescape_uri $sphx_filters $arg_filters; | ||
set_unescape_uri $sphx_group $arg_group; | ||
set_unescape_uri $sphx_maxmatches $arg_maxres; | ||
set_unescape_uri $sphx_geo $arg_geo; | ||
set_unescape_uri $sphx_indexweights $arg_idxweights; | ||
set_unescape_uri $sphx_fieldweights $arg_fldweights; | ||
set_unescape_uri $sphx_outputtype $arg_format; | ||
set_unescape_uri $sphx_docid "0"; | ||
sphinx2_pass 127.0.0.1:9312; | ||
} | ||
|
||
Description | ||
|
||
This is an Nginx upstream module that makes nginx talk to a Sphinx | ||
(<http://sphinxsearch.com/>) 2.x server in a non-blocking way. | ||
|
||
Following features are supported as of now. | ||
1 Searching | ||
|
||
This module supports 3 output formats - XML, JSON and Raw. The URL's | ||
outputformat query parameter can be used to specify the desired one. | ||
|
||
Limitations | ||
|
||
<TODO> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
ngx_addon_name=ngx_http_sphinx2_module | ||
|
||
HTTP_MODULES="$HTTP_MODULES ngx_http_sphinx2_module" | ||
|
||
NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/src/ngx_http_sphinx2_args_parser.h $ngx_addon_dir/src/ngx_http_sphinx2_stream.h $ngx_addon_dir/src/ngx_http_sphinx2_sphx.h" | ||
|
||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/src/ngx_http_sphinx2_args_parser.c $ngx_addon_dir/src/ngx_http_sphinx2_stream.c $ngx_addon_dir/src/ngx_http_sphinx2_sphx.c $ngx_addon_dir/src/ngx_http_sphinx2_module.c" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,265 @@ | ||
/* | ||
* Sphinx upstream module URI query params parsing | ||
*/ | ||
|
||
#include <ngx_config.h> | ||
#include <ngx_core.h> | ||
#include <ngx_http.h> | ||
#include <assert.h> | ||
#include "ngx_http_sphinx2_args_parser.h" | ||
|
||
/* FUNCTION DEFINITIONS */ | ||
|
||
/* register the input, hints and delimiter to create a parsing ctx */ | ||
ngx_int_t | ||
sphx2_arg_parse_register( | ||
sphx2_arg_parse_ctx_t * ctxt, | ||
ngx_pool_t * pool, | ||
char * input, | ||
sphx2_arg_parse_hint_t * hints, | ||
const char * delimiter) | ||
{ | ||
ctxt->input = input; | ||
ctxt->hints = hints; | ||
ctxt->delimiter = delimiter; | ||
ctxt->curr = NULL; | ||
ctxt->num_tokens = 0; | ||
ctxt->pool = pool; | ||
|
||
return NGX_OK; | ||
} | ||
|
||
/* register current 'token' of a ctx to another to parse it further */ | ||
ngx_int_t | ||
sphx2_arg_parse_register_child( | ||
sphx2_arg_parse_ctx_t * to, | ||
sphx2_arg_parse_ctx_t * from, | ||
ngx_pool_t * pool, | ||
sphx2_arg_parse_hint_t * hints, | ||
const char * delimiter) | ||
{ | ||
assert(NULL != from->curr); | ||
|
||
return sphx2_arg_parse_register(to, pool, from->curr, hints, delimiter); | ||
} | ||
|
||
/* take one tokenizing step, so curr and input pointers are modified */ | ||
ngx_int_t | ||
sphx2_arg_step(sphx2_arg_parse_ctx_t * ctxt) | ||
{ | ||
if(NULL == (ctxt->curr = strsep(&ctxt->input, ctxt->delimiter))) { | ||
return NGX_ERROR; | ||
} | ||
|
||
++ctxt->num_tokens; | ||
|
||
return NGX_OK; | ||
} | ||
|
||
/* get a string arg - internally does a 'step' and also a check using | ||
* the hints if available | ||
*/ | ||
ngx_str_t* | ||
sphx2_arg_parse_get_str_arg(sphx2_arg_parse_ctx_t * ctxt) | ||
{ | ||
ngx_str_t * str; | ||
|
||
if(NULL != ctxt->hints && | ||
SPHX2_ARG_TYPE_STRING != | ||
ctxt->hints[ctxt->num_tokens].param_type) | ||
{ | ||
return(NULL); | ||
} | ||
|
||
if(NGX_ERROR == sphx2_arg_step(ctxt)) | ||
return (NULL); | ||
|
||
if(NULL == (str = ngx_palloc(ctxt->pool, sizeof(ngx_str_t)))) { | ||
return(NULL); | ||
} | ||
|
||
str->len = strlen(ctxt->curr)+1; | ||
|
||
if(NULL == (str->data = ngx_palloc(ctxt->pool, str->len))) { | ||
return(NULL); | ||
} | ||
|
||
memcpy(str->data, ctxt->curr, str->len); | ||
|
||
return(str); | ||
} | ||
|
||
/* get an integer arg - internally does a 'step' and also a check using | ||
* the hints if available | ||
*/ | ||
uint32_t | ||
sphx2_arg_parse_get_int_arg(sphx2_arg_parse_ctx_t * ctxt) | ||
{ | ||
if(NULL != ctxt->hints && | ||
SPHX2_ARG_TYPE_INTEGER != | ||
ctxt->hints[ctxt->num_tokens].param_type) | ||
{ | ||
return(NGX_ERROR); | ||
} | ||
|
||
if(NGX_ERROR == sphx2_arg_step(ctxt)) | ||
return (NGX_ERROR); | ||
|
||
return(atoi(ctxt->curr)); | ||
} | ||
|
||
/* get an int64 arg - internally does a 'step' and also a check using | ||
* the hints if available | ||
*/ | ||
uint64_t | ||
sphx2_arg_parse_get_int64_arg(sphx2_arg_parse_ctx_t * ctxt) | ||
{ | ||
if(NULL != ctxt->hints && | ||
SPHX2_ARG_TYPE_INTEGER64 != | ||
ctxt->hints[ctxt->num_tokens].param_type) | ||
{ | ||
return(NGX_ERROR); | ||
} | ||
|
||
if(NGX_ERROR == sphx2_arg_step(ctxt)) | ||
return (NGX_ERROR); | ||
|
||
return(strtoll(ctxt->curr, NULL, 10)); | ||
} | ||
|
||
/* get a float arg - internally does a 'step' and also a check using | ||
* the hints if available | ||
*/ | ||
float | ||
sphx2_arg_parse_get_float_arg(sphx2_arg_parse_ctx_t * ctxt) | ||
{ | ||
if(NULL != ctxt->hints && | ||
SPHX2_ARG_TYPE_FLOAT != | ||
ctxt->hints[ctxt->num_tokens].param_type) | ||
{ | ||
return((float)NGX_ERROR); | ||
} | ||
|
||
if(NGX_ERROR == sphx2_arg_step(ctxt)) | ||
return ((float)NGX_ERROR); | ||
|
||
return(atof(ctxt->curr)); | ||
} | ||
|
||
/* get an enum arg - internally does a 'step' and also a check using | ||
* the hints if available. the matching str-arr if specified overrides | ||
* the hints (if specified). one of the arg here or hint must be | ||
* available. | ||
*/ | ||
int32_t | ||
sphx2_arg_parse_get_enum_arg( | ||
sphx2_arg_parse_ctx_t * ctxt, | ||
const char * str_arr[], | ||
size_t sz_str_arr) | ||
{ | ||
size_t i; | ||
|
||
if(NULL != ctxt->hints && | ||
SPHX2_ARG_TYPE_ENUM != | ||
ctxt->hints[ctxt->num_tokens].param_type) | ||
{ | ||
return(NGX_ERROR); | ||
} | ||
|
||
assert(!(NULL == str_arr && NULL == ctxt->hints)); | ||
|
||
if(NULL == str_arr) { | ||
str_arr = ctxt->hints[ctxt->num_tokens].str_arr; | ||
sz_str_arr = ctxt->hints[ctxt->num_tokens].sz_str_arr; | ||
} | ||
|
||
if(NGX_ERROR == sphx2_arg_step(ctxt)) | ||
return (NGX_ERROR); | ||
|
||
for(i = 0; i < sz_str_arr; ++i) { | ||
if(!strncmp(ctxt->curr, str_arr[i], strlen(str_arr[i]))) { | ||
return (i); | ||
} | ||
} | ||
|
||
return(NGX_ERROR); | ||
} | ||
|
||
/* parse the whole input using the hints and copy the results in the | ||
* order specified by hints array into the target pointer arg assuming | ||
* it is a struct pointer with elements of types specified in hints | ||
* occurring in that order | ||
*/ | ||
ngx_int_t | ||
sphx2_arg_parse_whole_using_hints( | ||
sphx2_arg_parse_ctx_t * ctxt, | ||
void * ptr) | ||
{ | ||
#define APPEND_4_BYTES(p, v, a) \ | ||
do { \ | ||
memcpy(p, v, sizeof(uint32_t)); \ | ||
p = (void*)((uint64_t)p + sizeof(uint32_t)); \ | ||
a = 1 - a; \ | ||
} while(0) | ||
|
||
#define APPEND_8_BYTES(p, v, a) \ | ||
do { \ | ||
if(0==a) { p = (void*)((uint64_t)p + sizeof(uint32_t)); a = 1;}; \ | ||
memcpy(p, v, sizeof(uint64_t)); \ | ||
p = (void*)((uint64_t)p + sizeof(uint64_t)); \ | ||
} while(0) | ||
|
||
size_t i = 0; | ||
int32_t is_ptr_aligned = 1; | ||
union { uint32_t i; uint64_t i64; float f; ngx_str_t* s; int32_t e; } v; | ||
|
||
assert(NULL != ctxt->hints); | ||
|
||
while(SPHX2_ARG_TYPE_NONE != ctxt->hints[i].param_type) { | ||
|
||
switch(ctxt->hints[i].param_type) { | ||
case SPHX2_ARG_TYPE_INTEGER: | ||
if((uint32_t)NGX_ERROR == (v.i = sphx2_arg_parse_get_int_arg(ctxt))) | ||
{ | ||
return(NGX_ERROR); | ||
} | ||
APPEND_4_BYTES(ptr, &v.i, is_ptr_aligned); | ||
break; | ||
case SPHX2_ARG_TYPE_INTEGER64: | ||
if((uint64_t)NGX_ERROR == (v.i64 = sphx2_arg_parse_get_int64_arg(ctxt))) | ||
{ | ||
return(NGX_ERROR); | ||
} | ||
APPEND_8_BYTES(ptr, &v.i64, is_ptr_aligned); | ||
break; | ||
case SPHX2_ARG_TYPE_FLOAT: | ||
if((float)NGX_ERROR == (v.f = sphx2_arg_parse_get_float_arg(ctxt))) | ||
{ | ||
return(NGX_ERROR); | ||
} | ||
APPEND_4_BYTES(ptr, &v.i, is_ptr_aligned); | ||
break; | ||
case SPHX2_ARG_TYPE_STRING: | ||
if(NULL == (v.s = sphx2_arg_parse_get_str_arg(ctxt))) | ||
{ | ||
return(NGX_ERROR); | ||
} | ||
APPEND_8_BYTES(ptr, &v.s, is_ptr_aligned); | ||
break; | ||
case SPHX2_ARG_TYPE_ENUM: | ||
if((int32_t)NGX_ERROR == (v.e = sphx2_arg_parse_get_enum_arg(ctxt, | ||
ctxt->hints[i].str_arr, ctxt->hints[i].sz_str_arr))) | ||
{ | ||
return(NGX_ERROR); | ||
} | ||
APPEND_4_BYTES(ptr, &v.e, is_ptr_aligned); | ||
break; | ||
default: | ||
assert(0); | ||
} | ||
|
||
++i; | ||
} | ||
|
||
return (NGX_OK); | ||
} |
Oops, something went wrong.