static void ngx_http_lua_timer_handler(ngx_event_t *ev) { int n; lua_State *L; ngx_int_t rc; ngx_connection_t *c = NULL; ngx_http_request_t *r = NULL; ngx_http_lua_ctx_t *ctx; ngx_http_cleanup_t *cln; ngx_pool_cleanup_t *pcln; ngx_http_lua_timer_ctx_t tctx; ngx_http_lua_main_conf_t *lmcf; ngx_http_core_loc_conf_t *clcf; ngx_http_lua_timer_log_ctx_t *logctx; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua ngx.timer expired"); ngx_memcpy(&tctx, ev->data, sizeof(ngx_http_lua_timer_ctx_t)); ngx_free(ev); ev = NULL; lmcf = tctx.lmcf; lmcf->pending_timers--; if (lmcf->running_timers >= lmcf->max_running_timers) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "%i lua_max_running_timers are not enough", lmcf->max_running_timers); goto failed; } c = ngx_http_lua_create_fake_connection(tctx.pool); if (c == NULL) { goto failed; } logctx = ngx_palloc(c->pool, sizeof(ngx_http_lua_timer_log_ctx_t)); if (logctx == NULL) { goto failed; } logctx->connection = c; c->log->handler = ngx_http_lua_log_timer_error; c->log->data = logctx; c->listening = tctx.listening; c->addr_text = tctx.client_addr_text; r = ngx_http_lua_create_fake_request(c); if (r == NULL) { goto failed; } r->main_conf = tctx.main_conf; r->srv_conf = tctx.srv_conf; r->loc_conf = tctx.loc_conf; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); #if defined(nginx_version) && nginx_version >= 1003014 ngx_http_set_connection_log(r->connection, clcf->error_log); #else c->log->file = clcf->error_log->file; if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { c->log->log_level = clcf->error_log->log_level; } #endif dd("lmcf: %p", lmcf); ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { goto failed; } if (tctx.vm_state) { ctx->vm_state = tctx.vm_state; pcln = ngx_pool_cleanup_add(r->pool, 0); if (pcln == NULL) { goto failed; } pcln->handler = ngx_http_lua_cleanup_vm; pcln->data = tctx.vm_state; } ctx->cur_co_ctx = &ctx->entry_co_ctx; L = ngx_http_lua_get_lua_vm(r, ctx); cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { goto failed; } cln->handler = ngx_http_lua_request_cleanup_handler; cln->data = ctx; ctx->cleanup = &cln->handler; ctx->entered_content_phase = 1; ctx->context = NGX_HTTP_LUA_CONTEXT_TIMER; r->read_event_handler = ngx_http_block_reading; ctx->cur_co_ctx->co_ref = tctx.co_ref; ctx->cur_co_ctx->co = tctx.co; ctx->cur_co_ctx->co_status = NGX_HTTP_LUA_CO_RUNNING; dd("r connection: %p, log %p", r->connection, r->connection->log); /* save the request in coroutine globals table */ ngx_http_lua_set_req(tctx.co, r); lmcf->running_timers++; lua_pushboolean(tctx.co, tctx.premature); n = lua_gettop(tctx.co); if (n > 2) { lua_insert(tctx.co, 2); } #ifdef NGX_LUA_USE_ASSERT ctx->cur_co_ctx->co_top = 1; #endif rc = ngx_http_lua_run_thread(L, r, ctx, n - 1); dd("timer lua run thread: %d", (int) rc); if (rc == NGX_ERROR || rc >= NGX_OK) { /* do nothing */ } else if (rc == NGX_AGAIN) { rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 0); } else if (rc == NGX_DONE) { rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 1); } else { rc = NGX_OK; } ngx_http_lua_finalize_request(r, rc); return; failed: if (tctx.co_ref && tctx.co) { lua_pushlightuserdata(tctx.co, &ngx_http_lua_coroutines_key); lua_rawget(tctx.co, LUA_REGISTRYINDEX); luaL_unref(tctx.co, -1, tctx.co_ref); lua_settop(tctx.co, 0); } if (tctx.vm_state) { ngx_http_lua_cleanup_vm(tctx.vm_state); } if (c) { ngx_http_lua_close_fake_connection(c); } else if (tctx.pool) { ngx_destroy_pool(tctx.pool); } }
static void ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_connection_t *c; ngx_http_upstream_resolved_t *ur; ngx_http_lua_ctx_t *lctx; lua_State *L; ngx_http_lua_socket_udp_upstream_t *u; u_char *p; size_t len; #if defined(nginx_version) && nginx_version >= 1005008 socklen_t socklen; struct sockaddr *sockaddr; #else struct sockaddr_in *sin; #endif ngx_uint_t i; unsigned waiting; u = ctx->data; r = u->request; c = r->connection; ur = u->resolved; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolve handler"); lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (lctx == NULL) { return; } lctx->cur_co_ctx = u->co_ctx; u->co_ctx->cleanup = NULL; L = lctx->cur_co_ctx->co; dd("setting socket_ready to 1"); waiting = u->waiting; if (ctx->state) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua udp socket resolver error: %s (waiting: %d)", ngx_resolver_strerror(ctx->state), (int) u->waiting); lua_pushnil(L); lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len); lua_pushfstring(L, " could not be resolved (%d: %s)", (int) ctx->state, ngx_resolver_strerror(ctx->state)); lua_concat(L, 2); #if 1 ngx_resolve_name_done(ctx); ur->ctx = NULL; #endif u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_RESOLVER); if (waiting) { ngx_http_run_posted_requests(c); } return; } ur->naddrs = ctx->naddrs; ur->addrs = ctx->addrs; #if (NGX_DEBUG) { # if defined(nginx_version) && nginx_version >= 1005008 u_char text[NGX_SOCKADDR_STRLEN]; ngx_str_t addr; # else in_addr_t addr; # endif ngx_uint_t i; # if defined(nginx_version) && nginx_version >= 1005008 addr.data = text; for (i = 0; i < ctx->naddrs; i++) { addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen, text, NGX_SOCKADDR_STRLEN, 0); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "name was resolved to %V", &addr); } # else for (i = 0; i < ctx->naddrs; i++) { dd("addr i: %d %p", (int) i, &ctx->addrs[i]); addr = ntohl(ctx->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } # endif } #endif ngx_http_lua_assert(ur->naddrs > 0); if (ur->naddrs == 1) { i = 0; } else { i = ngx_random() % ur->naddrs; } dd("selected addr index: %d", (int) i); #if defined(nginx_version) && nginx_version >= 1005008 socklen = ur->addrs[i].socklen; sockaddr = ngx_palloc(r->pool, socklen); if (sockaddr == NULL) { goto nomem; } ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen); switch (sockaddr->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port); break; #endif default: /* AF_INET */ ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port); } p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN); if (p == NULL) { goto nomem; } len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); ur->sockaddr = sockaddr; ur->socklen = socklen; #else /* for nginx older than 1.5.8 */ len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in)); if (p == NULL) { goto nomem; } sin = (struct sockaddr_in *) &p[len]; ngx_memzero(sin, sizeof(struct sockaddr_in)); len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", ur->port) - p; sin->sin_family = AF_INET; sin->sin_port = htons(ur->port); sin->sin_addr.s_addr = ur->addrs[i]; ur->sockaddr = (struct sockaddr *) sin; ur->socklen = sizeof(struct sockaddr_in); #endif ur->host.data = p; ur->host.len = len; ur->naddrs = 1; ngx_resolve_name_done(ctx); ur->ctx = NULL; u->waiting = 0; if (waiting) { lctx->resume_handler = ngx_http_lua_socket_udp_resume; r->write_event_handler(r); ngx_http_run_posted_requests(c); } else { (void) ngx_http_lua_socket_resolve_retval_handler(r, u, L); } return; nomem: if (ur->ctx) { ngx_resolve_name_done(ctx); ur->ctx = NULL; } u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_NOMEM); if (waiting) { ngx_http_run_posted_requests(c); } else { lua_pushnil(L); lua_pushliteral(L, "no memory"); } }
static int ngx_http_lua_socket_udp_receive(lua_State *L) { ngx_http_request_t *r; ngx_http_lua_socket_udp_upstream_t *u; ngx_int_t rc; ngx_http_lua_ctx_t *ctx; ngx_http_lua_co_ctx_t *coctx; size_t size; int nargs; ngx_http_lua_loc_conf_t *llcf; nargs = lua_gettop(L); if (nargs != 1 && nargs != 2) { return luaL_error(L, "expecting 1 or 2 arguments " "(including the object), but got %d", nargs); } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request found"); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket calling receive() method"); luaL_checktype(L, 1, LUA_TTABLE); lua_rawgeti(L, 1, SOCKET_CTX_INDEX); u = lua_touserdata(L, -1); lua_pop(L, 1); if (u == NULL || u->udp_connection.connection == NULL) { llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (llcf->log_socket_errors) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "attempt to receive data on a closed socket: u:%p, " "c:%p", u, u ? u->udp_connection.connection : NULL); } lua_pushnil(L); lua_pushliteral(L, "closed"); return 2; } if (u->request != r) { return luaL_error(L, "bad request"); } if (u->ft_type) { u->ft_type = 0; } #if 1 if (u->waiting) { lua_pushnil(L); lua_pushliteral(L, "socket busy"); return 2; } #endif ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket read timeout: %M", u->read_timeout); size = (size_t) luaL_optnumber(L, 2, UDP_MAX_DATAGRAM_SIZE); size = ngx_min(size, UDP_MAX_DATAGRAM_SIZE); u->recv_buf_size = size; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket receive buffer size: %uz", u->recv_buf_size); rc = ngx_http_lua_socket_udp_read(r, u); if (rc == NGX_ERROR) { dd("read failed: %d", (int) u->ft_type); rc = ngx_http_lua_socket_udp_receive_retval_handler(r, u, L); dd("udp receive retval returned: %d", (int) rc); return rc; } if (rc == NGX_OK) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket receive done in a single run"); return ngx_http_lua_socket_udp_receive_retval_handler(r, u, L); } /* n == NGX_AGAIN */ u->read_event_handler = ngx_http_lua_socket_udp_read_handler; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no request ctx found"); } coctx = ctx->cur_co_ctx; ngx_http_lua_cleanup_pending_operation(coctx); coctx->cleanup = ngx_http_lua_udp_socket_cleanup; coctx->data = u; if (ctx->entered_content_phase) { r->write_event_handler = ngx_http_lua_content_wev_handler; } else { r->write_event_handler = ngx_http_core_run_phases; } u->co_ctx = coctx; u->waiting = 1; u->prepare_retvals = ngx_http_lua_socket_udp_receive_retval_handler; return lua_yield(L, 0); }
static int ngx_http_lua_ngx_req_set_body_file(lua_State *L) { u_char *p; ngx_http_request_t *r; int n; ngx_http_request_body_t *rb; ngx_temp_file_t *tf; ngx_buf_t *b; ngx_str_t name; ngx_int_t rc; int clean; ngx_open_file_info_t of; ngx_str_t key, value; ngx_pool_cleanup_t *cln; ngx_pool_cleanup_file_t *clnf; ngx_err_t err; ngx_chain_t *cl; ngx_buf_tag_t tag; n = lua_gettop(L); if (n != 1 && n != 2) { return luaL_error(L, "expecting 1 or 2 arguments but seen %d", n); } p = (u_char *) luaL_checklstring(L, 1, &name.len); lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "request object not found"); } if (r->discard_body) { return luaL_error(L, "request body already discarded asynchronously"); } if (r->request_body == NULL) { return luaL_error(L, "request body not read yet"); } name.data = ngx_palloc(r->pool, name.len + 1); if (name.data == NULL) { return luaL_error(L, "out of memory"); } ngx_memcpy(name.data, p, name.len); name.data[name.len] = '\0'; if (n == 2) { luaL_checktype(L, 2, LUA_TBOOLEAN); clean = lua_toboolean(L, 2); } else { clean = 0; } dd("clean: %d", (int) clean); rb = r->request_body; /* clean up existing r->request_body->bufs (if any) */ tag = (ngx_buf_tag_t) &ngx_http_lua_module; if (rb->bufs) { dd("XXX reusing buf"); for (cl = rb->bufs; cl; cl = cl->next) { if (cl->buf->tag == tag && cl->buf->temporary) { dd("free old request body buffer: size:%d", (int) ngx_buf_size(cl->buf)); ngx_pfree(r->pool, cl->buf->start); cl->buf->tag = (ngx_buf_tag_t) NULL; cl->buf->temporary = 0; } } rb->bufs->next = NULL; b = rb->bufs->buf; ngx_memzero(b, sizeof(ngx_buf_t)); b->tag = tag; } else { dd("XXX creating new buf"); rb->bufs = ngx_alloc_chain_link(r->pool); if (rb->bufs == NULL) { return luaL_error(L, "out of memory"); } rb->bufs->next = NULL; b = ngx_calloc_buf(r->pool); if (b == NULL) { return luaL_error(L, "out of memory"); } b->tag = tag; rb->bufs->buf = b; rb->buf = b; } b->last_in_chain = 1; /* just make r->request_body->temp_file a bare stub */ tf = rb->temp_file; if (tf) { if (tf->file.fd != NGX_INVALID_FILE) { dd("cleaning temp file %.*s", (int) tf->file.name.len, tf->file.name.data); ngx_http_lua_pool_cleanup_file(r->pool, tf->file.fd); ngx_memzero(tf, sizeof(ngx_temp_file_t)); tf->file.fd = NGX_INVALID_FILE; dd("temp file cleaned: %.*s", (int) tf->file.name.len, tf->file.name.data); } } else { tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)); if (tf == NULL) { return luaL_error(L, "out of memory"); } tf->file.fd = NGX_INVALID_FILE; rb->temp_file = tf; } /* read the file info and construct an in-file buf */ ngx_memzero(&of, sizeof(ngx_open_file_info_t)); if (ngx_http_lua_open_and_stat_file(name.data, &of, r->connection->log) != NGX_OK) { return luaL_error(L, "%s \"%s\" failed", of.failed, name.data); } dd("XXX new body file fd: %d", of.fd); tf->file.fd = of.fd; tf->file.name = name; tf->file.log = r->connection->log; /* FIXME we should not always set directio here */ tf->file.directio = 1; if (of.size == 0) { if (clean) { if (ngx_delete_file(name.data) == NGX_FILE_ERROR) { err = ngx_errno; if (err != NGX_ENOENT) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, err, ngx_delete_file_n " \"%s\" failed", name.data); } } } if (ngx_close_file(of.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, ngx_close_file_n " \"%s\" failed", name.data); } r->request_body->bufs = NULL; r->request_body->buf = NULL; goto set_header; } /* register file cleanup hook */ cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t)); if (cln == NULL) { return luaL_error(L, "out of memory"); } cln->handler = clean ? ngx_pool_delete_file : ngx_pool_cleanup_file; clnf = cln->data; clnf->fd = of.fd; clnf->name = name.data; clnf->log = r->pool->log; b->file = &tf->file; if (b->file == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } dd("XXX file size: %d", (int) of.size); b->file_pos = 0; b->file_last = of.size; b->in_file = 1; dd("buf file: %p, f:%u", b->file, b->in_file); set_header: /* override input header Content-Length (value must be null terminated) */ value.data = ngx_palloc(r->pool, NGX_OFF_T_LEN + 1); if (value.data == NULL) { return luaL_error(L, "out of memory"); } value.len = ngx_sprintf(value.data, "%O", of.size) - value.data; value.data[value.len] = '\0'; r->headers_in.content_length_n = of.size; if (r->headers_in.content_length) { r->headers_in.content_length->value.data = value.data; r->headers_in.content_length->value.len = value.len; } else { ngx_str_set(&key, "Content-Length"); rc = ngx_http_lua_set_input_header(r, key, value, 1 /* override */); if (rc != NGX_OK) { return luaL_error(L, "failed to reset the Content-Length " "input header"); } } return 0; }
/// Do one iteration. bool LevenbergMarquardtMDMinimizer::iterate() { const bool debug = getProperty("Debug"); const double muMax = getProperty("MuMax"); const double absError = getProperty("AbsError"); if ( !m_leastSquares ) { throw std::runtime_error("Cost function isn't set up."); } size_t n = m_leastSquares->nParams(); if ( n == 0 ) { m_errorString = "No parameters to fit."; g_log.warning() << m_errorString << std::endl; return false; } if ( m_mu > muMax ) { //m_errorString = "Failed to converge, maximum mu reached"; //g_log.warning() << m_errorString << std::endl; return false; } // calculate the first and second derivatives of the cost function. if (m_mu == 0.0) {// first time calculate everything m_F = m_leastSquares->valDerivHessian(); } else if (m_rho > 0) {// last iteration was good: calculate new m_der and m_hessian, dont't recalculate m_F m_leastSquares->valDerivHessian(false); } // else if m_rho < 0 last iteration was bad: reuse m_der and m_hessian // Calculate damping to hessian if (m_mu == 0) // first iteration or accidental zero { m_mu = m_tau; m_nu = 2.0; } if (debug) { g_log.warning() << "===========================================================" << std::endl; g_log.warning() << "mu=" << m_mu << std::endl << std::endl; } if (m_D.empty()) { m_D.resize(n); } // copy the hessian GSLMatrix H( m_leastSquares->getHessian() ); GSLVector dd( m_leastSquares->getDeriv() ); // scaling factors std::vector<double> sf(n); for(size_t i = 0; i < n; ++i) { double d = fabs(dd.get(i)); if (m_D[i] > d) d = m_D[i]; m_D[i] = d; double tmp = H.get(i,i) + m_mu * d; H.set(i,i,tmp); sf[i] = sqrt( tmp ); if ( tmp == 0.0 ) { m_errorString = "Singular matrix."; g_log.warning() << m_errorString << std::endl; return false; } } // apply scaling for(size_t i = 0; i < n; ++i) { double d = dd.get(i); dd.set( i, d / sf[i] ); for(size_t j = i; j < n; ++j) { const double f = sf[i] * sf[j]; double tmp = H.get(i,j); H.set(i,j,tmp/f); if ( i != j ) { tmp = H.get(j,i); H.set(j,i,tmp/f); } } } if (debug && m_rho > 0) { g_log.warning() << "Hessian:\n" << H ; g_log.warning() << "Right-hand side:\n"; for(size_t j = 0; j < n; ++j) {g_log.warning() << dd.get(j) << ' '; } g_log.warning() << std::endl; g_log.warning() << "Determinant=" << H.det() << std::endl; } // Parameter corrections GSLVector dx(n); // To find dx solve the system of linear equations H * dx == -m_der dd *= -1.0; H.solve( dd, dx ); if (debug) { g_log.warning() << "\nScaling factors:" << std::endl; for(size_t j = 0; j < n; ++j) {g_log.warning() << sf[j] << ' '; } g_log.warning() << std::endl; g_log.warning() << "Corrections:" << std::endl; for(size_t j = 0; j < n; ++j) {g_log.warning() << dx.get(j) << ' '; } g_log.warning() << std::endl << std::endl; } // restore scaling for(size_t i = 0; i < n; ++i) { double d = dx.get(i); dx.set( i, d / sf[i] ); d = dd.get(i); dd.set( i, d * sf[i] ); } // save previous state m_leastSquares->push(); // Update the parameters of the cost function. for(size_t i = 0; i < n; ++i) { double d = m_leastSquares->getParameter(i) + dx.get(i); m_leastSquares->setParameter(i,d); if (debug) { g_log.warning() << "Parameter(" << i << ")=" << d << std::endl; } } m_leastSquares->getFittingFunction()->applyTies(); // --- prepare for the next iteration --- // double dL; // der -> - der - 0.5 * hessian * dx gsl_blas_dgemv( CblasNoTrans,-0.5, m_leastSquares->getHessian().gsl(), dx.gsl(), 1., dd.gsl() ); // calculate the linear part of the change in cost function // dL = - der * dx - 0.5 * dx * hessian * dx gsl_blas_ddot( dd.gsl(), dx.gsl(), &dL ); double F1 = m_leastSquares->val(); if (debug) { g_log.warning() << std::endl; g_log.warning() << "Old cost function " << m_F << std::endl; g_log.warning() << "New cost function " << F1 << std::endl; g_log.warning() << "Linear part " << dL << std::endl; } // Try the stop condition if (m_rho >= 0) { GSLVector p(n); m_leastSquares->getParameters(p); double dx_norm = gsl_blas_dnrm2(dx.gsl()); if (dx_norm < absError) { if (debug) { g_log.warning() << "Successful fit, parameters changed by less than " << absError << std::endl; } return false; } if (m_rho == 0) { if ( m_F != F1 ) { this->m_errorString = "Failed to converge, rho == 0"; g_log.warning() << m_errorString << std::endl; } if (debug) { g_log.warning() << "Successful fit, cost function didn't change." << std::endl; } return false; } } if (fabs(dL) == 0.0) { if ( m_F == F1 ) m_rho = 1.0; else m_rho = 0; } else { m_rho = (m_F - F1) / dL; if ( m_rho == 0 ) { return false; } } if (debug) { g_log.warning() << "rho=" << m_rho << std::endl; } if (m_rho > 0) {// good progress, decrease m_mu but no more than by 1/3 // rho = 1 - (2*rho - 1)^3 m_rho = 2.0 * m_rho - 1.0; m_rho = 1.0 - m_rho * m_rho * m_rho; const double I3 = 1.0 / 3.0; if (m_rho > I3) m_rho = I3; if (m_rho < 0.0001) m_rho = 0.1; m_mu *= m_rho; m_nu = 2.0; m_F = F1; if (debug) { g_log.warning() << "Good iteration, accept new parameters." << std::endl; g_log.warning() << "rho=" << m_rho << std::endl; } // drop saved state, accept new parameters m_leastSquares->drop(); } else {// bad iteration. increase m_mu and revert changes to parameters m_mu *= m_nu; m_nu *= 2.0; // undo parameter update m_leastSquares->pop(); m_F = m_leastSquares->val(); if (debug) { g_log.warning() << "Bad iteration, increase mu and revert changes to parameters." << std::endl; } } return true; }
static int ngx_http_lua_ngx_req_set_body_data(lua_State *L) { ngx_http_request_t *r; int n; ngx_http_request_body_t *rb; ngx_temp_file_t *tf; ngx_buf_t *b; ngx_str_t body, key, value; #if 1 ngx_int_t rc; #endif ngx_chain_t *cl; ngx_buf_tag_t tag; n = lua_gettop(L); if (n != 1) { return luaL_error(L, "expecting 1 arguments but seen %d", n); } body.data = (u_char *) luaL_checklstring(L, 1, &body.len); lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "request object not found"); } if (r->discard_body) { return luaL_error(L, "request body already discarded asynchronously"); } if (r->request_body == NULL) { return luaL_error(L, "request body not read yet"); } rb = r->request_body; tag = (ngx_buf_tag_t) &ngx_http_lua_module; tf = rb->temp_file; if (tf) { if (tf->file.fd != NGX_INVALID_FILE) { dd("cleaning temp file %.*s", (int) tf->file.name.len, tf->file.name.data); ngx_http_lua_pool_cleanup_file(r->pool, tf->file.fd); tf->file.fd = NGX_INVALID_FILE; dd("temp file cleaned: %.*s", (int) tf->file.name.len, tf->file.name.data); } rb->temp_file = NULL; } if (body.len == 0) { if (rb->bufs) { for (cl = rb->bufs; cl; cl = cl->next) { if (cl->buf->tag == tag && cl->buf->temporary) { dd("free old request body buffer: size:%d", (int) ngx_buf_size(cl->buf)); ngx_pfree(r->pool, cl->buf->start); cl->buf->tag = (ngx_buf_tag_t) NULL; cl->buf->temporary = 0; } } } rb->bufs = NULL; rb->buf = NULL; dd("request body is set to empty string"); goto set_header; } if (rb->bufs) { for (cl = rb->bufs; cl; cl = cl->next) { if (cl->buf->tag == tag && cl->buf->temporary) { dd("free old request body buffer: size:%d", (int) ngx_buf_size(cl->buf)); ngx_pfree(r->pool, cl->buf->start); cl->buf->tag = (ngx_buf_tag_t) NULL; cl->buf->temporary = 0; } } rb->bufs->next = NULL; b = rb->bufs->buf; ngx_memzero(b, sizeof(ngx_buf_t)); b->temporary = 1; b->tag = tag; b->start = ngx_palloc(r->pool, body.len); if (b->start == NULL) { return luaL_error(L, "out of memory"); } b->end = b->start + body.len; b->pos = b->start; b->last = ngx_copy(b->pos, body.data, body.len); } else { rb->bufs = ngx_alloc_chain_link(r->pool); if (rb->bufs == NULL) { return luaL_error(L, "out of memory"); } rb->bufs->next = NULL; b = ngx_create_temp_buf(r->pool, body.len); b->tag = tag; b->last = ngx_copy(b->pos, body.data, body.len); rb->bufs->buf = b; rb->buf = b; } set_header: /* override input header Content-Length (value must be null terminated) */ value.data = ngx_palloc(r->pool, NGX_SIZE_T_LEN + 1); if (value.data == NULL) { return luaL_error(L, "out of memory"); } value.len = ngx_sprintf(value.data, "%uz", body.len) - value.data; value.data[value.len] = '\0'; dd("setting request Content-Length to %.*s (%d)", (int) value.len, value.data, (int) body.len); r->headers_in.content_length_n = body.len; if (r->headers_in.content_length) { r->headers_in.content_length->value.data = value.data; r->headers_in.content_length->value.len = value.len; } else { ngx_str_set(&key, "Content-Length"); rc = ngx_http_lua_set_input_header(r, key, value, 1 /* override */); if (rc != NGX_OK) { return luaL_error(L, "failed to reset the Content-Length " "input header"); } } return 0; }
static int ngx_http_lua_ngx_req_read_body(lua_State *L) { ngx_http_request_t *r; int n; ngx_int_t rc; ngx_http_lua_ctx_t *ctx; ngx_http_lua_co_ctx_t *coctx; n = lua_gettop(L); if (n != 0) { return luaL_error(L, "expecting 0 arguments but seen %d", n); } lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "request object not found"); } r->request_body_in_single_buf = 1; r->request_body_in_persistent_file = 1; r->request_body_in_clean_file = 1; #if 1 if (r->request_body_in_file_only) { r->request_body_file_log_level = 0; } #endif ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no ctx found"); } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); coctx = ctx->cur_co_ctx; if (coctx == NULL) { return luaL_error(L, "no co ctx found"); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua start to read buffered request body"); rc = ngx_http_read_client_request_body(r, ngx_http_lua_req_body_post_read); #if (nginx_version < 1002006) || \ (nginx_version >= 1003000 && nginx_version < 1003009) r->main->count--; #endif if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { ctx->exit_code = rc; ctx->exited = 1; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http read client request body returned error code %i, " "exitting now", rc); return lua_yield(L, 0); } #if (nginx_version >= 1002006 && nginx_version < 1003000) || \ nginx_version >= 1003009 r->main->count--; dd("decrement r->main->count: %d", (int) r->main->count); #endif if (rc == NGX_AGAIN) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua read buffered request body requires I/O " "interruptions"); ctx->waiting_more_body = 1; ctx->req_body_reader_co_ctx = coctx; coctx->cleanup = ngx_http_lua_req_body_cleanup; coctx->data = r; return lua_yield(L, 0); } /* rc == NGX_OK */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua has read buffered request body in a single run"); return 0; }
uint32 urandweighted(size_t count, double const* chances) { std::discrete_distribution<uint32> dd(chances, chances + count); return dd(SFMTEngine::Instance()); }
static int ngx_http_lua_ngx_location_capture_multi(lua_State *L) { ngx_http_request_t *r; ngx_http_request_t *sr; /* subrequest object */ ngx_http_post_subrequest_t *psr; ngx_http_lua_ctx_t *sr_ctx; ngx_http_lua_ctx_t *ctx; ngx_array_t *extra_vars; ngx_str_t uri; ngx_str_t args; ngx_str_t extra_args; ngx_uint_t flags; u_char *p; u_char *q; size_t len; size_t nargs; int rc; int n; ngx_uint_t method; ngx_http_request_body_t *body; int type; ngx_buf_t *b; unsigned vars_action; ngx_uint_t nsubreqs; ngx_uint_t index; size_t sr_statuses_len; size_t sr_headers_len; size_t sr_bodies_len; unsigned custom_ctx; ngx_http_lua_co_ctx_t *coctx; ngx_http_lua_post_subrequest_data_t *psr_data; n = lua_gettop(L); if (n != 1) { return luaL_error(L, "only one argument is expected, but got %d", n); } luaL_checktype(L, 1, LUA_TTABLE); nsubreqs = lua_objlen(L, 1); if (nsubreqs == 0) { return luaL_error(L, "at least one subrequest should be specified"); } lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "no request object found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no ctx found"); } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); coctx = ctx->cur_co_ctx; if (coctx == NULL) { return luaL_error(L, "no co ctx found"); } sr_statuses_len = nsubreqs * sizeof(ngx_int_t); sr_headers_len = nsubreqs * sizeof(ngx_http_headers_out_t *); sr_bodies_len = nsubreqs * sizeof(ngx_str_t); p = ngx_pcalloc(r->pool, sr_statuses_len + sr_headers_len + sr_bodies_len); if (p == NULL) { return luaL_error(L, "out of memory"); } coctx->sr_statuses = (void *) p; p += sr_statuses_len; coctx->sr_headers = (void *) p; p += sr_headers_len; coctx->sr_bodies = (void *) p; coctx->nsubreqs = nsubreqs; coctx->done = 0; coctx->waiting = 0; extra_vars = NULL; for (index = 0; index < nsubreqs; index++) { coctx->waiting++; lua_rawgeti(L, 1, index + 1); if (lua_isnil(L, -1)) { return luaL_error(L, "only array-like tables are allowed"); } dd("queries query: top %d", lua_gettop(L)); if (lua_type(L, -1) != LUA_TTABLE) { return luaL_error(L, "the query argument %d is not a table, " "but a %s", index, lua_typename(L, lua_type(L, -1))); } nargs = lua_objlen(L, -1); if (nargs != 1 && nargs != 2) { return luaL_error(L, "query argument %d expecting one or " "two arguments", index); } lua_rawgeti(L, 2, 1); /* queries query uri */ dd("queries query uri: %d", lua_gettop(L)); dd("first arg in first query: %s", lua_typename(L, lua_type(L, -1))); body = NULL; extra_args.data = NULL; extra_args.len = 0; if (extra_vars != NULL) { /* flush out existing elements in the array */ extra_vars->nelts = 0; } vars_action = 0; custom_ctx = 0; if (nargs == 2) { /* check out the options table */ lua_rawgeti(L, 2, 2); /* queries query uri opts */ dd("queries query uri opts: %d", lua_gettop(L)); if (lua_type(L, 4) != LUA_TTABLE) { return luaL_error(L, "expecting table as the 2nd argument for " "subrequest %d, but got %s", index, luaL_typename(L, 4)); } dd("queries query uri opts: %d", lua_gettop(L)); /* check the args option */ lua_getfield(L, 4, "args"); type = lua_type(L, -1); switch (type) { case LUA_TTABLE: ngx_http_lua_process_args_option(r, L, -1, &extra_args); break; case LUA_TNIL: /* do nothing */ break; case LUA_TNUMBER: case LUA_TSTRING: extra_args.data = (u_char *) lua_tolstring(L, -1, &len); extra_args.len = len; break; default: return luaL_error(L, "Bad args option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the vars option */ lua_getfield(L, 4, "vars"); switch (lua_type(L, -1)) { case LUA_TTABLE: ngx_http_lua_process_vars_option(r, L, -1, &extra_vars); dd("post process vars top: %d", lua_gettop(L)); break; case LUA_TNIL: /* do nothing */ break; default: return luaL_error(L, "Bad vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the share_all_vars option */ lua_getfield(L, 4, "share_all_vars"); switch (lua_type(L, -1)) { case LUA_TNIL: /* do nothing */ break; case LUA_TBOOLEAN: if (lua_toboolean(L, -1)) { vars_action |= NGX_HTTP_LUA_SHARE_ALL_VARS; } break; default: return luaL_error(L, "Bad share_all_vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the copy_all_vars option */ lua_getfield(L, 4, "copy_all_vars"); switch (lua_type(L, -1)) { case LUA_TNIL: /* do nothing */ break; case LUA_TBOOLEAN: if (lua_toboolean(L, -1)) { vars_action |= NGX_HTTP_LUA_COPY_ALL_VARS; } break; default: return luaL_error(L, "Bad copy_all_vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the "method" option */ lua_getfield(L, 4, "method"); type = lua_type(L, -1); if (type == LUA_TNIL) { method = NGX_HTTP_GET; } else { if (type != LUA_TNUMBER) { return luaL_error(L, "Bad http request method"); } method = (ngx_uint_t) lua_tonumber(L, -1); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the "ctx" option */ lua_getfield(L, 4, "ctx"); type = lua_type(L, -1); if (type != LUA_TNIL) { if (type != LUA_TTABLE) { return luaL_error(L, "Bad ctx option value type %s, " "expected a Lua table", lua_typename(L, type)); } custom_ctx = 1; } else { lua_pop(L, 1); } dd("queries query uri opts ctx?: %d", lua_gettop(L)); /* check the "body" option */ lua_getfield(L, 4, "body"); type = lua_type(L, -1); if (type != LUA_TNIL) { if (type != LUA_TSTRING && type != LUA_TNUMBER) { return luaL_error(L, "Bad http request body"); } body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); if (body == NULL) { return luaL_error(L, "out of memory"); } q = (u_char *) lua_tolstring(L, -1, &len); dd("request body: [%.*s]", (int) len, q); if (len) { b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { return luaL_error(L, "out of memory"); } b->last = ngx_copy(b->last, q, len); body->bufs = ngx_alloc_chain_link(r->pool); if (body->bufs == NULL) { return luaL_error(L, "out of memory"); } body->bufs->buf = b; body->bufs->next = NULL; body->buf = b; } } lua_pop(L, 1); /* pop the body */ /* stack: queries query uri opts ctx? */ lua_remove(L, 4); /* stack: queries query uri ctx? */ dd("queries query uri ctx?: %d", lua_gettop(L)); } else { method = NGX_HTTP_GET; } /* stack: queries query uri ctx? */ p = (u_char *) luaL_checklstring(L, 3, &len); uri.data = ngx_palloc(r->pool, len); if (uri.data == NULL) { return luaL_error(L, "memory allocation error"); } ngx_memcpy(uri.data, p, len); uri.len = len; args.data = NULL; args.len = 0; flags = 0; rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags); if (rc != NGX_OK) { dd("rc = %d", (int) rc); return luaL_error(L, "unsafe uri in argument #1: %s", p); } if (args.len == 0) { args = extra_args; } else if (extra_args.len) { /* concatenate the two parts of args together */ len = args.len + (sizeof("&") - 1) + extra_args.len; p = ngx_palloc(r->pool, len); if (p == NULL) { return luaL_error(L, "out of memory"); } q = ngx_copy(p, args.data, args.len); *q++ = '&'; ngx_memcpy(q, extra_args.data, extra_args.len); args.data = p; args.len = len; } p = ngx_pnalloc(r->pool, sizeof(ngx_http_post_subrequest_t) + sizeof(ngx_http_lua_ctx_t) + sizeof(ngx_http_lua_post_subrequest_data_t)); if (p == NULL) { return luaL_error(L, "out of memory"); } psr = (ngx_http_post_subrequest_t *) p; p += sizeof(ngx_http_post_subrequest_t); sr_ctx = (ngx_http_lua_ctx_t *) p; p += sizeof(ngx_http_lua_ctx_t); psr_data = (ngx_http_lua_post_subrequest_data_t *) p; ngx_memzero(sr_ctx, sizeof(ngx_http_lua_ctx_t)); /* set by ngx_memzero: * sr_ctx->run_post_subrequest = 0 * sr_ctx->free = NULL */ sr_ctx->entry_ref = LUA_NOREF; sr_ctx->ctx_ref = LUA_NOREF; sr_ctx->capture = 1; sr_ctx->index = index; psr_data->ctx = sr_ctx; psr_data->pr_co_ctx = coctx; psr->handler = ngx_http_lua_post_subrequest; psr->data = psr_data; rc = ngx_http_lua_subrequest(r, &uri, &args, &sr, psr, 0); if (rc != NGX_OK) { return luaL_error(L, "failed to issue subrequest: %d", (int) rc); } ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module); rc = ngx_http_lua_adjust_subrequest(sr, method, body, vars_action, extra_vars); if (rc != NGX_OK) { return luaL_error(L, "failed to adjust the subrequest: %d", (int) rc); } dd("queries query uri opts ctx? %d", lua_gettop(L)); /* stack: queries query uri ctx? */ if (custom_ctx) { ngx_http_lua_ngx_set_ctx_helper(L, sr, sr_ctx, -1); lua_pop(L, 3); } else { lua_pop(L, 2); } /* stack: queries */ } if (extra_vars) { ngx_array_destroy(extra_vars); } return lua_yield(L, 0); }
ngx_int_t ngx_http_lua_rewrite_handler(ngx_http_request_t *r) { ngx_http_lua_loc_conf_t *llcf; ngx_http_lua_ctx_t *ctx; ngx_int_t rc; ngx_http_lua_main_conf_t *lmcf; /* XXX we need to take into account ngx_rewrite's location dump */ if (r->uri_changed) { return NGX_DECLINED; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua rewrite handler, uri:\"%V\" c:%ud", &r->uri, r->main->count); lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); if (!lmcf->postponed_to_rewrite_phase_end) { ngx_http_core_main_conf_t *cmcf; ngx_http_phase_handler_t tmp; ngx_http_phase_handler_t *ph; ngx_http_phase_handler_t *cur_ph; ngx_http_phase_handler_t *last_ph; lmcf->postponed_to_rewrite_phase_end = 1; cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); ph = cmcf->phase_engine.handlers; cur_ph = &ph[r->phase_handler]; last_ph = &ph[cur_ph->next - 1]; #if 0 if (cur_ph == last_ph) { dd("XXX our handler is already the last rewrite phase handler"); } #endif if (cur_ph < last_ph) { dd("swaping the contents of cur_ph and last_ph..."); tmp = *cur_ph; memmove(cur_ph, cur_ph + 1, (last_ph - cur_ph) * sizeof (ngx_http_phase_handler_t)); *last_ph = tmp; r->phase_handler--; /* redo the current ph */ return NGX_DECLINED; } } llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (llcf->rewrite_handler == NULL) { dd("no rewrite handler found"); return NGX_DECLINED; } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); dd("ctx = %p", ctx); if (ctx == NULL) { ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } } dd("entered? %d", (int) ctx->entered_rewrite_phase); if (ctx->entered_rewrite_phase) { dd("rewriteby: calling wev handler"); rc = ctx->resume_handler(r); dd("rewriteby: wev handler returns %d", (int) rc); if (rc == NGX_OK) { rc = NGX_DECLINED; } if (rc == NGX_DECLINED) { if (r->header_sent) { dd("header already sent"); /* response header was already generated in access_by_lua*, * so it is no longer safe to proceed to later phases * which may generate responses again */ if (!ctx->eof) { dd("eof not yet sent"); rc = ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */); if (rc == NGX_ERROR || rc > NGX_OK) { return rc; } } return NGX_HTTP_OK; } } return rc; } if (ctx->waiting_more_body) { return NGX_DONE; } if (llcf->force_read_body && !ctx->read_body_done) { r->request_body_in_single_buf = 1; r->request_body_in_persistent_file = 1; r->request_body_in_clean_file = 1; rc = ngx_http_read_client_request_body(r, ngx_http_lua_generic_phase_post_read); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { #if (nginx_version < 1002006) || \ (nginx_version >= 1003000 && nginx_version < 1003009) r->main->count--; #endif return rc; } if (rc == NGX_AGAIN) { ctx->waiting_more_body = 1; return NGX_DONE; } } dd("calling rewrite handler"); return llcf->rewrite_handler(r); }
ngx_int_t ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { int buffer_fully_loadead = 0; ngx_chain_t *chain = in; ngx_http_modsecurity_ctx_t *ctx = NULL; #ifdef MODSECURITY_SANITY_CHECKS ngx_list_part_t *part = &r->headers_out.headers.part; ngx_table_elt_t *data = part->elts; ngx_uint_t i = 0; #endif if (in == NULL) { return ngx_http_next_body_filter(r, in); } ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity); dd("body filter, recovering ctx: %p", ctx); if (ctx == NULL) { return ngx_http_next_body_filter(r, in); } #ifdef MODSECURITY_SANITY_CHECKS #if 0 dd("dumping stored ctx headers"); for (i = 0; i < ctx->sanity_headers_out->nelts; i++) { ngx_http_modsecurity_header_t *vals = ctx->sanity_headers_out->elts; ngx_str_t *s2 = &vals[i].name, *s3 = &vals[i].value; dd(" dump[%d]: name = '%.*s', value = '%.*s'", (int)i, (int)s2->len, (char*)s2->data, (int)s3->len, (char*)s3->data); } #endif /* * Identify if there is a header that was not inspected by ModSecurity. */ int worth_to_fail = 0; for (i = 0; ; i++) { int found = 0; ngx_uint_t j = 0; ngx_table_elt_t *s1; ngx_http_modsecurity_header_t *vals; if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; data = part->elts; i = 0; } vals = ctx->sanity_headers_out->elts; s1 = &data[i]; /* * Headers that were inspected by ModSecurity. */ while (j < ctx->sanity_headers_out->nelts) { ngx_str_t *s2 = &vals[j].name; ngx_str_t *s3 = &vals[j].value; if (s1->key.len == s2->len && ngx_strncmp(s1->key.data, s2->data, s1->key.len) == 0) { if (s1->value.len == s3->len && ngx_strncmp(s1->value.data, s3->data, s1->value.len) == 0) { found = 1; break; } } j++; } if (!found) { dd("header: `%.*s' with value: `%.*s' was not inspected by ModSecurity", (int) s1->key.len, (const char *) s1->key.data, (int) s1->value.len, (const char *) s1->value.data); worth_to_fail++; } } if (worth_to_fail) { dd("%d header(s) were not inspected by ModSecurity, so exiting", worth_to_fail); return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); } #endif for (; chain != NULL; chain = chain->next) { /* XXX: chain->buf->last_buf || chain->buf->last_in_chain */ if (chain->buf->last_buf) { buffer_fully_loadead = 1; } } if (buffer_fully_loadead == 1) { int ret; for (chain = in; chain != NULL; chain = chain->next) { u_char *data = chain->buf->start; msc_append_response_body(ctx->modsec_transaction, data, chain->buf->end - data); ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r); if (ret > 0) { return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, ret); } } msc_process_response_body(ctx->modsec_transaction); /* XXX: I don't get how body from modsec being transferred to nginx's buffer. If so - after adjusting of nginx's XXX: body we can proceed to adjust body size (content-length). see xslt_body_filter() for example */ ret = ngx_http_modsecurity_process_intervention(ctx->modsec_transaction, r); if (ret > 0) { return ret; } else if (ret < 0) { return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); } } else { dd("buffer was not fully loaded! ctx: %p", ctx); } /* XXX: xflt_filter() -- return NGX_OK here */ return ngx_http_next_body_filter(r, in); }
static ngx_int_t ngx_http_lua_rewrite_by_chunk(lua_State *L, ngx_http_request_t *r) { int co_ref; lua_State *co; ngx_int_t rc; ngx_connection_t *c; ngx_http_lua_ctx_t *ctx; ngx_http_cleanup_t *cln; ngx_http_lua_loc_conf_t *llcf; /* {{{ new coroutine to handle request */ co = ngx_http_lua_new_thread(r, L, &co_ref); if (co == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "lua: failed to create new coroutine to handle request"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } /* move code closure to new coroutine */ lua_xmove(L, co, 1); /* set closure's env table to new coroutine's globals table */ ngx_http_lua_get_globals_table(co); lua_setfenv(co, -2); /* save nginx request in coroutine globals table */ ngx_http_lua_set_req(co, r); /* {{{ initialize request context */ ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); dd("ctx = %p", ctx); if (ctx == NULL) { return NGX_ERROR; } ngx_http_lua_reset_ctx(r, L, ctx); ctx->entered_rewrite_phase = 1; ctx->cur_co_ctx = &ctx->entry_co_ctx; ctx->cur_co_ctx->co = co; ctx->cur_co_ctx->co_ref = co_ref; #ifdef NGX_LUA_USE_ASSERT ctx->cur_co_ctx->co_top = 1; #endif /* }}} */ /* {{{ register request cleanup hooks */ if (ctx->cleanup == NULL) { cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } cln->handler = ngx_http_lua_request_cleanup_handler; cln->data = ctx; ctx->cleanup = &cln->handler; } /* }}} */ ctx->context = NGX_HTTP_LUA_CONTEXT_REWRITE; llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (llcf->check_client_abort) { r->read_event_handler = ngx_http_lua_rd_check_broken_connection; } else { r->read_event_handler = ngx_http_block_reading; } rc = ngx_http_lua_run_thread(L, r, ctx, 0); if (rc == NGX_ERROR || rc > NGX_OK) { return rc; } c = r->connection; if (rc == NGX_AGAIN) { rc = ngx_http_lua_run_posted_threads(c, L, r, ctx); } else if (rc == NGX_DONE) { ngx_http_lua_finalize_request(r, NGX_DONE); rc = ngx_http_lua_run_posted_threads(c, L, r, ctx); } if (rc == NGX_OK || rc == NGX_DECLINED) { if (r->header_sent) { dd("header already sent"); /* response header was already generated in access_by_lua*, * so it is no longer safe to proceed to later phases * which may generate responses again */ if (!ctx->eof) { dd("eof not yet sent"); rc = ngx_http_lua_send_chain_link(r, ctx, NULL /* indicate last_buf */); if (rc == NGX_ERROR || rc > NGX_OK) { return rc; } } return NGX_HTTP_OK; } return NGX_DECLINED; } return rc; }
static int ngx_http_lua_ngx_timer_at(lua_State *L) { int nargs, co_ref; u_char *p; lua_State *vm; /* the main thread */ lua_State *co; ngx_msec_t delay; ngx_event_t *ev; ngx_http_request_t *r; ngx_connection_t *saved_c = NULL; ngx_http_lua_ctx_t *ctx; #if 0 ngx_http_connection_t *hc; #endif ngx_http_lua_timer_ctx_t *tctx = NULL; ngx_http_lua_main_conf_t *lmcf; #if 0 ngx_http_core_main_conf_t *cmcf; #endif nargs = lua_gettop(L); if (nargs < 2) { return luaL_error(L, "expecting at least 2 arguments but got %d", nargs); } delay = (ngx_msec_t) (luaL_checknumber(L, 1) * 1000); luaL_argcheck(L, lua_isfunction(L, 2) && !lua_iscfunction(L, 2), 2, "Lua function expected"); r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ngx_exiting && delay > 0) { lua_pushnil(L); lua_pushliteral(L, "process exiting"); return 2; } lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); if (lmcf->pending_timers >= lmcf->max_pending_timers) { lua_pushnil(L); lua_pushliteral(L, "too many pending timers"); return 2; } if (lmcf->watcher == NULL) { /* create the watcher fake connection */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua creating fake watcher connection"); if (ngx_cycle->files) { saved_c = ngx_cycle->files[0]; } lmcf->watcher = ngx_get_connection(0, ngx_cycle->log); if (ngx_cycle->files) { ngx_cycle->files[0] = saved_c; } if (lmcf->watcher == NULL) { return luaL_error(L, "no memory"); } /* to work around the -1 check in ngx_worker_process_cycle: */ lmcf->watcher->fd = (ngx_socket_t) -2; lmcf->watcher->idle = 1; lmcf->watcher->read->handler = ngx_http_lua_abort_pending_timers; lmcf->watcher->data = lmcf; } vm = ngx_http_lua_get_lua_vm(r, ctx); co = lua_newthread(vm); /* L stack: time func [args] thread */ ngx_http_lua_probe_user_coroutine_create(r, L, co); lua_createtable(co, 0, 0); /* the new globals table */ /* co stack: global_tb */ lua_createtable(co, 0, 1); /* the metatable */ ngx_http_lua_get_globals_table(co); lua_setfield(co, -2, "__index"); lua_setmetatable(co, -2); /* co stack: global_tb */ ngx_http_lua_set_globals_table(co); /* co stack: <empty> */ dd("stack top: %d", lua_gettop(L)); lua_xmove(vm, L, 1); /* move coroutine from main thread to L */ /* L stack: time func [args] thread */ /* vm stack: empty */ lua_pushvalue(L, 2); /* copy entry function to top of L*/ /* L stack: time func [args] thread func */ lua_xmove(L, co, 1); /* move entry function from L to co */ /* L stack: time func [args] thread */ /* co stack: func */ ngx_http_lua_get_globals_table(co); lua_setfenv(co, -2); /* co stack: func */ lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); lua_rawget(L, LUA_REGISTRYINDEX); /* L stack: time func [args] thread corountines */ lua_pushvalue(L, -2); /* L stack: time func [args] thread coroutines thread */ co_ref = luaL_ref(L, -2); lua_pop(L, 1); /* L stack: time func [args] thread */ if (nargs > 2) { lua_pop(L, 1); /* L stack: time func [args] */ lua_xmove(L, co, nargs - 2); /* L stack: time func */ /* co stack: func [args] */ } p = ngx_alloc(sizeof(ngx_event_t) + sizeof(ngx_http_lua_timer_ctx_t), r->connection->log); if (p == NULL) { goto nomem; } ev = (ngx_event_t *) p; ngx_memzero(ev, sizeof(ngx_event_t)); p += sizeof(ngx_event_t); tctx = (ngx_http_lua_timer_ctx_t *) p; tctx->premature = 0; tctx->co_ref = co_ref; tctx->co = co; tctx->main_conf = r->main_conf; tctx->srv_conf = r->srv_conf; tctx->loc_conf = r->loc_conf; tctx->lmcf = lmcf; tctx->pool = ngx_create_pool(128, ngx_cycle->log); if (tctx->pool == NULL) { goto nomem; } if (r->connection) { tctx->listening = r->connection->listening; } else { tctx->listening = NULL; } if (r->connection->addr_text.len) { tctx->client_addr_text.data = ngx_palloc(tctx->pool, r->connection->addr_text.len); if (tctx->client_addr_text.data == NULL) { goto nomem; } ngx_memcpy(tctx->client_addr_text.data, r->connection->addr_text.data, r->connection->addr_text.len); tctx->client_addr_text.len = r->connection->addr_text.len; } else { tctx->client_addr_text.len = 0; tctx->client_addr_text.data = NULL; } if (ctx && ctx->vm_state) { tctx->vm_state = ctx->vm_state; tctx->vm_state->count++; } else { tctx->vm_state = NULL; } ev->handler = ngx_http_lua_timer_handler; ev->data = tctx; ev->log = ngx_cycle->log; lmcf->pending_timers++; ngx_add_timer(ev, delay); lua_pushinteger(L, 1); return 1; nomem: if (tctx && tctx->pool) { ngx_destroy_pool(tctx->pool); } lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); lua_rawget(L, LUA_REGISTRYINDEX); luaL_unref(L, -1, co_ref); return luaL_error(L, "no memory"); }
static void ngx_http_lua_abort_pending_timers(ngx_event_t *ev) { ngx_int_t i, n; ngx_event_t **events; ngx_connection_t *c, *saved_c = NULL; ngx_rbtree_node_t *cur, *prev, *next, *sentinel, *temp; ngx_http_lua_timer_ctx_t *tctx; ngx_http_lua_main_conf_t *lmcf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua abort pending timers"); c = ev->data; lmcf = c->data; dd("lua connection fd: %d", (int) c->fd); if (!c->close) { return; } c->read->closed = 1; c->write->closed = 1; /* we temporarily use a valid fd (0) to make ngx_free_connection happy */ c->fd = 0; if (ngx_cycle->files) { saved_c = ngx_cycle->files[0]; } ngx_free_connection(c); c->fd = (ngx_socket_t) -1; if (ngx_cycle->files) { ngx_cycle->files[0] = saved_c; } if (lmcf->pending_timers == 0) { return; } /* expire pending timers immediately */ sentinel = ngx_event_timer_rbtree.sentinel; cur = ngx_event_timer_rbtree.root; /* XXX nginx does not guarentee the parent of root is meaningful, * so we temporarily override it to simplify tree traversal. */ temp = cur->parent; cur->parent = NULL; prev = NULL; events = ngx_pcalloc(ngx_cycle->pool, lmcf->pending_timers * sizeof(ngx_event_t)); if (events == NULL) { return; } n = 0; dd("root: %p, root parent: %p, sentinel: %p", cur, cur->parent, sentinel); while (n < lmcf->pending_timers) { if (cur == sentinel || cur == NULL) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "lua pending timer counter got out of sync: %i", lmcf->pending_timers); break; } dd("prev: %p, cur: %p, cur parent: %p, cur left: %p, cur right: %p", prev, cur, cur->parent, cur->left, cur->right); if (prev == cur->parent) { /* neither of the children has been accessed yet */ next = cur->left; if (next == sentinel) { ev = (ngx_event_t *) ((char *) cur - offsetof(ngx_event_t, timer)); if (ev->handler == ngx_http_lua_timer_handler) { dd("found node: %p", cur); events[n++] = ev; } next = (cur->right != sentinel) ? cur->right : cur->parent; } } else if (prev == cur->left) { /* just accessed the left child */ ev = (ngx_event_t *) ((char *) cur - offsetof(ngx_event_t, timer)); if (ev->handler == ngx_http_lua_timer_handler) { dd("found node 2: %p", cur); events[n++] = ev; } next = (cur->right != sentinel) ? cur->right : cur->parent; } else if (prev == cur->right) { /* already accessed both children */ next = cur->parent; } else { /* not reacheable */ next = NULL; } prev = cur; cur = next; } /* restore the old tree root's parent */ ngx_event_timer_rbtree.root->parent = temp; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua found %i pending timers to be aborted prematurely", n); for (i = 0; i < n; i++) { ev = events[i]; ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer); #if (NGX_DEBUG) ev->timer.left = NULL; ev->timer.right = NULL; ev->timer.parent = NULL; #endif ev->timer_set = 0; ev->timedout = 1; tctx = ev->data; tctx->premature = 1; dd("calling timer handler prematurely"); ev->handler(ev); } #if 0 if (pending_timers) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "lua pending timer counter got out of sync: %i", pending_timers); } #endif }
static ngx_int_t ngx_http_srcache_fetch_subrequest(ngx_http_request_t *r, ngx_http_srcache_loc_conf_t *conf, ngx_http_srcache_ctx_t *ctx) { ngx_http_srcache_ctx_t *sr_ctx; ngx_http_post_subrequest_t *psr; ngx_str_t args; ngx_uint_t flags = 0; ngx_http_request_t *sr; ngx_int_t rc; ngx_http_srcache_parsed_request_t *parsed_sr; dd_enter(); parsed_sr = ngx_palloc(r->pool, sizeof(ngx_http_srcache_parsed_request_t)); if (parsed_sr == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } parsed_sr->method = conf->fetch->method; parsed_sr->method_name = conf->fetch->method_name; parsed_sr->request_body = NULL; parsed_sr->content_length_n = -1; if (ngx_http_complex_value(r, &conf->fetch->location, &parsed_sr->location) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (parsed_sr->location.len == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ngx_http_complex_value(r, &conf->fetch->args, &parsed_sr->args) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } args.data = NULL; args.len = 0; if (ngx_http_parse_unsafe_uri(r, &parsed_sr->location, &args, &flags) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (args.len > 0 && parsed_sr->args.len == 0) { parsed_sr->args = args; } sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_srcache_ctx_t)); if (sr_ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } sr_ctx->in_fetch_subrequest = 1; psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); if (psr == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } psr->handler = ngx_http_srcache_fetch_post_subrequest; psr->data = sr_ctx; dd("firing the fetch subrequest"); dd("fetch location: %.*s", (int) parsed_sr->location.len, parsed_sr->location.data); dd("fetch args: %.*s", (int) parsed_sr->args.len, parsed_sr->args.data); rc = ngx_http_subrequest(r, &parsed_sr->location, &parsed_sr->args, &sr, psr, flags); if (rc != NGX_OK) { return NGX_ERROR; } rc = ngx_http_srcache_adjust_subrequest(sr, parsed_sr); if (rc != NGX_OK) { return NGX_ERROR; } ngx_http_set_ctx(sr, sr_ctx, ngx_http_srcache_filter_module); ctx->fetch_sr = sr; return NGX_OK; }
ngx_int_t ngx_http_lua_post_subrequest(ngx_http_request_t *r, void *data, ngx_int_t rc) { ngx_http_request_t *pr; ngx_http_lua_ctx_t *pr_ctx; ngx_http_lua_ctx_t *ctx; /* subrequest ctx */ ngx_http_lua_co_ctx_t *pr_coctx; size_t len; ngx_str_t *body_str; u_char *p; ngx_chain_t *cl; ngx_http_lua_post_subrequest_data_t *psr_data = data; ctx = psr_data->ctx; if (ctx->run_post_subrequest) { return NGX_OK; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua run post subrequest handler: rc:%d", rc); ctx->run_post_subrequest = 1; pr = r->parent; pr_ctx = ngx_http_get_module_ctx(pr, ngx_http_lua_module); if (pr_ctx == NULL) { return NGX_ERROR; } pr_coctx = psr_data->pr_co_ctx; pr_coctx->waiting--; if (pr_coctx->waiting == 0) { pr_coctx->done = 1; } if (pr_ctx->entered_content_phase) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua restoring write event handler"); pr->write_event_handler = ngx_http_lua_content_wev_handler; } dd("status rc = %d", (int) rc); dd("status headers_out.status = %d", (int) r->headers_out.status); dd("uri: %.*s", (int) r->uri.len, r->uri.data); /* capture subrequest response status */ if (rc == NGX_ERROR) { pr_coctx->sr_statuses[ctx->index] = NGX_HTTP_INTERNAL_SERVER_ERROR; } else if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { pr_coctx->sr_statuses[ctx->index] = rc; } else { pr_coctx->sr_statuses[ctx->index] = r->headers_out.status; } if (pr_coctx->sr_statuses[ctx->index] == 0) { pr_coctx->sr_statuses[ctx->index] = NGX_HTTP_OK; } dd("pr_coctx status: %d", (int) pr_coctx->sr_statuses[ctx->index]); /* copy subrequest response headers */ pr_coctx->sr_headers[ctx->index] = &r->headers_out; /* copy subrequest response body */ body_str = &pr_coctx->sr_bodies[ctx->index]; len = 0; for (cl = ctx->body; cl; cl = cl->next) { /* ignore all non-memory buffers */ len += cl->buf->last - cl->buf->pos; } body_str->len = len; if (len == 0) { body_str->data = NULL; } else { p = ngx_palloc(r->pool, len); if (p == NULL) { return NGX_ERROR; } body_str->data = p; /* copy from and then free the data buffers */ for (cl = ctx->body; cl; cl = cl->next) { p = ngx_copy(p, cl->buf->pos, cl->buf->last - cl->buf->pos); cl->buf->last = cl->buf->pos; #if 0 dd("free body chain link buf ASAP"); ngx_pfree(r->pool, cl->buf->start); #endif } } if (ctx->body) { #if defined(nginx_version) && nginx_version >= 1001004 ngx_chain_update_chains(r->pool, #else ngx_chain_update_chains( #endif &pr_ctx->free_bufs, &pr_ctx->busy_bufs, &ctx->body, (ngx_buf_tag_t) &ngx_http_lua_module); dd("free bufs: %p", pr_ctx->free_bufs); }
static int ngx_http_lua_ngx_req_get_body_data(lua_State *L) { ngx_http_request_t *r; int n; size_t len; ngx_chain_t *cl; u_char *p; u_char *buf; n = lua_gettop(L); if (n != 0) { return luaL_error(L, "expecting 0 arguments but seen %d", n); } lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "request object not found"); } if (r->request_body == NULL || r->request_body->temp_file || r->request_body->bufs == NULL) { lua_pushnil(L); return 1; } cl = r->request_body->bufs; if (cl->next == NULL) { len = cl->buf->last - cl->buf->pos; if (len == 0) { lua_pushnil(L); return 1; } lua_pushlstring(L, (char *) cl->buf->pos, len); return 1; } /* found multi-buffer body */ len = 0; for (; cl; cl = cl->next) { dd("body chunk len: %d", (int) ngx_buf_size(cl->buf)); len += cl->buf->last - cl->buf->pos; } if (len == 0) { lua_pushnil(L); return 1; } buf = (u_char *) lua_newuserdata(L, len); p = buf; for (cl = r->request_body->bufs; cl; cl = cl->next) { p = ngx_copy(p, cl->buf->pos, cl->buf->last - cl->buf->pos); } lua_pushlstring(L, (char *) buf, len); return 1; }
static int ngx_stream_lua_uthread_wait(lua_State *L) { int i, nargs, nrets; lua_State *sub_co; ngx_stream_session_t *s; ngx_stream_lua_ctx_t *ctx; ngx_stream_lua_co_ctx_t *coctx, *sub_coctx; s = ngx_stream_lua_get_session(L); if (s == NULL) { return luaL_error(L, "no session found"); } ctx = ngx_stream_get_module_ctx(s, ngx_stream_lua_module); if (ctx == NULL) { return luaL_error(L, "no session ctx found"); } ngx_stream_lua_check_context(L, ctx, NGX_STREAM_LUA_CONTEXT_CONTENT | NGX_STREAM_LUA_CONTEXT_TIMER); coctx = ctx->cur_co_ctx; nargs = lua_gettop(L); for (i = 1; i <= nargs; i++) { sub_co = lua_tothread(L, i); luaL_argcheck(L, sub_co, i, "stream lua thread expected"); sub_coctx = ngx_stream_lua_get_co_ctx(sub_co, ctx); if (sub_coctx == NULL) { return luaL_error(L, "no co ctx found"); } if (!sub_coctx->is_uthread) { return luaL_error(L, "attempt to wait on a coroutine that is " "not a user thread"); } if (sub_coctx->parent_co_ctx != coctx) { return luaL_error(L, "only the parent coroutine can wait on the " "thread"); } switch (sub_coctx->co_status) { case NGX_STREAM_LUA_CO_ZOMBIE: ngx_stream_lua_probe_info("found zombie child"); nrets = lua_gettop(sub_coctx->co); dd("child retval count: %d, %s: %s", (int) nrets, luaL_typename(sub_coctx->co, -1), lua_tostring(sub_coctx->co, -1)); if (nrets) { lua_xmove(sub_coctx->co, L, nrets); } #if 1 ngx_stream_lua_del_thread(s, L, ctx, sub_coctx); ctx->uthreads--; #endif return nrets; case NGX_STREAM_LUA_CO_DEAD: dd("uthread already waited: %p (parent %p)", sub_coctx, coctx); if (i < nargs) { /* just ignore it if it is not the last one */ continue; } /* being the last one */ lua_pushnil(L); lua_pushliteral(L, "already waited or killed"); return 2; default: dd("uthread %p still alive, status: %d, parent %p", sub_coctx, sub_coctx->co_status, coctx); break; } #if 0 /* TODO */ ngx_stream_lua_probe_user_thread_wait(L, sub_coctx->co); #endif sub_coctx->waited_by_parent = 1; } return lua_yield(L, 0); }
static int ngx_http_lua_ngx_req_init_body(lua_State *L) { ngx_http_request_t *r; int n; ngx_http_request_body_t *rb; size_t size; lua_Integer num; #if 1 ngx_temp_file_t *tf; #endif ngx_http_core_loc_conf_t *clcf; n = lua_gettop(L); if (n != 1 && n != 0) { return luaL_error(L, "expecting 0 or 1 argument but seen %d", n); } lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r->discard_body) { return luaL_error(L, "request body already discarded asynchronously"); } if (r->request_body == NULL) { return luaL_error(L, "request body not read yet"); } if (n == 1) { num = luaL_checkinteger(L, 1); if (num <= 0) { return luaL_error(L, "bad size argument: %d", (int) num); } size = (size_t) num; } else { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); size = clcf->client_body_buffer_size; size += size >> 2; /* avoid allocating an unnecessary large buffer */ if (size > (size_t) r->headers_in.content_length_n) { size = r->headers_in.content_length_n; } } rb = r->request_body; #if 1 tf = rb->temp_file; if (tf) { if (tf->file.fd != NGX_INVALID_FILE) { dd("cleaning temp file %.*s", (int) tf->file.name.len, tf->file.name.data); ngx_http_lua_pool_cleanup_file(r->pool, tf->file.fd); ngx_memzero(tf, sizeof(ngx_temp_file_t)); tf->file.fd = NGX_INVALID_FILE; dd("temp file cleaned: %.*s", (int) tf->file.name.len, tf->file.name.data); } rb->temp_file = NULL; } #endif r->request_body_in_clean_file = 1; r->headers_in.content_length_n = 0; rb->buf = ngx_create_temp_buf(r->pool, size); if (rb->buf == NULL) { return luaL_error(L, "out of memory"); } rb->bufs = ngx_alloc_chain_link(r->pool); if (rb->bufs == NULL) { return luaL_error(L, "out of memory"); } rb->bufs->buf = rb->buf; rb->bufs->next = NULL; return 0; }
/** * Set nginx internal variable content * * @retval Always return a boolean on Lua stack. Return true when variable * content was modified successfully, false otherwise. * @seealso ngx_tcp_lua_var_get * */ static int ngx_tcp_lua_var_set(lua_State *L) { ngx_tcp_variable_t *v; ngx_tcp_variable_value_t *vv; ngx_tcp_core_main_conf_t *cmcf; u_char *p, *lowcase, *val; size_t len; ngx_str_t name; ngx_uint_t hash; ngx_tcp_session_t *s; int value_type; const char *msg; lua_pushlightuserdata(L, &ngx_tcp_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); s = lua_touserdata(L, -1); lua_pop(L, 1); if (s == NULL) { return luaL_error(L, "no request object found"); } /* we skip the first argument that is the table */ /* we read the variable name */ p = (u_char *) luaL_checklstring(L, 2, &len); lowcase = ngx_palloc(s->pool, len + 1); if (lowcase == NULL) { return luaL_error(L, "memory allocation error"); } lowcase[len] = '\0'; hash = ngx_hash_strlow(lowcase, p, len); name.len = len; name.data = lowcase; /* we read the variable new value */ value_type = lua_type(L, 3); switch (value_type) { case LUA_TNUMBER: case LUA_TSTRING: p = (u_char *) luaL_checklstring(L, 3, &len); val = ngx_palloc(s->pool, len); if (val == NULL) { return luaL_error(L, "memory allocation erorr"); } ngx_memcpy(val, p, len); break; case LUA_TNIL: /* undef the variable */ val = NULL; len = 0; break; default: msg = lua_pushfstring(L, "string, number, or nil expected, " "but got %s", lua_typename(L, value_type)); return luaL_argerror(L, 1, msg); } /* we fetch the variable itself */ cmcf = ngx_tcp_get_module_main_conf(s, ngx_tcp_core_module); v = ngx_hash_find(&cmcf->variables_hash, hash, name.data, name.len); if (v) { if (!(v->flags & NGX_TCP_VAR_CHANGEABLE)) { return luaL_error(L, "variable \"%s\" not changeable", lowcase); } if (v->set_handler) { dd("set variables with set_handler"); vv = ngx_palloc(s->pool, sizeof(ngx_tcp_variable_value_t)); if (vv == NULL) { return luaL_error(L, "out of memory"); } if (value_type == LUA_TNIL) { vv->valid = 0; vv->not_found = 1; vv->no_cacheable = 0; vv->data = NULL; vv->len = 0; } else { vv->valid = 1; vv->not_found = 0; vv->no_cacheable = 0; vv->data = val; vv->len = len; } v->set_handler(s, vv, v->data); return 0; } /*if (v->flags & NGX_TCP_VAR_INDEXED) { vv = &s->variables[v->index]; dd("set indexed variable"); if (value_type == LUA_TNIL) { vv->valid = 0; vv->not_found = 1; vv->no_cacheable = 0; vv->data = NULL; vv->len = 0; } else { vv->valid = 1; vv->not_found = 0; vv->no_cacheable = 0; vv->data = val; vv->len = len; } return 0; }*/ return luaL_error(L, "variable \"%s\" cannot be assigned a value", lowcase); } /* variable not found */ return luaL_error(L, "varaible \"%s\" not found for writing; " "maybe it is a built-in variable that is not changeable " "or you sould have used \"set $%s '';\" earlier " "in the config file", lowcase, lowcase); }
static int ngx_http_lua_ngx_req_body_finish(lua_State *L) { ngx_http_request_t *r; int n; ngx_http_request_body_t *rb; ngx_buf_t *b; size_t size; ngx_str_t value; ngx_str_t key; ngx_int_t rc; n = lua_gettop(L); if (n != 0) { return luaL_error(L, "expecting 0 argument but seen %d", n); } lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r->request_body == NULL || r->request_body->buf == NULL || r->request_body->bufs == NULL) { return luaL_error(L, "request_body not initalized"); } rb = r->request_body; if (rb->temp_file) { /* save the last part */ if (ngx_http_lua_write_request_body(r, rb->bufs) != NGX_OK) { return luaL_error(L, "fail to write file"); } b = ngx_calloc_buf(r->pool); if (b == NULL) { return luaL_error(L, "out of memory"); } b->in_file = 1; b->file_pos = 0; b->file_last = rb->temp_file->file.offset; b->file = &rb->temp_file->file; if (rb->bufs->next) { rb->bufs->next->buf = b; } else { rb->bufs->buf = b; } } /* override input header Content-Length (value must be null terminated) */ value.data = ngx_palloc(r->pool, NGX_SIZE_T_LEN + 1); if (value.data == NULL) { return luaL_error(L, "out of memory"); } size = r->headers_in.content_length_n; value.len = ngx_sprintf(value.data, "%uz", size) - value.data; value.data[value.len] = '\0'; dd("setting request Content-Length to %.*s (%d)", (int) value.len, value.data, (int) size); if (r->headers_in.content_length) { r->headers_in.content_length->value.data = value.data; r->headers_in.content_length->value.len = value.len; } else { ngx_str_set(&key, "Content-Length"); rc = ngx_http_lua_set_input_header(r, key, value, 1 /* override */); if (rc != NGX_OK) { return luaL_error(L, "failed to reset the Content-Length " "input header"); } } return 0; }
ngx_inline static ngx_http_xrlt_ctx_t * ngx_http_xrlt_create_ctx(ngx_http_request_t *r, size_t id) { ngx_http_xrlt_ctx_t *ctx; ngx_http_xrlt_loc_conf_t *conf; ngx_uint_t i, j; ngx_http_xrlt_param_t *params; xmlChar **xrltparams; conf = ngx_http_get_module_loc_conf(r, ngx_http_xrlt_module); ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_xrlt_ctx_t)); if (ctx == NULL) { return NULL; } if (id == 0) { ngx_pool_cleanup_t *cln; cln = ngx_pool_cleanup_add(r->pool, 0); if (cln == NULL) { return NULL; } dd("XRLT context creation"); if (conf->params != NULL && conf->params->nelts > 0) { params = conf->params->elts; xrltparams = ngx_palloc( r->pool, sizeof(xmlChar *) * (conf->params->nelts * 2 + 1) ); j = 0; for (i = 0; i < conf->params->nelts; i++) { xrltparams[j++] = xmlStrndup(params[i].name.data, params[i].name.len); xrltparams[j++] = xmlStrndup(params[i].value.value.data, params[i].value.value.len); } xrltparams[j] = NULL; } else { xrltparams = NULL; } ctx->xctx = xrltContextCreate(conf->sheet, xrltparams); ctx->id = 0; ctx->main_ctx = ctx; if (ctx->xctx == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to create XRLT context"); } cln->handler = ngx_http_xrlt_cleanup_context; cln->data = ctx->xctx; } else { ngx_http_xrlt_ctx_t *main_ctx; main_ctx = ngx_http_get_module_ctx(r->main, ngx_http_xrlt_module); if (main_ctx == NULL || main_ctx->xctx == NULL) { return NULL; } ctx->xctx = main_ctx->xctx; ctx->id = id; ctx->main_ctx = main_ctx; } return ctx; }
/*! Connect to Pepper robot, and apply some motion. By default, this example connect to a robot with ip address: 198.18.0.1. If you want to connect on an other robot, run: ./motion --ip <robot ip address> Example: ./motion --ip 169.254.168.230 */ int main(int argc, const char* argv[]) { try { std::string opt_ip = "198.18.0.1";; if (argc == 3) { if (std::string(argv[1]) == "--ip") opt_ip = argv[2]; } vpNaoqiRobot robot; if (! opt_ip.empty()) { std::cout << "Connect to robot with ip address: " << opt_ip << std::endl; robot.setRobotIp(opt_ip); } robot.open(); std::vector<std::string> names = robot.getBodyNames("Body"); std::vector<float> values(names.size(),0.0); robot.getProxy()->setMoveArmsEnabled(false,false); robot.getPosition(names,values,false); bool servoing = true; // Define values float y = 1.0; // float ell1 = 2.0; // float ell2 = 2.0; // float ell = 2.0; float d = 0.7; // float x = 0.0; vpMatrix L(1,6); L = 0.0; //float lambda = 0.03; float lambda = 0.1;//0.09; // 0.050; vpColVector s(1); vpColVector s_star(1); s_star[0] = 3.;// 1.; vpColVector vel(6); vpColVector vel_(3); // vpMatrix J (6,6); // J =0.0; // j[] AL::ALMemoryProxy memProxy(opt_ip, 9559); bool start = false; vpImage<unsigned char> I(320, 320); vpDisplayX dd(I); vpDisplay::setTitle(I, "ViSP viewer"); vpDisplay::setWindowPosition(I,1200,900); vpLinearKalmanFilterInstantiation kalman; double rho=0.3; vpColVector sigma_state; vpColVector sigma_measure(1); int signal = 1; kalman.setStateModel(vpLinearKalmanFilterInstantiation::stateConstAccWithColoredNoise_MeasureVel); //kf.init(nbSrc,nbSrc,nbSrc); int state_size = kalman.getStateSize(); sigma_state.resize(2); sigma_state= 0.00001; // Same variance for all the signals sigma_measure = 0.05; // Same measure variance for all the signals double dt = 0.172; kalman.initFilter(signal, sigma_state , sigma_measure, rho, dt ); kalman.verbose(true); vpLinearKalmanFilterInstantiation kalman1; kalman1.setStateModel(vpLinearKalmanFilterInstantiation::stateConstAccWithColoredNoise_MeasureVel); //kf.init(nbSrc,nbSrc,nbSrc); sigma_state.resize(2); sigma_state= 0.00001; // Same variance for all the signals sigma_measure = 0.05; // Same measure variance for all the signals kalman1.initFilter(signal, sigma_state , sigma_measure, rho, dt ); kalman1.verbose(true); vpPlot plotter (2); plotter.initGraph(0, 1); plotter.initGraph(1, 2); //plotter_eyes.initGraph(2, 1); //plotter_eyes.initGraph(3, 1); plotter.setTitle(0, "Ratio"); plotter.setTitle(1, "Error"); //plotter_eyes.setTitle(2, "REyeYaw"); //plotter_eyes.setTitle(3, "REyePitch"); vpPlot plotter_kal (1); plotter_kal.initGraph(0, 2); //plotter_eyes.initGraph(2, 1); //plotter_eyes.initGraph(3, 1); plotter_kal.setTitle(0, "Ratio"); plotter_kal.setLegend(0, 0, "Ratio"); plotter_kal.setLegend(0, 1, "Ratio kal"); // vpPlot plotter_e (1); // plotter_e.initGraph(0, 2); // plotter_e.setLegend(0, 0, "Right"); // plotter_e.setLegend(0, 1, "Left"); // plotter_e.setTitle(0, "Energy"); vpPlot plotter_vel (1); plotter_vel.initGraph(0, 3); plotter_vel.setTitle(0, "Velocity"); plotter_vel.setLegend(0, 0, "vx"); plotter_vel.setLegend(0, 1, "vy"); plotter_vel.setLegend(0, 2, "wz"); unsigned long loop_iter = 0; while (1) { std::cout << "----------------------------------" << std::endl; double t = vpTime::measureTimeMs(); float ratio = memProxy.getData("ALSoundProcessing/ratioRightLeft"); float sound_detected = memProxy.getData("ALSoundProcessing/soundDetectedEnergy"); std::cout << "SoundDetected:" << sound_detected << std::endl; if ( (sound_detected > 0.5) && !start) start = true; if (start) { float E1 = memProxy.getData("ALSoundProcessing/rightMicEnergy"); float E2= memProxy.getData("ALSoundProcessing/leftMicEnergy"); E1 = E1/1e9; E2 = E2/1e9; // plotter_e.plot(0, 0,loop_iter, float( memProxy.getData("ALSoundProcessing/rightMicEnergy"))); // plotter_e.plot(0, 1,loop_iter, float( memProxy.getData("ALSoundProcessing/leftMicEnergy"))); // plotter.plot(0, 1, loop_iter,ratio); float c_x=d/2.*(E1+E2)/(E1-E2); float c_r=std::abs((d*(sqrt(E1*E2)/(E1-E2)))) ; ell=2.;//sqrt(sqrt(sqr(d*c_x))-d*d/4.+1); ell1=sqrt((c_x-d/2)*(c_x-d/2) + c_r * c_r); ell2=sqrt((c_x+d/2)*(c_x+d/2) + c_r * c_r); //float Em=4.*E1*ell1*ell1/(2*ell1*ell1+2*ell2*ell2-d*d); c_x=c_x/abs(c_x); //x=c_x; if (ratio >= 1.) x = 2; else x = -2; y=1;//c_r; std::cout<<"ell:"<<ell<<std::endl; vpColVector ratio_v(1); ratio_v[0] = ratio; //ratio_v[1] = Em; kalman.filter(ratio_v); std::cout << "Estimated x velocity: kalman.Xest[0]" << kalman.Xest[0]<< std::endl; std::cout << "Estimated x velocity: kalman.Xest[1]" << kalman.Xest[1]<< std::endl; plotter_kal.plot(0, 0, loop_iter, ratio); ratio = (4*ratio + 3*kalman.Xest[0])/7; plotter_kal.plot(0, 1, loop_iter, ratio); // Compute Interaction matrix L[0][0]= (2*x*(ratio-1)-d*(1+ratio))/(ell*ell-d*x+d*d/4.); L[0][1]=(2*y*(ratio-1))/(ell*ell-d*x+d*d/4.); L[0][5]=(y*d*(ratio+1))/(ell*ell-d*x+d*d/4.); s[0] = ratio; std::cout << "L: " << L << std::endl; //lambda = 0.0216404* log(1+abs(ratio - s_star)); //Compute joint velocity NeckYaw vpColVector e = (s-s_star); vel =-lambda*L.pseudoInverse()*e;/* Compute V_m*/ std::cout << "e :" << e << std::endl; vel_[0] = vel[1]; vel_[1] = -vel[0]; vel_[2] = vel[5]; plotter_vel.plot(0, 0, loop_iter, vel_[0]); plotter_vel.plot(0, 1, loop_iter, vel_[1]); plotter_vel.plot(0, 2, loop_iter, vel_[2]); plotter.plot(0, 0, loop_iter,ratio); plotter.plot(1, 0, loop_iter,e[0]); std::cout << "vel: " << vel << std::endl; if (servoing) { robot.getProxy()->move(vel_[0],vel_[1],vel_[2]); robot.getProxy()->setAngles(names,values,1.0); } } // Save current values loop_iter ++; vpTime::sleepMs(170); std::cout << "Loop time: " << vpTime::measureTimeMs() - t << " ms" << std::endl; if (vpDisplay::getClick(I, false)) break; } robot.getProxy()->move(0.0,0.0,0.0); // plotter->saveData(0, "ratio.dat"); vpDisplay::getClick(I, true); plotter_kal.saveData(0, "ratio.dat"); // plotter_kal.saveData(1,"em.dat"); plotter_vel.saveData(0, "vel.dat"); } catch (const vpException &e) { std::cerr << "Caught exception: " << e.what() << std::endl; } catch (const AL::ALError &e) { std::cerr << "Caught exception: " << e.what() << std::endl; } return 0; }
ngx_inline static ngx_int_t ngx_http_xrlt_process_transform_result(ngx_http_request_t *r, ngx_http_xrlt_ctx_t *ctx, int result) { xrltString s; if (result & XRLT_STATUS_ERROR) { return NGX_ERROR; } if (result == XRLT_STATUS_WAITING) { // Nothing to do, just wait. return NGX_AGAIN; } if (result & XRLT_STATUS_HEADER) { ngx_table_elt_t *h; xrltHeaderOutType htype; xrltString hname; xrltString hval; ngx_int_t hst; while (xrltHeaderOutListShift(&ctx->xctx->header, &htype, &hname, &hval)) { if (ctx->headers_sent) { dd("Response headers are already sent"); } else { if (htype == XRLT_HEADER_OUT_STATUS) { hst = ngx_atoi((u_char *)hval.data, hval.len); if (hst < 0) { xrltStringClear(&hname); xrltStringClear(&hval); return NGX_ERROR; } r->main->headers_out.status = (ngx_uint_t)hst; } else { h = ngx_list_push(&r->main->headers_out.headers); if (h == NULL) { xrltStringClear(&hname); xrltStringClear(&hval); return NGX_ERROR; } h->hash = 1; XRLT_STR_2_NGX_STR(h->key, hname); XRLT_STR_2_NGX_STR(h->value, hval); dd("Pushing response header (name: %s, value: %s)", h->key.data, h->value.data); } } xrltStringClear(&hname); xrltStringClear(&hval); } } if (result & XRLT_STATUS_REFUSE_SUBREQUEST) { // Cancel r subrequest, there is something wrong with it. ctx->refused = TRUE; } if (result & XRLT_STATUS_SUBREQUEST) { size_t sr_id; xrltHTTPMethod m; xrltSubrequestDataType type; xrltHeaderOutList sr_header; xrltString url, querystring, body, hname, hval; xrltHeaderOutType htype; ngx_http_xrlt_ctx_t *sr_ctx; ngx_str_t sr_uri, sr_querystring, sr_body; ngx_http_request_t *sr; ngx_http_post_subrequest_t *psr; ngx_http_request_body_t *rb; ngx_buf_t *b; ngx_table_elt_t *h; ngx_http_core_main_conf_t *cmcf; while (xrltSubrequestListShift(&ctx->xctx->sr, &sr_id, &m, &type, &sr_header, &url, &querystring, &body)) { sr_ctx = ngx_http_xrlt_create_ctx(r, sr_id); if (sr_ctx == NULL) { xrltHeaderOutListClear(&sr_header); xrltStringClear(&url); xrltStringClear(&querystring); xrltStringClear(&body); return NGX_ERROR; } XRLT_STR_2_NGX_STR(sr_uri, url); XRLT_STR_2_NGX_STR(sr_querystring, querystring); XRLT_STR_2_NGX_STR(sr_body, body); xrltStringClear(&url); xrltStringClear(&querystring); xrltStringClear(&body); psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); if (psr == NULL) { return NGX_ERROR; } psr->handler = ngx_http_xrlt_post_sr; psr->data = sr_ctx; if (ngx_http_subrequest(r->main, &sr_uri, &sr_querystring, &sr, psr, 0) != NGX_OK) { xrltHeaderOutListClear(&sr_header); return NGX_ERROR; } dd("Performing subrequest (r: %p, uri: %s, querystring: %s, " "body: %s)", sr, sr_uri.data, sr_querystring.data, sr_body.data); // Don't inherit parent request variables. Content-Length is // cacheable in proxy module and we don't need Content-Length from // another subrequest. cmcf = ngx_http_get_module_main_conf(sr, ngx_http_core_module); sr->variables = ngx_pcalloc(sr->pool, cmcf->variables.nelts * sizeof(ngx_http_variable_value_t)); if (sr->variables == NULL) { return NGX_ERROR; } switch (m) { case XRLT_METHOD_GET: sr->method = NGX_HTTP_GET; break; case XRLT_METHOD_HEAD: sr->method = NGX_HTTP_HEAD; sr->method_name = ngx_http_xrlt_head_method; break; case XRLT_METHOD_POST: sr->method = NGX_HTTP_POST; sr->method_name = ngx_http_xrlt_post_method; break; case XRLT_METHOD_PUT: sr->method = NGX_HTTP_PUT; sr->method_name = ngx_http_xrlt_put_method; break; case XRLT_METHOD_DELETE: sr->method = NGX_HTTP_DELETE; sr->method_name = ngx_http_xrlt_delete_method; break; case XRLT_METHOD_TRACE: sr->method = NGX_HTTP_TRACE; sr->method_name = ngx_http_xrlt_trace_method; break; case XRLT_METHOD_OPTIONS: sr->method = NGX_HTTP_OPTIONS; sr->method_name = ngx_http_xrlt_options_method; break; default: sr->method = NGX_HTTP_GET; } if (ngx_http_xrlt_init_subrequest_headers(sr, sr_body.len) == NGX_ERROR) { xrltHeaderOutListClear(&sr_header); return NGX_ERROR; } if (sr_header.first != NULL) { while (xrltHeaderOutListShift(&sr_header, &htype, &hname, &hval)) { h = ngx_list_push(&sr->headers_in.headers); if (h == NULL) { xrltStringClear(&hname); xrltStringClear(&hval); xrltHeaderOutListClear(&sr_header); return NGX_ERROR; } XRLT_STR_2_NGX_STR(h->key, hname); XRLT_STR_2_NGX_STR(h->value, hval); xrltStringClear(&hname); xrltStringClear(&hval); h->lowcase_key = ngx_pnalloc(r->pool, h->key.len); if (h->lowcase_key == NULL) { xrltHeaderOutListClear(&sr_header); return NGX_ERROR; } ngx_strlow(h->lowcase_key, h->key.data, h->key.len); } } ngx_http_set_ctx(sr, sr_ctx, ngx_http_xrlt_module); if (sr_body.len > 0) { rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); if (rb == NULL) { return NGX_ERROR; } b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } rb->bufs = ngx_alloc_chain_link(r->pool); if (rb->bufs == NULL) { return NGX_ERROR; } b->temporary = 1; b->start = b->pos = sr_body.data; b->end = b->last = sr_body.data + sr_body.len; b->last_buf = 1; b->last_in_chain = 1; rb->bufs->buf = b; rb->bufs->next = NULL; rb->buf = b; sr->request_body = rb; } } } if (result & XRLT_STATUS_CHUNK) { // Send response chunks out in case we don't have response headers in // progress or if response headers are sent. if (ctx->headers_sent || ctx->xctx->headerCount == 0) { ngx_buf_t *b; ngx_chain_t out; ngx_http_request_t *ar; /* active request */ ngx_int_t rc; while (xrltChunkListShift(&ctx->xctx->chunk, &s)) { if (s.len > 0) { if (!ctx->main_ctx->headers_sent) { ctx->main_ctx->headers_sent = 1; dd("Sending response headers"); if (ngx_http_send_header(r->main) != NGX_OK) { xrltStringClear(&s); return NGX_ERROR; } } b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { xrltStringClear(&s); return NGX_ERROR; } b->start = ngx_pcalloc(r->pool, s.len); if (b->start == NULL) { xrltStringClear(&s); return NGX_ERROR; } (void)ngx_copy(b->start, s.data, s.len); b->pos = b->start; b->last = b->end = b->start + s.len; b->temporary = 1; b->last_in_chain = 1; b->flush = 1; b->last_buf = 0; out.buf = b; out.next = NULL; dd("Sending response chunk (len: %zd)", s.len); ar = r->connection->data; if (ar != r->main) { /* bypass ngx_http_postpone_filter_module */ r->connection->data = r->main; rc = ngx_http_output_filter(r->main, &out); r->connection->data = ar; } else { rc = ngx_http_output_filter(r->main, &out); } if (rc == NGX_ERROR) { xrltStringClear(&s); return NGX_ERROR; } } xrltStringClear(&s); } } } if (result & XRLT_STATUS_LOG) { xrltLogType ltype; ngx_uint_t l; while (xrltLogListShift(&ctx->xctx->log, <ype, &s)) { switch (ltype) { case XRLT_ERROR: l = NGX_LOG_ERR; break; case XRLT_WARNING: l = NGX_LOG_WARN; break; case XRLT_DEBUG: l = NGX_LOG_DEBUG; break; case XRLT_INFO: default: l = NGX_LOG_INFO; break; } ngx_log_error(l, r->connection->log, 0, s.data); xrltStringClear(&s); } } if (result & XRLT_STATUS_DONE) { if (!ctx->main_ctx->headers_sent) { ctx->main_ctx->headers_sent = 1; dd("Sending response headers"); if (ngx_http_send_header(r->main) != NGX_OK) { return NGX_ERROR; } } r->main->write_event_handler = ngx_http_xrlt_wev_handler; if (ngx_http_send_special(r->main, NGX_HTTP_LAST) == NGX_ERROR) { return NGX_ERROR; } return NGX_DONE; } return NGX_OK; }
static int ngx_http_lua_socket_udp_setpeername(lua_State *L) { ngx_http_request_t *r; ngx_http_lua_ctx_t *ctx; ngx_str_t host; int port; ngx_resolver_ctx_t *rctx, temp; ngx_http_core_loc_conf_t *clcf; int saved_top; int n; u_char *p; size_t len; ngx_url_t url; ngx_int_t rc; ngx_http_lua_loc_conf_t *llcf; int timeout; ngx_http_lua_co_ctx_t *coctx; ngx_http_lua_udp_connection_t *uc; ngx_http_lua_socket_udp_upstream_t *u; /* * TODO: we should probably accept an extra argument to setpeername() * to allow the user bind the datagram unix domain socket himself, * which is necessary for systems without autobind support. */ n = lua_gettop(L); if (n != 2 && n != 3) { return luaL_error(L, "ngx.socket.udp setpeername: expecting 2 or 3 " "arguments (including the object), but seen %d", n); } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no ctx found"); } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT | NGX_HTTP_LUA_CONTEXT_TIMER | NGX_HTTP_LUA_CONTEXT_SSL_CERT); luaL_checktype(L, 1, LUA_TTABLE); p = (u_char *) luaL_checklstring(L, 2, &len); host.data = ngx_palloc(r->pool, len + 1); if (host.data == NULL) { return luaL_error(L, "no memory"); } host.len = len; ngx_memcpy(host.data, p, len); host.data[len] = '\0'; if (n == 3) { port = luaL_checkinteger(L, 3); if (port < 0 || port > 65536) { lua_pushnil(L); lua_pushfstring(L, "bad port number: %d", port); return 2; } } else { /* n == 2 */ port = 0; } lua_rawgeti(L, 1, SOCKET_CTX_INDEX); u = lua_touserdata(L, -1); lua_pop(L, 1); if (u) { if (u->request && u->request != r) { return luaL_error(L, "bad request"); } if (u->waiting) { lua_pushnil(L); lua_pushliteral(L, "socket busy"); return 2; } if (u->udp_connection.connection) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket reconnect without shutting down"); ngx_http_lua_socket_udp_finalize(r, u); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua reuse socket upstream ctx"); } else { u = lua_newuserdata(L, sizeof(ngx_http_lua_socket_udp_upstream_t)); if (u == NULL) { return luaL_error(L, "no memory"); } #if 1 lua_pushlightuserdata(L, &ngx_http_lua_udp_udata_metatable_key); lua_rawget(L, LUA_REGISTRYINDEX); lua_setmetatable(L, -2); #endif lua_rawseti(L, 1, SOCKET_CTX_INDEX); } ngx_memzero(u, sizeof(ngx_http_lua_socket_udp_upstream_t)); u->request = r; /* set the controlling request */ llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); u->conf = llcf; uc = &u->udp_connection; uc->log = *r->connection->log; dd("lua peer connection log: %p", &uc->log); lua_rawgeti(L, 1, SOCKET_TIMEOUT_INDEX); timeout = (ngx_int_t) lua_tointeger(L, -1); lua_pop(L, 1); if (timeout > 0) { u->read_timeout = (ngx_msec_t) timeout; } else { u->read_timeout = u->conf->read_timeout; } ngx_memzero(&url, sizeof(ngx_url_t)); url.url.len = host.len; url.url.data = host.data; url.default_port = (in_port_t) port; url.no_resolve = 1; if (ngx_parse_url(r->pool, &url) != NGX_OK) { lua_pushnil(L); if (url.err) { lua_pushfstring(L, "failed to parse host name \"%s\": %s", host.data, url.err); } else { lua_pushfstring(L, "failed to parse host name \"%s\"", host.data); } return 2; } u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); if (u->resolved == NULL) { return luaL_error(L, "no memory"); } if (url.addrs && url.addrs[0].sockaddr) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket network address given directly"); u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; u->resolved->host = url.addrs[0].name; } else { u->resolved->host = host; u->resolved->port = (in_port_t) port; } if (u->resolved->sockaddr) { rc = ngx_http_lua_socket_resolve_retval_handler(r, u, L); if (rc == NGX_AGAIN) { return lua_yield(L, 0); } return rc; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); temp.name = host; rctx = ngx_resolve_start(clcf->resolver, &temp); if (rctx == NULL) { u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "failed to start the resolver"); return 2; } if (rctx == NGX_NO_RESOLVER) { u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushfstring(L, "no resolver defined to resolve \"%s\"", host.data); return 2; } rctx->name = host; #if !defined(nginx_version) || nginx_version < 1005008 rctx->type = NGX_RESOLVE_A; #endif rctx->handler = ngx_http_lua_socket_resolve_handler; rctx->data = u; rctx->timeout = clcf->resolver_timeout; u->co_ctx = ctx->cur_co_ctx; u->resolved->ctx = rctx; saved_top = lua_gettop(L); coctx = ctx->cur_co_ctx; ngx_http_lua_cleanup_pending_operation(coctx); coctx->cleanup = ngx_http_lua_udp_resolve_cleanup; if (ngx_resolve_name(rctx) != NGX_OK) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket fail to run resolver immediately"); u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; u->resolved->ctx = NULL; lua_pushnil(L); lua_pushfstring(L, "%s could not be resolved", host.data); return 2; } if (u->waiting == 1) { /* resolved and already connecting */ return lua_yield(L, 0); } n = lua_gettop(L) - saved_top; if (n) { /* errors occurred during resolving or connecting * or already connected */ return n; } /* still resolving */ u->waiting = 1; u->prepare_retvals = ngx_http_lua_socket_resolve_retval_handler; coctx->data = u; if (ctx->entered_content_phase) { r->write_event_handler = ngx_http_lua_content_wev_handler; } else { r->write_event_handler = ngx_http_core_run_phases; } return lua_yield(L, 0); }
static ngx_int_t ngx_http_xrlt_transform_headers(ngx_http_request_t *r, ngx_http_xrlt_ctx_t *ctx) { ngx_list_part_t *part; ngx_table_elt_t *header; ngx_uint_t i; ngx_int_t rc; xrltTransformValue val; int result; ngx_table_elt_t **cookies; char *begin, *end; dd("Transform headers (r: %p, id: %zd)", r, ctx->id); if (r == r->main) { part = &r->headers_in.headers.part; cookies = r->headers_in.cookies.elts; val.type = XRLT_TRANSFORM_VALUE_COOKIE; for (i = 0; i < r->headers_in.cookies.nelts; i++) { begin = (char *)cookies[i]->value.data; end = (char *)cookies[i]->value.data + cookies[i]->value.len; while (begin < end) { while (begin < end && *begin == ' ') { begin++; } if (begin >= end) { break; // Ignore incorrect cookie header. } val.headerval.name.data = begin; val.headerval.name.len = 0; while (begin < end && *begin != '=') { begin++; } if (begin < end && val.headerval.name.data < begin) { val.headerval.name.len = begin - val.headerval.name.data; begin++; val.headerval.val.data = begin; } else { break; // Ignore incorrect cookie header. } while (begin < end && *begin != ';') { begin++; } val.headerval.val.len = begin - val.headerval.val.data; if (val.headerval.val.len == 0) { val.headerval.val.data = NULL; } result = xrltTransform(ctx->xctx, 0, &val); rc = ngx_http_xrlt_process_transform_result(r, ctx, result); if (rc == NGX_ERROR || rc == NGX_DONE) { return rc; } begin++; } } val.type = XRLT_TRANSFORM_VALUE_QUERYSTRING; val.querystringval.val.data = (char *)r->args.data; val.querystringval.val.len = r->args.len; result = xrltTransform(ctx->xctx, 0, &val); rc = ngx_http_xrlt_process_transform_result(r, ctx, result); if (rc == NGX_ERROR || rc == NGX_DONE) { return rc; } } else { part = &r->headers_out.headers.part; } header = part->elts; val.type = XRLT_TRANSFORM_VALUE_HEADER; for (i = 0; /* void */; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } val.headerval.name.data = (char *)header[i].key.data; val.headerval.name.len = header[i].key.len; val.headerval.val.data = (char *)header[i].value.data; val.headerval.val.len = header[i].value.len; result = xrltTransform(ctx->xctx, ctx->id, &val); rc = ngx_http_xrlt_process_transform_result(r, ctx, result); if (rc == NGX_ERROR || rc == NGX_DONE) { return rc; } } if (r != r->main) { val.type = XRLT_TRANSFORM_VALUE_STATUS; val.statusval.status = r->headers_out.status; result = xrltTransform(ctx->xctx, ctx->id, &val); rc = ngx_http_xrlt_process_transform_result(r, ctx, result); if (rc == NGX_ERROR || rc == NGX_DONE) { return rc; } } val.type = XRLT_TRANSFORM_VALUE_EMPTY; rc = NGX_OK; while (rc == NGX_OK) { result = xrltTransform(ctx->xctx, 0, &val); rc = ngx_http_xrlt_process_transform_result(r, ctx, result); } return rc; }
static int ngx_http_lua_socket_udp_send(lua_State *L) { ssize_t n; ngx_http_request_t *r; u_char *p; size_t len; ngx_http_lua_socket_udp_upstream_t *u; int type; const char *msg; ngx_str_t query; ngx_http_lua_loc_conf_t *llcf; if (lua_gettop(L) != 2) { return luaL_error(L, "expecting 2 arguments (including the object), " "but got %d", lua_gettop(L)); } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "request object not found"); } luaL_checktype(L, 1, LUA_TTABLE); lua_rawgeti(L, 1, SOCKET_CTX_INDEX); u = lua_touserdata(L, -1); lua_pop(L, 1); if (u == NULL || u->udp_connection.connection == NULL) { llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (llcf->log_socket_errors) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "attempt to send data on a closed socket: u:%p, c:%p", u, u ? u->udp_connection.connection : NULL); } lua_pushnil(L); lua_pushliteral(L, "closed"); return 2; } if (u->request != r) { return luaL_error(L, "bad request"); } if (u->ft_type) { u->ft_type = 0; } if (u->waiting) { lua_pushnil(L); lua_pushliteral(L, "socket busy"); return 2; } type = lua_type(L, 2); switch (type) { case LUA_TNUMBER: case LUA_TSTRING: lua_tolstring(L, 2, &len); break; case LUA_TTABLE: len = ngx_http_lua_calc_strlen_in_table(L, 2, 2, 1 /* strict */); break; default: msg = lua_pushfstring(L, "string, number, boolean, nil, " "or array table expected, got %s", lua_typename(L, type)); return luaL_argerror(L, 2, msg); } query.data = lua_newuserdata(L, len); query.len = len; switch (type) { case LUA_TNUMBER: case LUA_TSTRING: p = (u_char *) lua_tolstring(L, 2, &len); ngx_memcpy(query.data, (u_char *) p, len); break; case LUA_TTABLE: (void) ngx_http_lua_copy_str_in_table(L, 2, query.data); break; default: return luaL_error(L, "impossible to reach here"); } u->ft_type = 0; /* mimic ngx_http_upstream_init_request here */ #if 1 u->waiting = 0; #endif dd("sending query %.*s", (int) query.len, query.data); n = ngx_send(u->udp_connection.connection, query.data, query.len); dd("ngx_send returns %d (query len %d)", (int) n, (int) query.len); if (n == NGX_ERROR || n == NGX_AGAIN) { u->socket_errno = ngx_socket_errno; return ngx_http_lua_socket_error_retval_handler(r, u, L); } if (n != (ssize_t) query.len) { dd("not the while query was sent"); u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_PARTIALWRITE; return ngx_http_lua_socket_error_retval_handler(r, u, L); } dd("n == len"); lua_pushinteger(L, 1); return 1; }
ngx_int_t ngx_http_srcache_access_handler(ngx_http_request_t *r) { ngx_str_t skip; ngx_int_t rc; ngx_http_srcache_loc_conf_t *conf; ngx_http_srcache_main_conf_t *smcf; ngx_http_srcache_ctx_t *ctx; ngx_chain_t *cl; size_t len; unsigned no_store; if (r != r->main) { return NGX_DECLINED; } /* being the main request */ conf = ngx_http_get_module_loc_conf(r, ngx_http_srcache_filter_module); if (conf->fetch == NULL && conf->store == NULL) { dd("bypass: %.*s", (int) r->uri.len, r->uri.data); return NGX_DECLINED; } dd("store defined? %p", conf->store); dd("req method: %lu", (unsigned long) r->method); dd("cache methods: %lu", (unsigned long) conf->cache_methods); if (!(r->method & conf->cache_methods)) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "srcache_fetch and srcache_store skipped due to request " "method %V", &r->method_name); return NGX_DECLINED; } if (conf->req_cache_control && ngx_http_srcache_request_no_cache(r, &no_store) == NGX_OK) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "srcache_fetch skipped due to request headers " "\"Cache-Control: no-cache\" or \"Pragma: no-cache\""); if (!no_store) { /* register a ctx to give a chance to srcache_store to run */ ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_srcache_filter_module)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_srcache_filter_module); } else { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "srcache_store skipped due to request header " "\"Cache-Control: no-store\""); } return NGX_DECLINED; } if (conf->fetch_skip != NULL && ngx_http_complex_value(r, conf->fetch_skip, &skip) == NGX_OK && skip.len && (skip.len != 1 || skip.data[0] != '0')) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "srcache_fetch skipped due to the true value fed into " "srcache_fetch_skip: \"%V\"", &skip); /* register a ctx to give a chance to srcache_store to run */ ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_srcache_filter_module)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_srcache_filter_module); return NGX_DECLINED; } ctx = ngx_http_get_module_ctx(r, ngx_http_srcache_filter_module); if (ctx != NULL) { /* if (ctx->fetch_error) { return NGX_DECLINED; } */ if (ctx->waiting_subrequest) { dd("waiting subrequest"); return NGX_AGAIN; } if (ctx->request_done) { dd("request done"); if ( #if defined(nginx_version) && nginx_version >= 8012 ngx_http_post_request(r, NULL) #else ngx_http_post_request(r) #endif != NGX_OK) { return NGX_ERROR; } if (!ctx->from_cache) { return NGX_DECLINED; } dd("sending header"); if (ctx->body_from_cache && !(r->method & NGX_HTTP_HEAD)) { len = 0; for (cl = ctx->body_from_cache; cl->next; cl = cl->next) { len += ngx_buf_size(cl->buf); } len += ngx_buf_size(cl->buf); cl->buf->last_buf = 1; r->headers_out.content_length_n = len; rc = ngx_http_srcache_next_header_filter(r); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } rc = ngx_http_srcache_next_body_filter(r, ctx->body_from_cache); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } dd("sent body from cache: %d", (int) rc); } else { r->headers_out.content_length_n = 0; rc = ngx_http_srcache_next_header_filter(r); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } dd("sent header from cache: %d", (int) rc); dd("send last buf for the main request"); cl = ngx_alloc_chain_link(r->pool); cl->buf = ngx_calloc_buf(r->pool); cl->buf->last_buf = 1; rc = ngx_http_srcache_next_body_filter(r, cl); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } dd("sent last buf from cache: %d", (int) rc); } dd("finalize from here..."); ngx_http_finalize_request(r, NGX_OK); /* dd("r->main->count (post): %d", (int) r->main->count); */ return NGX_DONE; } } else { ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_srcache_filter_module)); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_srcache_filter_module); } smcf = ngx_http_get_module_main_conf(r, ngx_http_srcache_filter_module); if (! smcf->postponed_to_access_phase_end) { ngx_http_core_main_conf_t *cmcf; ngx_http_phase_handler_t tmp; ngx_http_phase_handler_t *ph; ngx_http_phase_handler_t *cur_ph; ngx_http_phase_handler_t *last_ph; smcf->postponed_to_access_phase_end = 1; cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); ph = cmcf->phase_engine.handlers; cur_ph = &ph[r->phase_handler]; last_ph = &ph[cur_ph->next - 1]; if (cur_ph < last_ph) { dd("swaping the contents of cur_ph and last_ph..."); tmp = *cur_ph; memmove(cur_ph, cur_ph + 1, (last_ph - cur_ph) * sizeof (ngx_http_phase_handler_t)); *last_ph = tmp; r->phase_handler--; /* redo the current ph */ return NGX_DECLINED; } } if (conf->fetch == NULL) { dd("fetch is not defined"); return NGX_DECLINED; } dd("running phase handler..."); /* issue a subrequest to fetch cached stuff (if any) */ rc = ngx_http_srcache_fetch_subrequest(r, conf, ctx); if (rc != NGX_OK) { return rc; } ctx->waiting_subrequest = 1; dd("quit"); return NGX_AGAIN; }
void ngx_postgres_keepalive_free_peer(ngx_peer_connection_t *pc, ngx_postgres_upstream_peer_data_t *pgp, ngx_postgres_upstream_srv_conf_t *pgscf, ngx_uint_t state) { ngx_postgres_keepalive_cache_t *item; ngx_queue_t *q; ngx_connection_t *c; ngx_http_upstream_t *u; dd("entering"); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "postgres: free keepalive peer"); if (state & NGX_PEER_FAILED) { pgp->failed = 1; } u = pgp->upstream; if ((!pgp->failed) && (pc->connection != NULL) && (u->headers_in.status_n == NGX_HTTP_OK)) { c = pc->connection; if (c->read->timer_set) { ngx_del_timer(c->read); } if (c->write->timer_set) { ngx_del_timer(c->write); } if (c->write->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { if (ngx_del_event(c->write, NGX_WRITE_EVENT, 0) != NGX_OK) { return; } } pc->connection = NULL; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "postgres: free keepalive peer: saving connection %p", c); if (ngx_queue_empty(&pgscf->free)) { /* connection pool is already full */ q = ngx_queue_last(&pgscf->cache); ngx_queue_remove(q); item = ngx_queue_data(q, ngx_postgres_keepalive_cache_t, queue); ngx_postgres_upstream_free_connection(pc->log, item->connection, item->pgconn, pgscf); } else { q = ngx_queue_head(&pgscf->free); ngx_queue_remove(q); item = ngx_queue_data(q, ngx_postgres_keepalive_cache_t, queue); } item->connection = c; ngx_queue_insert_head(&pgscf->cache, q); c->write->handler = ngx_postgres_keepalive_dummy_handler; c->read->handler = ngx_postgres_keepalive_close_handler; c->data = item; c->idle = 1; c->log = ngx_cycle->log; #if defined(nginx_version) && (nginx_version >= 1001004) c->pool->log = ngx_cycle->log; #endif c->read->log = ngx_cycle->log; c->write->log = ngx_cycle->log; item->socklen = pc->socklen; ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen); item->pgconn = pgp->pgconn; item->name.data = pgp->name.data; item->name.len = pgp->name.len; } dd("returning"); }
bool PairMatchingCut::Get_CDA_FromCalculation( EventClass &E, int t, int a, double &z, double &cda, int &iterations) { //=====================================================================// double z1,z2; //------------------------------------------------------------------// // Find the range where to look for the CDA // //------------------------------------------------------------------// if( E.dcmin[t] < E.dcmin[a]) { z1 = E.geo->dc(std::min(E.dcmax[t], E.dcmin[a])).center().z(); z2 = E.geo->dc(std::max(E.dcmax[t], E.dcmin[a])).center().z(); } else { z1 = E.geo->dc(std::min(E.dcmax[a], E.dcmin[t])).center().z(); z2 = E.geo->dc(std::max(E.dcmax[a], E.dcmin[t])).center().z(); } z1 = z1 -0.2; z2 = z2 +0.2; // L corresponding to the maximum frequency: // L1 --> omega1, L2 --> omega2, omega_max = w1 + w2 --> Lmin double lmin = fabs(E.wavelen[t])*fabs(E.wavelen[a])/(fabs(E.wavelen[t])+fabs(E.wavelen[a])); // cout<<" In Get_CDA_FromCalculation 2 lmin ="<<lmin<<endl; // cout<<" In Get_CDA_FromCalculation 2 wavelen ="<<E.wavelen[t]<<" "<<E.wavelen[a]<<endl; // cout<<" In Get_CDA_FromCalculation 2 ptot ="<<E.ptot[t]<<" "<<E.costh[a]<<endl; //------------------------------------------------------------------// // Sample the distance to isolate local minima // // First decide about the number of points in the sample // //------------------------------------------------------------------// int nsample = int(12*(1.+fabs(z1-z2)/lmin)); TrackDistanceUV distance(E, t, a, z1, z2); vector<double> dd(nsample); for(int i = 0; i<nsample; i++) { double z = z1 + (z2-z1)*i/double(nsample-1); dd[i] = distance(z); } double A,M,B; vector<MinBracket> brackets; for(int i=1; i<nsample-1; i++) { if( (dd[i] < dd[i-1]) && (dd[i] <= dd[i+1]) ) { A = z1 + (z2-z1)*(i-1)/double(nsample-1); M = z1 + (z2-z1)*i/double(nsample-1); B = z1 + (z2-z1)*(i+1)/double(nsample-1); brackets.push_back(MinBracket(A,M,B)); } } //------------------------------------------------------------------// // Check the ends of the search interval // //------------------------------------------------------------------// // cout<<" In Get_CDA_FromCalculation 3"<<endl; // The distance of approach vector<double> Alldist; // Position of minimal distance of approach vector<double> Allz; vector<int> Alliter; if(dd[0] <= dd[1]) { double ztest = z1 + std::min(z2-z1, tolerance_abs); double ftest = distance(ztest); if( (ftest <= dd[0]) && (ftest <= dd[1])) { //std::cerr<<" z1 bracket"<<std::endl; brackets.push_back(MinBracket(z1,ztest, z1 + (z2-z1)/double(nsample-1))); } else { //std::cerr<<" z1 min"<<std::endl; // Extract the distances of approach here Alldist.push_back(dd[0]); // Position of minimal distance of approach Allz.push_back(z1); Alliter.push_back(0); } } if(dd[nsample-1] <= dd[nsample-2]) { double ztest = z2 - std::min(z2-z1, tolerance_abs); double ftest = distance(ztest); if( (ftest <= dd[nsample-1]) && (ftest <= dd[nsample-2])) { //std::cerr<<" z2 bracket"<<std::endl; brackets.push_back(MinBracket(z1 + (z2-z1)*(nsample-2)/double(nsample-1), ztest, z2)); } else { //std::cerr<<" z2 min"<<std::endl; // Extract the distances of approach here Alldist.push_back(dd[nsample-1]); // Position of minimal distance of approach Allz.push_back(z2); Alliter.push_back(0); } } // cout<<" In Get_CDA_FromCalculation 4 brackets size ="<<brackets.size()<<endl; //------------------------------------------------------------------// // Loop over the brackets and for each one of them, find a minimum. // //------------------------------------------------------------------// for(unsigned i=0; i<brackets.size(); i++) { //std::cerr<<"Bracket{"<<brackets[i].a<<", "<<brackets[i].m<<", "<<brackets[i].b<<std::endl; const gsl_min_fminimizer_type *T = gsl_min_fminimizer_brent; gsl_min_fminimizer *s = gsl_min_fminimizer_alloc (T); gsl_function F; F.function = &TrackDistanceUV::fwrapper; F.params = &distance; gsl_min_fminimizer_set(s, &F, brackets[i].m, brackets[i].a, brackets[i].b); int iter=0; while(1) { iter++; int status; if(GSL_SUCCESS != (status = gsl_min_fminimizer_iterate (s)) ) { gsl_min_fminimizer_free(s); Log->warn("PairMatchingCut: Get_CDA_FromCalculation(): failure from gsl_min_fminimizer_iterate(): status==%i", status); return false; } M = gsl_min_fminimizer_x_minimum (s); A = gsl_min_fminimizer_x_lower (s); B = gsl_min_fminimizer_x_upper (s); status = gsl_min_test_interval (A, B, tolerance_abs, tolerance_rel); if (status == GSL_SUCCESS) { //printf ("Converged:\n"); //printf ("%5d [%.7f, %.7f] %.7f %.7f\n", iter, a, b, m, b - a); // Extract the distances of approach here Alldist.push_back(gsl_min_fminimizer_f_minimum(s)); // Position of minimal distance of approach Allz.push_back(M); Alliter.push_back(iter); break; } else if(status == GSL_CONTINUE) { if(iter>max_iter) { gsl_min_fminimizer_free(s); Log->warn("PairMatchingCut: Get_CDA_FromCalculation(): exceeded max_iter="); return false; } } else { gsl_min_fminimizer_free(s); Log->warn("PairMatchingCut: Get_CDA_FromCalculation(); failure from gsl_min_test_interval(): status="); return false; } } // while(1) minimize gsl_min_fminimizer_free(s); } // for(brackets) // cout<<" In Get_CDA_FromCalculation 5 Alldist size ="<<Alldist.size()<<endl; //------------------------------------------------------------------// // The CDA is the minimum of all the distances of approach // //------------------------------------------------------------------// int MinIndex = -1; cda = 500.; z = 1000.; iterations = 0; // cout<<" In Get_CDA_FromCalculation 6 cda = "<<cda<<endl; for (int i = 0; i < Alldist.size(); i++) { // cout<<" In Get_CDA_FromCalculation 6.1 AllDist[0] = "<<Alldist[0]<<endl; if ( Alldist[i] < cda ) { MinIndex = i; cda = Alldist[i]; // cout<<" In Get_CDA_FromCalculation 6.2 cda = "<<cda<<endl; } } if (MinIndex == -1) { Log->warn("PairMatchingCut: Get_CDA_FromCalculation(); The cda could not be found."); cda = 500; // Safer with a large number since we cut on the small cda. return false; } else { z = Allz[MinIndex]; iterations = Alliter[MinIndex]; } // cout<<" In Get_CDA_FromCalculation 7 cda = "<<cda<<endl; return true; }