Ejemplo n.º 1
0
u_char *
ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err)
{
    if (buf > last - 50) {

        /* leave a space for an error code */

        buf = last - 50;
        *buf++ = '.';
        *buf++ = '.';
        *buf++ = '.';
    }

#if (NGX_WIN32)
    buf = ngx_slprintf(buf, last, ((unsigned) err < 0x80000000)
                                       ? " (%d: " : " (%Xd: ", err);
#else
    buf = ngx_slprintf(buf, last, " (%d: ", err);
#endif

    buf = ngx_strerror(err, buf, last - buf);

    if (buf < last) {
        *buf++ = ')';
    }

    return buf;
}
static int
ngx_http_lua_socket_error_retval_handler(ngx_http_request_t *r,
    ngx_http_lua_socket_udp_upstream_t *u, lua_State *L)
{
    u_char           errstr[NGX_MAX_ERROR_STR];
    u_char          *p;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "lua udp socket error retval handler");

    if (u->ft_type & NGX_HTTP_LUA_SOCKET_FT_RESOLVER) {
        return 2;
    }

    lua_pushnil(L);

    if (u->ft_type & NGX_HTTP_LUA_SOCKET_FT_PARTIALWRITE) {
        lua_pushliteral(L, "partial write");

    } else if (u->ft_type & NGX_HTTP_LUA_SOCKET_FT_TIMEOUT) {
        lua_pushliteral(L, "timeout");

    } else if (u->ft_type & NGX_HTTP_LUA_SOCKET_FT_CLOSED) {
        lua_pushliteral(L, "closed");

    } else if (u->ft_type & NGX_HTTP_LUA_SOCKET_FT_BUFTOOSMALL) {
        lua_pushliteral(L, "buffer too small");

    } else if (u->ft_type & NGX_HTTP_LUA_SOCKET_FT_NOMEM) {
        lua_pushliteral(L, "out of memory");

    } else {

        if (u->socket_errno) {
#if (nginx_version >= 1000000)
            p = ngx_strerror(u->socket_errno, errstr, sizeof(errstr));
#else
            p = ngx_strerror_r(u->socket_errno, errstr, sizeof(errstr));
#endif
            /* for compatibility with LuaSocket */
            ngx_strlow(errstr, errstr, p - errstr);
            lua_pushlstring(L, (char *) errstr, p - errstr);

        } else {
            lua_pushliteral(L, "error");
        }
    }

    return 2;
}
static int
ngx_tcp_lua_req_error_retval_handler(ngx_tcp_session_t *s, lua_State *L)
{
    u_char                   errstr[NGX_MAX_ERROR_STR];
    u_char                  *p;
    ngx_tcp_lua_ctx_t       *ctx;

    ngx_log_debug0(NGX_LOG_DEBUG_TCP, s->connection->log, 0,
                   "lua socket error retval handler");

    //ngx_tcp_lua_socket_finalize(s, u);

    ctx = s->ctx;

    lua_pushnil(L);

    if (ctx->ft_type & NGX_TCP_LUA_REQ_FT_TIMEOUT) {
        lua_pushliteral(L, "timeout");

    } else if (ctx->ft_type & NGX_TCP_LUA_REQ_FT_CLOSED) {
        lua_pushliteral(L, "closed");

    } else if (ctx->ft_type & NGX_TCP_LUA_REQ_FT_NOMEM) {
        lua_pushliteral(L, "out of memory");

    } else {

        if (ctx->socket_errno) {

            p = ngx_strerror(ctx->socket_errno, errstr, sizeof(errstr));

            /* for compatibility with LuaSocket */
            ngx_strlow(errstr, errstr, p - errstr);
            lua_pushlstring(L, (char *) errstr, p - errstr);

        } else {
            lua_pushliteral(L, "error");
        }
    }

    return 2;
}
Ejemplo n.º 4
0
mrb_parser_state ngx_init_mruby_parser(ngx_str_t *source_filename, const ngx_log_t *log) {
    FILE            *source_file;
    char            *source;
    struct stat     source_file_stat;
    unsigned int    source_size; 

    struct mrb_parser_state *parser;

    if (source_filename == NULL) {
        ngx_log_error(NGX_LOG_CRIT, log, "mruby source filename is invalid");
        return NULL;
    }

    mrb_interpreter = mrb_open();

    if (mrb_interpreter == NULL) {
        ngx_log_error(NGX_LOG_CRIT, "could not allocate mruby interpreter");
        return NULL;
    }

    parser = mrb_parser_new(mrb_interpreter);

    stat(source_filename, &source_file_stat);

    if (source_file_stat == NULL) {
        ngx_log_error(NGX_LOG_CRIT, log, "mruby file '%s' does not exist.", source_filename);
        return NULL;
    }

    source_size = (source_file_stat.st_size * sizeof(char)) + 1;
    source      = calloc(source_size);

    if (source == NULL) {
        ngx_log_error(NGX_LOG_CRIT, log, "could not allocate memory for mruby source");
        return NULL;
    }

    source_file = fopen(source_filename, "r");
    fread(source, sizeof(char), source_file_stat.st_size, source_file);

    if (ferror(source_file)) {
        ngx_log_error(
            NGX_LOG_CRIT, 
            log, 
            "could not read mruby file '%s': %s", 
            source_filename, 
            ngx_strerror(ferror(source_file))
        );

        free(source);

        return NULL;
    } else {
        fclose(source_file);
    }

    parser->filename        = (char *)source_filename;
    parser->s               = source;
    parser->send            = source + strlen(source);
    parser->capture_errors  = 1;
    parser->lineno          = 1;

    return parser;
}
static ngx_int_t
ngx_http_store_plusplus_add_path(ngx_http_request_t *r, ngx_conhash_t *conhash, ngx_chain_t *out)
{
    ngx_str_t                            value;
    size_t                               len;
    ngx_int_t                            rc;
    ngx_buf_t                           *b;
    u_char                              *p, *path_name;
    ngx_file_info_t                      fi;
    ngx_err_t                            err;
    
    rc = ngx_http_arg(r, (u_char *) STORE_VALUE_STR, sizeof(STORE_VALUE_STR) - 1, &value);
    if (rc != NGX_OK) {
        return rc;
    }
    
    b = ngx_create_temp_buf(r->pool, 1024);
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    if (value.data[0] != '/') {
        b->last = ngx_sprintf(b->last, "ERROR: must be an absolute path." CRLF);
        rc = NGX_OK;
        goto done;
    }
    
    if (value.data[value.len - 1] == '/') {
        value.len--;
    }
    
    //  check whether the store path is existent.
    len = value.len + 1 + sizeof(NGX_STORE_PLUSPLUS_TMP_PATH) - 1;
    path_name = ngx_pcalloc(r->pool, len + 1);
    if (path_name == NULL) {
        return NGX_ERROR;
    }
    
    p = ngx_cpymem(path_name, value.data, value.len);
    *p = '\0';
    
    rc = ngx_file_info(path_name, &fi);
    if (rc == NGX_FILE_ERROR) {
        err = ngx_errno;
        b->last = ngx_strerror(err, b->last, b->end - b->last);
        *b->last++ = CR;
        *b->last++ = LF;
        rc = NGX_OK;
        goto done;
    }
    
    //  create temp_path in this store path
    p = ngx_cpymem(path_name, value.data, value.len);
    *p++ = '/';
    p = ngx_cpymem(p, NGX_STORE_PLUSPLUS_TMP_PATH, sizeof(NGX_STORE_PLUSPLUS_TMP_PATH) - 1);
    *p++ = '\0';

    if (ngx_create_dir(path_name, ngx_dir_access(NGX_FILE_OWNER_ACCESS)) 
        == NGX_FILE_ERROR) 
    {
        err = ngx_errno;
        if (err != NGX_EEXIST) {
            b->last = ngx_strerror(err, b->last, b->end - b->last);
            *b->last++ = CR;
            *b->last++ = LF;
            rc = NGX_OK;
            goto done;
        }
    }
    
    rc = ngx_conhash_add_node(conhash, value.data, value.len, NULL);
    if (rc == NGX_OK) {
        b->last = ngx_sprintf(b->last, "Add node successfully!" CRLF);
    }
    
    if (rc == NGX_DECLINED) {
        b->last = ngx_sprintf(b->last, "The node already exists!" CRLF);
        rc = NGX_OK;
    }
    
    if (rc == NGX_AGAIN) {
        b->last = ngx_sprintf(b->last, "The conhash space is not enough!" CRLF);
        rc = NGX_OK;
    }

done:
    b->last_buf = 1;
    out->buf = b;
    
    return rc;
}
static int
ngx_stream_lua_ngx_echo(lua_State *L, unsigned newline)
{
    ngx_stream_session_t        *s;
    ngx_stream_lua_ctx_t        *ctx;
    const char                  *p;
    size_t                       len;
    size_t                       size;
    ngx_buf_t                   *b;
    ngx_chain_t                 *cl;
    ngx_int_t                    rc;
    int                          i;
    int                          nargs;
    int                          type;
    ngx_err_t                    err;
    const char                  *msg;
    u_char                       errbuf[NGX_STREAM_LUA_MAX_ERROR_STR];

    s = ngx_stream_lua_get_session(L);
    if (s == NULL) {
        return luaL_error(L, "no session object 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);

#if 0
    if (ctx->acquired_raw_req_socket) {
        lua_pushnil(L);
        lua_pushliteral(L, "raw session socket acquired");
        return 2;
    }
#endif

    if (ctx->eof) {
        lua_pushnil(L);
        lua_pushliteral(L, "seen eof");
        return 2;
    }

    nargs = lua_gettop(L);
    size = 0;

    for (i = 1; i <= nargs; i++) {

        type = lua_type(L, i);

        switch (type) {
            case LUA_TNUMBER:
            case LUA_TSTRING:

                lua_tolstring(L, i, &len);
                size += len;
                break;

            case LUA_TNIL:

                size += sizeof("nil") - 1;
                break;

            case LUA_TBOOLEAN:

                if (lua_toboolean(L, i)) {
                    size += sizeof("true") - 1;

                } else {
                    size += sizeof("false") - 1;
                }

                break;

            case LUA_TTABLE:

                size += ngx_stream_lua_calc_strlen_in_table(L, i, i,
                                                            0 /* strict */);
                break;

            case LUA_TLIGHTUSERDATA:

                dd("userdata: %p", lua_touserdata(L, i));

                if (lua_touserdata(L, i) == NULL) {
                    size += sizeof("null") - 1;
                    break;
                }

                continue;

            default:

                msg = lua_pushfstring(L, "string, number, boolean, nil, "
                                      "ngx.null, or array table expected, "
                                      "but got %s", lua_typename(L, type));

                return luaL_argerror(L, i, msg);
        }
    }

    if (newline) {
        size += sizeof("\n") - 1;
    }

    if (size == 0) {
        /* do nothing for empty strings */
        lua_pushinteger(L, 1);
        return 1;
    }

    cl = ngx_stream_lua_chain_get_free_buf(s->connection->log,
                                           s->connection->pool,
                                           &ctx->free_bufs, size);

    if (cl == NULL) {
        return luaL_error(L, "no memory");
    }

    b = cl->buf;

    for (i = 1; i <= nargs; i++) {
        type = lua_type(L, i);
        switch (type) {
            case LUA_TNUMBER:
            case LUA_TSTRING:
                p = lua_tolstring(L, i, &len);
                b->last = ngx_copy(b->last, (u_char *) p, len);
                break;

            case LUA_TNIL:
                *b->last++ = 'n';
                *b->last++ = 'i';
                *b->last++ = 'l';
                break;

            case LUA_TBOOLEAN:
                if (lua_toboolean(L, i)) {
                    *b->last++ = 't';
                    *b->last++ = 'r';
                    *b->last++ = 'u';
                    *b->last++ = 'e';

                } else {
                    *b->last++ = 'f';
                    *b->last++ = 'a';
                    *b->last++ = 'l';
                    *b->last++ = 's';
                    *b->last++ = 'e';
                }

                break;

            case LUA_TTABLE:
                b->last = ngx_stream_lua_copy_str_in_table(L, i, b->last);
                break;

            case LUA_TLIGHTUSERDATA:
                *b->last++ = 'n';
                *b->last++ = 'u';
                *b->last++ = 'l';
                *b->last++ = 'l';
                break;

            default:
                return luaL_error(L, "impossible to reach here");
        }
    }

    if (newline) {
        *b->last++ = '\n';
    }

#if 0
    if (b->last != b->end) {
        return luaL_error(L, "buffer error: %p != %p", b->last, b->end);
    }
#endif

    ngx_log_debug0(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
                   newline ? "stream lua say response"
                           : "stream lua print response");

    ngx_set_errno(0);

    rc = ngx_stream_lua_send_chain_link(s, ctx, cl);

    if (rc == NGX_ERROR) {
        err = ngx_errno;

        lua_pushnil(L);

        if (err) {
            size = ngx_strerror(err, errbuf, sizeof(errbuf)) - errbuf;
            ngx_strlow(errbuf, errbuf, size);
            lua_pushlstring(L, (char *) errbuf, size);

        } else {
            lua_pushliteral(L, "unknown");
        }

        return 2;
    }

    dd("downstream write: %d, buf len: %d", (int) rc,
       (int) (b->last - b->pos));

    lua_pushinteger(L, 1);
    return 1;
}
    void
ngx_http_fsutil_code_common( ngx_http_script_engine_t *e )
{
    fsutil_code_t             *codeobj;
    ngx_http_variable_value_t *vv_src;
    ngx_http_variable_value_t *vv_dst;
    char                      *dst;
    char                      *src;
    ngx_int_t                  i;
    ngx_int_t                  rc;

    codeobj = ( fsutil_code_t* )e->ip;

    _x_getvar( src );
    _x_getvar( dst );

#   undef _x_getvar

#   define lg( fmt ... )                                                         \
    ngx_log_error(NGX_LOG_ERR, e->request->connection->log, 0, fmt );


    dst[ 0 ] = '/';
    for ( i = 1; i < vv_dst->len; i++ ) {

        if ( vv_dst->data[ i ] == '/' ) {

            dst[ i ] = 0;
            rc = ngx_http_fsutil_create_dir_if_not_found( e->request->connection->log, dst );

            if ( NGX_OK != rc ) {
                goto error_fserror_to_httpcode;
            }

        }

        dst[ i ] = vv_dst->data[ i ];
    }

    dst[ i ] = 0;

    ngx_memcpy( src, vv_src->data, vv_src->len );
    src[ vv_src->len ] = 0;

    /* lg( "src=%s dst=%s", src, dst ); */

    switch ( codeobj->op ) {

        case fsutil_op_mv :

            if ( fsutil_opt_onexist_override & codeobj->opt ) {
                /* lg( "to rename directly" ); */
                rc = ngx_rename_file( src, dst );
            }
            else {
                /*
                 * Rename does'nt support non-override operation. Thus we
                 * need to link to it first and then remove the original
                 * one
                 */

                /* lg( "link and unlink" ); */

                rc = link( src, dst );
                /* lg( "link rc=%d", rc ); */


                if ( NGX_OK == rc ) {
                    rc = unlink( src );
                    /* lg( "unlink rc=%d", rc ); */
                }
                else if ( NGX_EEXIST == ngx_errno ) {
                    if ( fsutil_opt_onexist_touch & codeobj->opt ) {
                        rc = utimes( dst, NULL );
                        /* lg( "utimes rc=%d", rc ); */
                    }
                    else {
                        rc = NGX_OK;
                    }
                }
            }
            break;

        case fsutil_op_ln :

            if ( fsutil_opt_onexist_override & codeobj->opt ) {

                while ( NGX_OK != (
                            rc = link( src, dst ) ) ) {

                    if ( NGX_EEXIST != ngx_errno ) {
                        break;
                    }

                    rc = unlink( dst );
                    if ( NGX_OK == rc || NGX_ENOENT == ngx_errno ) {
                        continue;
                    }
                    else {
                        /* other error which can not be handled */
                        break;
                    }
                }
            }
            else if ( fsutil_opt_onexist_touch & codeobj->opt ) {

                if ( NGX_OK != ( rc = link( src, dst ) ) ) {

                    if ( NGX_EEXIST == ngx_errno ) {
                        rc = utimes( dst, NULL );
                    }
                }

            }
            else {
                /* ignore */
                link( src, dst );
                rc = NGX_OK;
            }

            break;

        default:
            goto error_op_unsupported;
    }

    if ( 0 != rc ) {
        u_char errstr[ 1024 ];
        ngx_strerror( ngx_errno, errstr, 1024 );

        ngx_log_error(NGX_LOG_ERR, e->request->connection->log, 0,
                "%V failed. src=%s dst=%s, err=%d %s", &opnames[ codeobj->op ], src, dst, ngx_errno, errstr );
        goto error_op_failed;
    }

    e->ip += sizeof(fsutil_code_t);
    return;

error_op_unsupported:
error_var_not_found:
    e->status = NGX_HTTP_BAD_REQUEST;
    e->ip += sizeof(fsutil_code_t) - sizeof(uintptr_t);
    return;

error_op_failed:
error_fserror_to_httpcode:
    switch ( rc ) {
        case NGX_ENOTDIR :
            e->status = NGX_HTTP_CONFLICT;
            break;
        default:
            e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    e->ip += sizeof(fsutil_code_t) - sizeof(uintptr_t);
    return;

error_500:
    e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
    e->ip += sizeof(fsutil_code_t) - sizeof(uintptr_t);
    return;
}