12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901 |
- /*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
- #include <ngx_config.h>
- #include <ngx_core.h>
- #include <ngx_http.h>
- static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);
- static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
- static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,
- ngx_str_t *value, ngx_uint_t last);
- static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc,
- ngx_str_t *name);
- static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc);
- #if (NGX_PCRE)
- static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc,
- ngx_uint_t n);
- #endif
- static ngx_int_t
- ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc);
- static size_t ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e);
- static void ngx_http_script_full_name_code(ngx_http_script_engine_t *e);
- #define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code
- static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;
- void
- ngx_http_script_flush_complex_value(ngx_http_request_t *r,
- ngx_http_complex_value_t *val)
- {
- ngx_uint_t *index;
- index = val->flushes;
- if (index) {
- while (*index != (ngx_uint_t) -1) {
- if (r->variables[*index].no_cacheable) {
- r->variables[*index].valid = 0;
- r->variables[*index].not_found = 0;
- }
- index++;
- }
- }
- }
- ngx_int_t
- ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val,
- ngx_str_t *value)
- {
- size_t len;
- ngx_http_script_code_pt code;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_engine_t e;
- if (val->lengths == NULL) {
- *value = val->value;
- return NGX_OK;
- }
- ngx_http_script_flush_complex_value(r, val);
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
- e.ip = val->lengths;
- e.request = r;
- e.flushed = 1;
- len = 0;
- while (*(uintptr_t *) e.ip) {
- lcode = *(ngx_http_script_len_code_pt *) e.ip;
- len += lcode(&e);
- }
- value->len = len;
- value->data = ngx_pnalloc(r->pool, len);
- if (value->data == NULL) {
- return NGX_ERROR;
- }
- e.ip = val->values;
- e.pos = value->data;
- e.buf = *value;
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
- *value = e.buf;
- return NGX_OK;
- }
- size_t
- ngx_http_complex_value_size(ngx_http_request_t *r,
- ngx_http_complex_value_t *val, size_t default_value)
- {
- size_t size;
- ngx_str_t value;
- if (val == NULL) {
- return default_value;
- }
- if (val->lengths == NULL) {
- return val->u.size;
- }
- if (ngx_http_complex_value(r, val, &value) != NGX_OK) {
- return default_value;
- }
- size = ngx_parse_size(&value);
- if (size == (size_t) NGX_ERROR) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid size \"%V\"", &value);
- return default_value;
- }
- return size;
- }
- ngx_int_t
- ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
- {
- ngx_str_t *v;
- ngx_uint_t i, n, nv, nc;
- ngx_array_t flushes, lengths, values, *pf, *pl, *pv;
- ngx_http_script_compile_t sc;
- v = ccv->value;
- nv = 0;
- nc = 0;
- for (i = 0; i < v->len; i++) {
- if (v->data[i] == '$') {
- if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
- nc++;
- } else {
- nv++;
- }
- }
- }
- if ((v->len == 0 || v->data[0] != '$')
- && (ccv->conf_prefix || ccv->root_prefix))
- {
- if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
- return NGX_ERROR;
- }
- ccv->conf_prefix = 0;
- ccv->root_prefix = 0;
- }
- ccv->complex_value->value = *v;
- ccv->complex_value->flushes = NULL;
- ccv->complex_value->lengths = NULL;
- ccv->complex_value->values = NULL;
- if (nv == 0 && nc == 0) {
- return NGX_OK;
- }
- n = nv + 1;
- if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- n = nv * (2 * sizeof(ngx_http_script_copy_code_t)
- + sizeof(ngx_http_script_var_code_t))
- + sizeof(uintptr_t);
- if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
- return NGX_ERROR;
- }
- n = (nv * (2 * sizeof(ngx_http_script_copy_code_t)
- + sizeof(ngx_http_script_var_code_t))
- + sizeof(uintptr_t)
- + v->len
- + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
- if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
- return NGX_ERROR;
- }
- pf = &flushes;
- pl = &lengths;
- pv = &values;
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
- sc.cf = ccv->cf;
- sc.source = v;
- sc.flushes = &pf;
- sc.lengths = &pl;
- sc.values = &pv;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
- sc.zero = ccv->zero;
- sc.conf_prefix = ccv->conf_prefix;
- sc.root_prefix = ccv->root_prefix;
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_ERROR;
- }
- if (flushes.nelts) {
- ccv->complex_value->flushes = flushes.elts;
- ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
- }
- ccv->complex_value->lengths = lengths.elts;
- ccv->complex_value->values = values.elts;
- return NGX_OK;
- }
- char *
- ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
- {
- char *p = conf;
- ngx_str_t *value;
- ngx_http_complex_value_t **cv;
- ngx_http_compile_complex_value_t ccv;
- cv = (ngx_http_complex_value_t **) (p + cmd->offset);
- if (*cv != NGX_CONF_UNSET_PTR && *cv != NULL) {
- return "is duplicate";
- }
- *cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (*cv == NULL) {
- return NGX_CONF_ERROR;
- }
- value = cf->args->elts;
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = *cv;
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- return NGX_CONF_OK;
- }
- char *
- ngx_http_set_complex_value_zero_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
- {
- char *p = conf;
- ngx_str_t *value;
- ngx_http_complex_value_t **cv;
- ngx_http_compile_complex_value_t ccv;
- cv = (ngx_http_complex_value_t **) (p + cmd->offset);
- if (*cv != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
- *cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (*cv == NULL) {
- return NGX_CONF_ERROR;
- }
- value = cf->args->elts;
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = *cv;
- ccv.zero = 1;
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- return NGX_CONF_OK;
- }
- char *
- ngx_http_set_complex_value_size_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
- {
- char *p = conf;
- char *rv;
- ngx_http_complex_value_t *cv;
- rv = ngx_http_set_complex_value_slot(cf, cmd, conf);
- if (rv != NGX_CONF_OK) {
- return rv;
- }
- cv = *(ngx_http_complex_value_t **) (p + cmd->offset);
- if (cv->lengths) {
- return NGX_CONF_OK;
- }
- cv->u.size = ngx_parse_size(&cv->value);
- if (cv->u.size == (size_t) NGX_ERROR) {
- return "invalid value";
- }
- return NGX_CONF_OK;
- }
- ngx_int_t
- ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates)
- {
- ngx_str_t val;
- ngx_uint_t i;
- ngx_http_complex_value_t *cv;
- if (predicates == NULL) {
- return NGX_OK;
- }
- cv = predicates->elts;
- for (i = 0; i < predicates->nelts; i++) {
- if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) {
- return NGX_ERROR;
- }
- if (val.len && (val.len != 1 || val.data[0] != '0')) {
- return NGX_DECLINED;
- }
- }
- return NGX_OK;
- }
- ngx_int_t
- ngx_http_test_required_predicates(ngx_http_request_t *r,
- ngx_array_t *predicates)
- {
- ngx_str_t val;
- ngx_uint_t i;
- ngx_http_complex_value_t *cv;
- if (predicates == NULL) {
- return NGX_OK;
- }
- cv = predicates->elts;
- for (i = 0; i < predicates->nelts; i++) {
- if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) {
- return NGX_ERROR;
- }
- if (val.len == 0 || (val.len == 1 && val.data[0] == '0')) {
- return NGX_DECLINED;
- }
- }
- return NGX_OK;
- }
- char *
- ngx_http_set_predicate_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
- {
- char *p = conf;
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_array_t **a;
- ngx_http_complex_value_t *cv;
- ngx_http_compile_complex_value_t ccv;
- a = (ngx_array_t **) (p + cmd->offset);
- if (*a == NGX_CONF_UNSET_PTR) {
- *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t));
- if (*a == NULL) {
- return NGX_CONF_ERROR;
- }
- }
- value = cf->args->elts;
- for (i = 1; i < cf->args->nelts; i++) {
- cv = ngx_array_push(*a);
- if (cv == NULL) {
- return NGX_CONF_ERROR;
- }
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
- ccv.cf = cf;
- ccv.value = &value[i];
- ccv.complex_value = cv;
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
- return NGX_CONF_OK;
- }
- ngx_uint_t
- ngx_http_script_variables_count(ngx_str_t *value)
- {
- ngx_uint_t i, n;
- for (n = 0, i = 0; i < value->len; i++) {
- if (value->data[i] == '$') {
- n++;
- }
- }
- return n;
- }
- ngx_int_t
- ngx_http_script_compile(ngx_http_script_compile_t *sc)
- {
- u_char ch;
- ngx_str_t name;
- ngx_uint_t i, bracket;
- if (ngx_http_script_init_arrays(sc) != NGX_OK) {
- return NGX_ERROR;
- }
- for (i = 0; i < sc->source->len; /* void */ ) {
- name.len = 0;
- if (sc->source->data[i] == '$') {
- if (++i == sc->source->len) {
- goto invalid_variable;
- }
- if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
- #if (NGX_PCRE)
- ngx_uint_t n;
- n = sc->source->data[i] - '0';
- if (sc->captures_mask & ((ngx_uint_t) 1 << n)) {
- sc->dup_capture = 1;
- }
- sc->captures_mask |= (ngx_uint_t) 1 << n;
- if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) {
- return NGX_ERROR;
- }
- i++;
- continue;
- #else
- ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
- "using variable \"$%c\" requires "
- "PCRE library", sc->source->data[i]);
- return NGX_ERROR;
- #endif
- }
- if (sc->source->data[i] == '{') {
- bracket = 1;
- if (++i == sc->source->len) {
- goto invalid_variable;
- }
- name.data = &sc->source->data[i];
- } else {
- bracket = 0;
- name.data = &sc->source->data[i];
- }
- for ( /* void */ ; i < sc->source->len; i++, name.len++) {
- ch = sc->source->data[i];
- if (ch == '}' && bracket) {
- i++;
- bracket = 0;
- break;
- }
- if ((ch >= 'A' && ch <= 'Z')
- || (ch >= 'a' && ch <= 'z')
- || (ch >= '0' && ch <= '9')
- || ch == '_')
- {
- continue;
- }
- break;
- }
- if (bracket) {
- ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
- "the closing bracket in \"%V\" "
- "variable is missing", &name);
- return NGX_ERROR;
- }
- if (name.len == 0) {
- goto invalid_variable;
- }
- sc->variables++;
- if (ngx_http_script_add_var_code(sc, &name) != NGX_OK) {
- return NGX_ERROR;
- }
- continue;
- }
- if (sc->source->data[i] == '?' && sc->compile_args) {
- sc->args = 1;
- sc->compile_args = 0;
- if (ngx_http_script_add_args_code(sc) != NGX_OK) {
- return NGX_ERROR;
- }
- i++;
- continue;
- }
- name.data = &sc->source->data[i];
- while (i < sc->source->len) {
- if (sc->source->data[i] == '$') {
- break;
- }
- if (sc->source->data[i] == '?') {
- sc->args = 1;
- if (sc->compile_args) {
- break;
- }
- }
- i++;
- name.len++;
- }
- sc->size += name.len;
- if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
- return ngx_http_script_done(sc);
- invalid_variable:
- ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
- return NGX_ERROR;
- }
- u_char *
- ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
- void *code_lengths, size_t len, void *code_values)
- {
- ngx_uint_t i;
- ngx_http_script_code_pt code;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_engine_t e;
- ngx_http_core_main_conf_t *cmcf;
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
- for (i = 0; i < cmcf->variables.nelts; i++) {
- if (r->variables[i].no_cacheable) {
- r->variables[i].valid = 0;
- r->variables[i].not_found = 0;
- }
- }
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
- e.ip = code_lengths;
- e.request = r;
- e.flushed = 1;
- while (*(uintptr_t *) e.ip) {
- lcode = *(ngx_http_script_len_code_pt *) e.ip;
- len += lcode(&e);
- }
- value->len = len;
- value->data = ngx_pnalloc(r->pool, len);
- if (value->data == NULL) {
- return NULL;
- }
- e.ip = code_values;
- e.pos = value->data;
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
- return e.pos;
- }
- void
- ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
- ngx_array_t *indices)
- {
- ngx_uint_t n, *index;
- if (indices) {
- index = indices->elts;
- for (n = 0; n < indices->nelts; n++) {
- if (r->variables[index[n]].no_cacheable) {
- r->variables[index[n]].valid = 0;
- r->variables[index[n]].not_found = 0;
- }
- }
- }
- }
- static ngx_int_t
- ngx_http_script_init_arrays(ngx_http_script_compile_t *sc)
- {
- ngx_uint_t n;
- if (sc->flushes && *sc->flushes == NULL) {
- n = sc->variables ? sc->variables : 1;
- *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
- if (*sc->flushes == NULL) {
- return NGX_ERROR;
- }
- }
- if (*sc->lengths == NULL) {
- n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
- + sizeof(ngx_http_script_var_code_t))
- + sizeof(uintptr_t);
- *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
- if (*sc->lengths == NULL) {
- return NGX_ERROR;
- }
- }
- if (*sc->values == NULL) {
- n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
- + sizeof(ngx_http_script_var_code_t))
- + sizeof(uintptr_t)
- + sc->source->len
- + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
- *sc->values = ngx_array_create(sc->cf->pool, n, 1);
- if (*sc->values == NULL) {
- return NGX_ERROR;
- }
- }
- sc->variables = 0;
- return NGX_OK;
- }
- static ngx_int_t
- ngx_http_script_done(ngx_http_script_compile_t *sc)
- {
- ngx_str_t zero;
- uintptr_t *code;
- if (sc->zero) {
- zero.len = 1;
- zero.data = (u_char *) "\0";
- if (ngx_http_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
- return NGX_ERROR;
- }
- }
- if (sc->conf_prefix || sc->root_prefix) {
- if (ngx_http_script_add_full_name_code(sc) != NGX_OK) {
- return NGX_ERROR;
- }
- }
- if (sc->complete_lengths) {
- code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
- *code = (uintptr_t) NULL;
- }
- if (sc->complete_values) {
- code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
- &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
- *code = (uintptr_t) NULL;
- }
- return NGX_OK;
- }
- void *
- ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
- {
- if (*codes == NULL) {
- *codes = ngx_array_create(pool, 256, 1);
- if (*codes == NULL) {
- return NULL;
- }
- }
- return ngx_array_push_n(*codes, size);
- }
- void *
- ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code)
- {
- u_char *elts, **p;
- void *new;
- elts = codes->elts;
- new = ngx_array_push_n(codes, size);
- if (new == NULL) {
- return NULL;
- }
- if (code) {
- if (elts != codes->elts) {
- p = code;
- *p += (u_char *) codes->elts - elts;
- }
- }
- return new;
- }
- static ngx_int_t
- ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value,
- ngx_uint_t last)
- {
- u_char *p;
- size_t size, len, zero;
- ngx_http_script_copy_code_t *code;
- zero = (sc->zero && last);
- len = value->len + zero;
- code = ngx_http_script_add_code(*sc->lengths,
- sizeof(ngx_http_script_copy_code_t), NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
- code->code = (ngx_http_script_code_pt) (void *)
- ngx_http_script_copy_len_code;
- code->len = len;
- size = (sizeof(ngx_http_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
- code = ngx_http_script_add_code(*sc->values, size, &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
- code->code = ngx_http_script_copy_code;
- code->len = len;
- p = ngx_cpymem((u_char *) code + sizeof(ngx_http_script_copy_code_t),
- value->data, value->len);
- if (zero) {
- *p = '\0';
- sc->zero = 0;
- }
- return NGX_OK;
- }
- size_t
- ngx_http_script_copy_len_code(ngx_http_script_engine_t *e)
- {
- ngx_http_script_copy_code_t *code;
- code = (ngx_http_script_copy_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_copy_code_t);
- return code->len;
- }
- void
- ngx_http_script_copy_code(ngx_http_script_engine_t *e)
- {
- u_char *p;
- ngx_http_script_copy_code_t *code;
- code = (ngx_http_script_copy_code_t *) e->ip;
- p = e->pos;
- if (!e->skip) {
- e->pos = ngx_copy(p, e->ip + sizeof(ngx_http_script_copy_code_t),
- code->len);
- }
- e->ip += sizeof(ngx_http_script_copy_code_t)
- + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script copy: \"%*s\"", e->pos - p, p);
- }
- static ngx_int_t
- ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, ngx_str_t *name)
- {
- ngx_int_t index, *p;
- ngx_http_script_var_code_t *code;
- index = ngx_http_get_variable_index(sc->cf, name);
- if (index == NGX_ERROR) {
- return NGX_ERROR;
- }
- if (sc->flushes) {
- p = ngx_array_push(*sc->flushes);
- if (p == NULL) {
- return NGX_ERROR;
- }
- *p = index;
- }
- code = ngx_http_script_add_code(*sc->lengths,
- sizeof(ngx_http_script_var_code_t), NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
- code->code = (ngx_http_script_code_pt) (void *)
- ngx_http_script_copy_var_len_code;
- code->index = (uintptr_t) index;
- code = ngx_http_script_add_code(*sc->values,
- sizeof(ngx_http_script_var_code_t),
- &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
- code->code = ngx_http_script_copy_var_code;
- code->index = (uintptr_t) index;
- return NGX_OK;
- }
- size_t
- ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e)
- {
- ngx_http_variable_value_t *value;
- ngx_http_script_var_code_t *code;
- code = (ngx_http_script_var_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_var_code_t);
- if (e->flushed) {
- value = ngx_http_get_indexed_variable(e->request, code->index);
- } else {
- value = ngx_http_get_flushed_variable(e->request, code->index);
- }
- if (value && !value->not_found) {
- return value->len;
- }
- return 0;
- }
- void
- ngx_http_script_copy_var_code(ngx_http_script_engine_t *e)
- {
- u_char *p;
- ngx_http_variable_value_t *value;
- ngx_http_script_var_code_t *code;
- code = (ngx_http_script_var_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_var_code_t);
- if (!e->skip) {
- if (e->flushed) {
- value = ngx_http_get_indexed_variable(e->request, code->index);
- } else {
- value = ngx_http_get_flushed_variable(e->request, code->index);
- }
- if (value && !value->not_found) {
- p = e->pos;
- e->pos = ngx_copy(p, value->data, value->len);
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP,
- e->request->connection->log, 0,
- "http script var: \"%*s\"", e->pos - p, p);
- }
- }
- }
- static ngx_int_t
- ngx_http_script_add_args_code(ngx_http_script_compile_t *sc)
- {
- uintptr_t *code;
- code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
- *code = (uintptr_t) ngx_http_script_mark_args_code;
- code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t), &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
- *code = (uintptr_t) ngx_http_script_start_args_code;
- return NGX_OK;
- }
- size_t
- ngx_http_script_mark_args_code(ngx_http_script_engine_t *e)
- {
- e->is_args = 1;
- e->ip += sizeof(uintptr_t);
- return 1;
- }
- void
- ngx_http_script_start_args_code(ngx_http_script_engine_t *e)
- {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script args");
- e->is_args = 1;
- e->args = e->pos;
- e->ip += sizeof(uintptr_t);
- }
- #if (NGX_PCRE)
- void
- ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
- {
- size_t len;
- ngx_int_t rc;
- ngx_uint_t n;
- ngx_http_request_t *r;
- ngx_http_script_engine_t le;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_regex_code_t *code;
- code = (ngx_http_script_regex_code_t *) e->ip;
- r = e->request;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http script regex: \"%V\"", &code->name);
- if (code->uri) {
- e->line = r->uri;
- } else {
- e->sp--;
- e->line.len = e->sp->len;
- e->line.data = e->sp->data;
- }
- rc = ngx_http_regex_exec(r, code->regex, &e->line);
- if (rc == NGX_DECLINED) {
- if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "\"%V\" does not match \"%V\"",
- &code->name, &e->line);
- }
- r->ncaptures = 0;
- if (code->test) {
- if (code->negative_test) {
- e->sp->len = 1;
- e->sp->data = (u_char *) "1";
- } else {
- e->sp->len = 0;
- e->sp->data = (u_char *) "";
- }
- e->sp++;
- e->ip += sizeof(ngx_http_script_regex_code_t);
- return;
- }
- e->ip += code->next;
- return;
- }
- if (rc == NGX_ERROR) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "\"%V\" matches \"%V\"", &code->name, &e->line);
- }
- if (code->test) {
- if (code->negative_test) {
- e->sp->len = 0;
- e->sp->data = (u_char *) "";
- } else {
- e->sp->len = 1;
- e->sp->data = (u_char *) "1";
- }
- e->sp++;
- e->ip += sizeof(ngx_http_script_regex_code_t);
- return;
- }
- if (code->status) {
- e->status = code->status;
- if (!code->redirect) {
- e->ip = ngx_http_script_exit;
- return;
- }
- }
- if (code->uri) {
- r->internal = 1;
- r->valid_unparsed_uri = 0;
- if (code->break_cycle) {
- r->valid_location = 0;
- r->uri_changed = 0;
- } else {
- r->uri_changed = 1;
- }
- }
- if (code->lengths == NULL) {
- e->buf.len = code->size;
- if (code->uri) {
- if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) {
- e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
- NGX_ESCAPE_ARGS);
- }
- }
- for (n = 2; n < r->ncaptures; n += 2) {
- e->buf.len += r->captures[n + 1] - r->captures[n];
- }
- } else {
- ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
- le.ip = code->lengths->elts;
- le.line = e->line;
- le.request = r;
- le.quote = code->redirect;
- len = 0;
- while (*(uintptr_t *) le.ip) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- len += lcode(&le);
- }
- e->buf.len = len;
- }
- if (code->add_args && r->args.len) {
- e->buf.len += r->args.len + 1;
- }
- e->buf.data = ngx_pnalloc(r->pool, e->buf.len);
- if (e->buf.data == NULL) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- e->quote = code->redirect;
- e->pos = e->buf.data;
- e->ip += sizeof(ngx_http_script_regex_code_t);
- }
- void
- ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
- {
- u_char *dst, *src;
- ngx_http_request_t *r;
- ngx_http_script_regex_end_code_t *code;
- code = (ngx_http_script_regex_end_code_t *) e->ip;
- r = e->request;
- e->quote = 0;
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http script regex end");
- if (code->redirect) {
- dst = e->buf.data;
- src = e->buf.data;
- ngx_unescape_uri(&dst, &src, e->pos - e->buf.data,
- NGX_UNESCAPE_REDIRECT);
- if (src < e->pos) {
- dst = ngx_movemem(dst, src, e->pos - src);
- }
- e->pos = dst;
- if (code->add_args && r->args.len) {
- *e->pos++ = (u_char) (code->args ? '&' : '?');
- e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
- }
- e->buf.len = e->pos - e->buf.data;
- if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "rewritten redirect: \"%V\"", &e->buf);
- }
- ngx_http_clear_location(r);
- r->headers_out.location = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.location == NULL) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- r->headers_out.location->hash = 1;
- r->headers_out.location->next = NULL;
- ngx_str_set(&r->headers_out.location->key, "Location");
- r->headers_out.location->value = e->buf;
- e->ip += sizeof(ngx_http_script_regex_end_code_t);
- return;
- }
- if (e->args) {
- e->buf.len = e->args - e->buf.data;
- if (code->add_args && r->args.len) {
- *e->pos++ = '&';
- e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
- }
- r->args.len = e->pos - e->args;
- r->args.data = e->args;
- e->args = NULL;
- } else {
- e->buf.len = e->pos - e->buf.data;
- if (!code->add_args) {
- r->args.len = 0;
- }
- }
- if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "rewritten data: \"%V\", args: \"%V\"",
- &e->buf, &r->args);
- }
- if (code->uri) {
- r->uri = e->buf;
- if (r->uri.len == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "the rewritten URI has a zero length");
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- ngx_http_set_exten(r);
- }
- e->ip += sizeof(ngx_http_script_regex_end_code_t);
- }
- static ngx_int_t
- ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, ngx_uint_t n)
- {
- ngx_http_script_copy_capture_code_t *code;
- code = ngx_http_script_add_code(*sc->lengths,
- sizeof(ngx_http_script_copy_capture_code_t),
- NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
- code->code = (ngx_http_script_code_pt) (void *)
- ngx_http_script_copy_capture_len_code;
- code->n = 2 * n;
- code = ngx_http_script_add_code(*sc->values,
- sizeof(ngx_http_script_copy_capture_code_t),
- &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
- code->code = ngx_http_script_copy_capture_code;
- code->n = 2 * n;
- if (sc->ncaptures < n) {
- sc->ncaptures = n;
- }
- return NGX_OK;
- }
- size_t
- ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
- {
- int *cap;
- u_char *p;
- ngx_uint_t n;
- ngx_http_request_t *r;
- ngx_http_script_copy_capture_code_t *code;
- r = e->request;
- code = (ngx_http_script_copy_capture_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_copy_capture_code_t);
- n = code->n;
- if (n < r->ncaptures) {
- cap = r->captures;
- if ((e->is_args || e->quote)
- && (e->request->quoted_uri || e->request->plus_in_uri))
- {
- p = r->captures_data;
- return cap[n + 1] - cap[n]
- + 2 * ngx_escape_uri(NULL, &p[cap[n]], cap[n + 1] - cap[n],
- NGX_ESCAPE_ARGS);
- } else {
- return cap[n + 1] - cap[n];
- }
- }
- return 0;
- }
- void
- ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
- {
- int *cap;
- u_char *p, *pos;
- ngx_uint_t n;
- ngx_http_request_t *r;
- ngx_http_script_copy_capture_code_t *code;
- r = e->request;
- code = (ngx_http_script_copy_capture_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_copy_capture_code_t);
- n = code->n;
- pos = e->pos;
- if (n < r->ncaptures) {
- cap = r->captures;
- p = r->captures_data;
- if ((e->is_args || e->quote)
- && (e->request->quoted_uri || e->request->plus_in_uri))
- {
- e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]],
- cap[n + 1] - cap[n],
- NGX_ESCAPE_ARGS);
- } else {
- e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
- }
- }
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script capture: \"%*s\"", e->pos - pos, pos);
- }
- #endif
- static ngx_int_t
- ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc)
- {
- ngx_http_script_full_name_code_t *code;
- code = ngx_http_script_add_code(*sc->lengths,
- sizeof(ngx_http_script_full_name_code_t),
- NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
- code->code = (ngx_http_script_code_pt) (void *)
- ngx_http_script_full_name_len_code;
- code->conf_prefix = sc->conf_prefix;
- code = ngx_http_script_add_code(*sc->values,
- sizeof(ngx_http_script_full_name_code_t),
- &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
- code->code = ngx_http_script_full_name_code;
- code->conf_prefix = sc->conf_prefix;
- return NGX_OK;
- }
- static size_t
- ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e)
- {
- ngx_http_script_full_name_code_t *code;
- code = (ngx_http_script_full_name_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_full_name_code_t);
- return code->conf_prefix ? ngx_cycle->conf_prefix.len:
- ngx_cycle->prefix.len;
- }
- static void
- ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
- {
- ngx_http_script_full_name_code_t *code;
- ngx_str_t value, *prefix;
- code = (ngx_http_script_full_name_code_t *) e->ip;
- value.data = e->buf.data;
- value.len = e->pos - e->buf.data;
- prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix:
- (ngx_str_t *) &ngx_cycle->prefix;
- if (ngx_get_full_name(e->request->pool, prefix, &value) != NGX_OK) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- e->buf = value;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script fullname: \"%V\"", &value);
- e->ip += sizeof(ngx_http_script_full_name_code_t);
- }
- void
- ngx_http_script_return_code(ngx_http_script_engine_t *e)
- {
- ngx_http_script_return_code_t *code;
- code = (ngx_http_script_return_code_t *) e->ip;
- if (code->status < NGX_HTTP_BAD_REQUEST
- || code->text.value.len
- || code->text.lengths)
- {
- e->status = ngx_http_send_response(e->request, code->status, NULL,
- &code->text);
- } else {
- e->status = code->status;
- }
- e->ip = ngx_http_script_exit;
- }
- void
- ngx_http_script_break_code(ngx_http_script_engine_t *e)
- {
- ngx_http_request_t *r;
- r = e->request;
- if (r->uri_changed) {
- r->valid_location = 0;
- r->uri_changed = 0;
- }
- e->ip = ngx_http_script_exit;
- }
- void
- ngx_http_script_if_code(ngx_http_script_engine_t *e)
- {
- ngx_http_script_if_code_t *code;
- code = (ngx_http_script_if_code_t *) e->ip;
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script if");
- e->sp--;
- if (e->sp->len && (e->sp->len != 1 || e->sp->data[0] != '0')) {
- if (code->loc_conf) {
- e->request->loc_conf = code->loc_conf;
- ngx_http_update_location_config(e->request);
- }
- e->ip += sizeof(ngx_http_script_if_code_t);
- return;
- }
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script if: false");
- e->ip += code->next;
- }
- void
- ngx_http_script_equal_code(ngx_http_script_engine_t *e)
- {
- ngx_http_variable_value_t *val, *res;
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script equal");
- e->sp--;
- val = e->sp;
- res = e->sp - 1;
- e->ip += sizeof(uintptr_t);
- if (val->len == res->len
- && ngx_strncmp(val->data, res->data, res->len) == 0)
- {
- *res = ngx_http_variable_true_value;
- return;
- }
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script equal: no");
- *res = ngx_http_variable_null_value;
- }
- void
- ngx_http_script_not_equal_code(ngx_http_script_engine_t *e)
- {
- ngx_http_variable_value_t *val, *res;
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script not equal");
- e->sp--;
- val = e->sp;
- res = e->sp - 1;
- e->ip += sizeof(uintptr_t);
- if (val->len == res->len
- && ngx_strncmp(val->data, res->data, res->len) == 0)
- {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script not equal: no");
- *res = ngx_http_variable_null_value;
- return;
- }
- *res = ngx_http_variable_true_value;
- }
- void
- ngx_http_script_file_code(ngx_http_script_engine_t *e)
- {
- ngx_str_t path;
- ngx_http_request_t *r;
- ngx_open_file_info_t of;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_variable_value_t *value;
- ngx_http_script_file_code_t *code;
- value = e->sp - 1;
- code = (ngx_http_script_file_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_file_code_t);
- path.len = value->len - 1;
- path.data = value->data;
- r = e->request;
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http script file op %p \"%V\"", (void *) code->op, &path);
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
- of.read_ahead = clcf->read_ahead;
- of.directio = clcf->directio;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.test_only = 1;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- if (of.err == 0) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- if (of.err != NGX_ENOENT
- && of.err != NGX_ENOTDIR
- && of.err != NGX_ENAMETOOLONG)
- {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
- "%s \"%s\" failed", of.failed, value->data);
- }
- switch (code->op) {
- case ngx_http_script_file_plain:
- case ngx_http_script_file_dir:
- case ngx_http_script_file_exists:
- case ngx_http_script_file_exec:
- goto false_value;
- case ngx_http_script_file_not_plain:
- case ngx_http_script_file_not_dir:
- case ngx_http_script_file_not_exists:
- case ngx_http_script_file_not_exec:
- goto true_value;
- }
- goto false_value;
- }
- switch (code->op) {
- case ngx_http_script_file_plain:
- if (of.is_file) {
- goto true_value;
- }
- goto false_value;
- case ngx_http_script_file_not_plain:
- if (of.is_file) {
- goto false_value;
- }
- goto true_value;
- case ngx_http_script_file_dir:
- if (of.is_dir) {
- goto true_value;
- }
- goto false_value;
- case ngx_http_script_file_not_dir:
- if (of.is_dir) {
- goto false_value;
- }
- goto true_value;
- case ngx_http_script_file_exists:
- if (of.is_file || of.is_dir || of.is_link) {
- goto true_value;
- }
- goto false_value;
- case ngx_http_script_file_not_exists:
- if (of.is_file || of.is_dir || of.is_link) {
- goto false_value;
- }
- goto true_value;
- case ngx_http_script_file_exec:
- if (of.is_exec) {
- goto true_value;
- }
- goto false_value;
- case ngx_http_script_file_not_exec:
- if (of.is_exec) {
- goto false_value;
- }
- goto true_value;
- }
- false_value:
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http script file op false");
- *value = ngx_http_variable_null_value;
- return;
- true_value:
- *value = ngx_http_variable_true_value;
- return;
- }
- void
- ngx_http_script_complex_value_code(ngx_http_script_engine_t *e)
- {
- size_t len;
- ngx_http_script_engine_t le;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_complex_value_code_t *code;
- code = (ngx_http_script_complex_value_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_complex_value_code_t);
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script complex value");
- ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
- le.ip = code->lengths->elts;
- le.line = e->line;
- le.request = e->request;
- le.quote = e->quote;
- for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
- e->buf.len = len;
- e->buf.data = ngx_pnalloc(e->request->pool, len);
- if (e->buf.data == NULL) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- e->pos = e->buf.data;
- e->sp->len = e->buf.len;
- e->sp->data = e->buf.data;
- e->sp++;
- }
- void
- ngx_http_script_value_code(ngx_http_script_engine_t *e)
- {
- ngx_http_script_value_code_t *code;
- code = (ngx_http_script_value_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_value_code_t);
- e->sp->len = code->text_len;
- e->sp->data = (u_char *) code->text_data;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script value: \"%v\"", e->sp);
- e->sp++;
- }
- void
- ngx_http_script_set_var_code(ngx_http_script_engine_t *e)
- {
- ngx_http_request_t *r;
- ngx_http_script_var_code_t *code;
- code = (ngx_http_script_var_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_var_code_t);
- r = e->request;
- e->sp--;
- r->variables[code->index].len = e->sp->len;
- r->variables[code->index].valid = 1;
- r->variables[code->index].no_cacheable = 0;
- r->variables[code->index].not_found = 0;
- r->variables[code->index].data = e->sp->data;
- #if (NGX_DEBUG)
- {
- ngx_http_variable_t *v;
- ngx_http_core_main_conf_t *cmcf;
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
- v = cmcf->variables.elts;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script set $%V", &v[code->index].name);
- }
- #endif
- }
- void
- ngx_http_script_var_set_handler_code(ngx_http_script_engine_t *e)
- {
- ngx_http_script_var_handler_code_t *code;
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script set var handler");
- code = (ngx_http_script_var_handler_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_var_handler_code_t);
- e->sp--;
- code->handler(e->request, e->sp, code->data);
- }
- void
- ngx_http_script_var_code(ngx_http_script_engine_t *e)
- {
- ngx_http_variable_value_t *value;
- ngx_http_script_var_code_t *code;
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script var");
- code = (ngx_http_script_var_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_var_code_t);
- value = ngx_http_get_flushed_variable(e->request, code->index);
- if (value && !value->not_found) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script var: \"%v\"", value);
- *e->sp = *value;
- e->sp++;
- return;
- }
- *e->sp = ngx_http_variable_null_value;
- e->sp++;
- }
- void
- ngx_http_script_nop_code(ngx_http_script_engine_t *e)
- {
- e->ip += sizeof(uintptr_t);
- }
|