ngx_int_t ngx_http_tfs_process_ms_ls_dir(ngx_http_tfs_t *t) { ngx_buf_t *b; ngx_int_t rc; ngx_chain_t *cl, **ll; ngx_http_tfs_ms_ls_response_t *fake_rsp; ngx_http_tfs_peer_connection_t *tps; ngx_http_tfs_peer_connection_t *tp; ngx_http_tfs_custom_meta_info_t *meta_info; tp = t->tfs_peer; b = &tp->body_buffer; tps = t->tfs_peer_servers; if (t->length != ngx_buf_size(b) && b->last != b->end) { return NGX_AGAIN; } rc = ngx_http_tfs_meta_server_parse_message(t); if (rc == NGX_ERROR) { return NGX_ERROR; } /* need update meta table */ if (rc == NGX_HTTP_TFS_EXIT_LEASE_EXPIRED || rc == NGX_HTTP_TFS_EXIT_TABLE_VERSION_ERROR) { t->state = NGX_HTTP_TFS_STATE_ACTION_GET_META_TABLE; ngx_http_tfs_clear_buf(b); ngx_http_tfs_peer_set_addr(t->pool, &tps[NGX_HTTP_TFS_ROOT_SERVER], (ngx_http_tfs_inet_t *) &t->loc_conf->meta_root_server); ngx_log_error(NGX_LOG_DEBUG, t->log, 0, "need update meta table, rc: %i", rc); return NGX_OK; } if (rc == NGX_OK) { if (t->length == 0) { if (!t->r_ctx.chk_exist) { if (t->file.still_have) { ngx_http_tfs_clear_buf(b); return NGX_OK; } if (t->meta_info.file_count > 0) { /* need json output */ for (cl = t->out_bufs, ll = &t->out_bufs; cl; cl = cl->next) { ll = &cl->next; } cl = ngx_http_tfs_json_custom_file_info(t->json_output, &t->meta_info, t->r_ctx.file_type); if (cl == NULL) { return NGX_ERROR; } *ll = cl; } } t->state = NGX_HTTP_TFS_STATE_ACTION_DONE; return NGX_DONE; } /* t->length > 0 */ /* find current meta_info */ for(meta_info = &t->meta_info; meta_info->next; meta_info = meta_info->next); if (meta_info->rest_file_count > 0) { /* fake next ls_dir response head */ fake_rsp = (ngx_http_tfs_ms_ls_response_t *) b->start; fake_rsp->still_have = 1; fake_rsp->count = meta_info->rest_file_count; b->last = ngx_movemem(b->start + sizeof(ngx_http_tfs_ms_ls_response_t), b->pos, ngx_buf_size(b)); b->pos = b->start; /* FIXME: fake len will be minus later, ugly */ t->length += ngx_buf_size(b); return NGX_AGAIN; } } return rc; }
static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx, ngx_uint_t flush) { u_char *p, c; ngx_str_t *m; ngx_int_t offset, start, next, end, len, rc; ngx_uint_t shift, i, j; ngx_http_sub_match_t *match; ngx_http_sub_tables_t *tables; ngx_http_sub_loc_conf_t *slcf; slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); tables = ctx->tables; match = ctx->matches->elts; offset = ctx->offset; end = ctx->buf->last - ctx->pos; if (ctx->once) { /* sets start and next to end */ offset = end + (ngx_int_t) tables->min_match_len - 1; goto again; } while (offset < end) { c = offset < 0 ? ctx->looked.data[ctx->looked.len + offset] : ctx->pos[offset]; c = ngx_tolower(c); shift = tables->shift[c]; if (shift > 0) { offset += shift; continue; } /* a potential match */ start = offset - (ngx_int_t) tables->min_match_len + 1; i = ngx_max((ngx_uint_t) tables->index[c], ctx->index); j = tables->index[c + 1]; while (i != j) { if (slcf->once && ctx->sub && ctx->sub[i].data) { goto next; } m = &match[i].match; rc = ngx_http_sub_match(ctx, start, m); if (rc == NGX_DECLINED) { goto next; } ctx->index = i; if (rc == NGX_AGAIN) { goto again; } ctx->offset = offset + (ngx_int_t) m->len; next = start + (ngx_int_t) m->len; end = ngx_max(next, 0); rc = NGX_OK; goto done; next: i++; } offset++; ctx->index = 0; } if (flush) { for ( ;; ) { start = offset - (ngx_int_t) tables->min_match_len + 1; if (start >= end) { break; } for (i = 0; i < ctx->matches->nelts; i++) { m = &match[i].match; if (ngx_http_sub_match(ctx, start, m) == NGX_AGAIN) { goto again; } } offset++; } } again: ctx->offset = offset; start = offset - (ngx_int_t) tables->min_match_len + 1; next = start; rc = NGX_AGAIN; done: /* send [ - looked.len, start ] to client */ ctx->saved.len = ctx->looked.len + ngx_min(start, 0); ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->saved.len); ctx->copy_start = ctx->pos; ctx->copy_end = ctx->pos + ngx_max(start, 0); /* save [ next, end ] in looked */ len = ngx_min(next, 0); p = ctx->looked.data; p = ngx_movemem(p, p + ctx->looked.len + len, - len); len = ngx_max(next, 0); p = ngx_cpymem(p, ctx->pos + len, end - len); ctx->looked.len = p - ctx->looked.data; /* update position */ ctx->pos += end; ctx->offset -= end; return rc; }