Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}