Esempio n. 1
0
static int cwx_request(CWX_CONNECT* conn){
    char  szHead[CWINUX_MSG_HEAD_LEN + 1];
    CWX_MSG_HEADER_S msg_head;
    CWX_KEY_VALUE_ITEM_S item;
    CWX_KEY_VALUE*  key_value;
    CWX_UINT64 begin, end, now;
    char* pvalue;
    char* snd_buf=0;
    int buf_size = 0;
    int pos;
    int len;
    int ret;
    int http_code = OK;
    CWX_UINT32 delay = 0;

    pos = CWINUX_MSG_HEAD_LEN;
    buf_size = conn->m_args?strlen(conn->m_args)+ 2048:2048;
    snd_buf = (char*)apr_pcalloc(conn->m_request->pool, buf_size);
    //get ip
    pvalue = cwx_get_ip(conn->m_request);
    if (NULL == pvalue) pvalue="255.255.255.255";
    //append ip
    if (-1 == (len = cwx_append_key(snd_buf + pos, buf_size - pos, "cwinux_ip", pvalue, strlen(pvalue), false))){
        CWX_ERR(("%s:%d:cwx_request(): Failure to invoke cwx_append_key() to append cwinux_ip\n", __FILE__, __LINE__));
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    pos += len;
    //append url
    if (-1 == (len = cwx_append_key(snd_buf + pos, buf_size - pos, "cwinux_url", conn->m_request->uri, strlen(conn->m_request->uri), false))){
        CWX_ERR(("%s:%d:cwx_request(): Failure to invoke cwx_append_key() to append cwinux_url\n", __FILE__, __LINE__));
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    pos += len;

    key_value = conn->m_args_head;
    while(key_value){
        if ((strcmp(key_value->m_key, "cwinux_ip") != 0) && (strcmp(key_value->m_key, "cwinux_url") != 0)){
            //append arg
            if (-1 == (len = cwx_append_key(snd_buf + pos, buf_size - pos, key_value->m_key, key_value->m_value, strlen(key_value->m_value), false))){
                CWX_ERR(("%s:%d:cwx_request(): Failure to invoke cwx_append_key() to append arg key\n", __FILE__, __LINE__));
                return HTTP_INTERNAL_SERVER_ERROR;
            }
            pos += len;
        }
        key_value = key_value->m_next;
    }
    msg_head.m_ucAttr = 0;
    msg_head.m_ucVersion = 0;
    msg_head.m_uiDataLen = pos - CWINUX_MSG_HEAD_LEN;
    msg_head.m_uiTaskId = 0;
    msg_head.m_unMsgType = atoi(conn->m_msg_type);
    cwx_pack_head(&msg_head, snd_buf);

    //send msg
    begin = (CWX_UINT64)conn->m_request->request_time/1000;
    end = begin + conn->m_host->m_user_config.m_query_timeout;
    now = cwx_time_of_day()/1000;

    if (now >= end)  return HTTP_REQUEST_TIME_OUT;

    ret = cwx_stream_write(conn, snd_buf, pos, (CWX_UINT32)(end - now));
    if (-1 == ret){
        cwx_stream_close(conn->m_socket->m_fd);
        conn->m_socket->m_fd = -1;
        return HTTP_PRECONDITION_FAILED;
    }else if(0 == ret){
        cwx_stream_close(conn->m_socket->m_fd);
        conn->m_socket->m_fd = -1;
        return HTTP_REQUEST_TIME_OUT;
    }
    //recv msg in following

    //recv head first
    now = cwx_time_of_day()/1000;
    if (now >= end)  return HTTP_REQUEST_TIME_OUT;
    ret = cwx_stream_read(conn, szHead, CWINUX_MSG_HEAD_LEN, end - now);
    if (-1 == ret){
        cwx_stream_close(conn->m_socket->m_fd);
        conn->m_socket->m_fd = -1;
        return HTTP_BAD_REQUEST;
    }else if(0 == ret){
        cwx_stream_close(conn->m_socket->m_fd);
        conn->m_socket->m_fd = -1;
        return HTTP_REQUEST_TIME_OUT;
    }
    if (!cwx_unpack_head(szHead, &msg_head)){
        cwx_stream_close(conn->m_socket->m_fd);
        conn->m_socket->m_fd = -1;
        CWX_ERR(("%s:%d:cwx_request(): Failure to invoke cwx_unpack_head().\n", __FILE__, __LINE__));
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    if (msg_head.m_unMsgType != atoi(conn->m_msg_type) + 1){
        cwx_stream_close(conn->m_socket->m_fd);
        conn->m_socket->m_fd = -1;
        CWX_ERR(("%s:%d:cwx_request(): Reply msg type error. should be %d, but:%d. handle=%s, arg=%s\n",
            __FILE__,
            __LINE__,
            atoi(conn->m_msg_type) + 1,
            msg_head.m_unMsgType,
            conn->m_request->handler,
            conn->m_args?conn->m_args:""));
        return HTTP_INTERNAL_SERVER_ERROR;
    }
    //recv data
    char* recv_buf = (char*)apr_pcalloc(conn->m_request->pool, msg_head.m_uiDataLen);
    now = cwx_time_of_day()/1000;
    if (now >= end)  return HTTP_REQUEST_TIME_OUT;
    ret = cwx_stream_read(conn,
        recv_buf,
        msg_head.m_uiDataLen,
        end-now);
    if (-1 == ret){
        cwx_stream_close(conn->m_socket->m_fd);
        conn->m_socket->m_fd = -1;
        return HTTP_PRECONDITION_FAILED;
    }else if(0 == ret){
        cwx_stream_close(conn->m_socket->m_fd);
        conn->m_socket->m_fd = -1;
        return HTTP_REQUEST_TIME_OUT;
    }
    now = cwx_time_of_day()/1000;
    delay = now - (CWX_UINT64)conn->m_request->request_time/1000;
    if (1 != conn->m_host->m_user_config.m_show){
        //get code
        ret =  cwx_get_key_by_name(recv_buf, msg_head.m_uiDataLen, "code", &item);
        if (0>ret){
            CWX_ERR(("%s:%d:cwx_request(): handle=[%s] Failure to invoke cwx_get_key_by_name(\"code\").\n",
                __FILE__, __LINE__, conn->m_request->handler));
            return HTTP_INTERNAL_SERVER_ERROR;
        }else if (0 == ret){
            CWX_ERR(("%s:%d:cwx_request(): handle=[%s] no [code] key in reply package.\n",
                __FILE__, __LINE__, conn->m_request->handler));
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        ret = atoi(item.m_szData);
        if (0 > ret){
            http_code = HTTP_BAD_REQUEST;
        }else if (200 > ret){
            http_code = OK;
        }
        if (OK != http_code){
            CWX_ERR(("%s:%d:cwx_request(): handle=[%s] Query failure, code=%d.\n",
                __FILE__, __LINE__, conn->m_request->handler, ret));
        }
        //get content-type
        ret = cwx_get_key_by_name(recv_buf, msg_head.m_uiDataLen, "content-type", &item);
        if (ret>0){
            conn->m_request->content_type = item.m_szData;
        }
        //get content
        ret = cwx_get_key_by_name(recv_buf, msg_head.m_uiDataLen, "content", &item);
        if (0>ret){
            CWX_ERR(("%s:%d:cwx_request(): handle=[%s] Failure to invoke cwx_get_key_by_name(\"content\").\n",
                __FILE__, __LINE__, conn->m_request->handler));
            return HTTP_INTERNAL_SERVER_ERROR;
        }else if (0 == ret){
            CWX_ERR(("%s:%d:cwx_request(): handle=[%s] no [content] key in reply package.\n",
                __FILE__, __LINE__, conn->m_request->handler));
            return HTTP_INTERNAL_SERVER_ERROR;
        }
        cwx_output_header(conn, delay);
        ap_rwrite(item.m_szData, item.m_uiDataLen, conn->m_request);
        return http_code;
    }
    //show the package
    if (!cwx_is_valid_package(recv_buf, msg_head.m_uiDataLen)){
        cwx_output_header(conn, delay);
        ap_rwrite(recv_buf, msg_head.m_uiDataLen, conn->m_request);
        return http_code;
    }

    char* out_buf = (char*)apr_pcalloc(conn->m_request->pool, msg_head.m_uiDataLen * 2);
    CWX_UINT32 data_size = 0;
    len = 0;
    while(len < msg_head.m_uiDataLen){
        if (0>= cwx_get_key_by_index(recv_buf + len, msg_head.m_uiDataLen - len, 0, &item)) break;
        memcpy(out_buf +data_size, item.m_szKey, item.m_unKeyLen);
        data_size+=item.m_unKeyLen;
        memcpy(out_buf +data_size, "=", 1);
        data_size+=1;
        memcpy(out_buf +data_size, item.m_szData, item.m_uiDataLen);
        data_size+=item.m_uiDataLen;
        memcpy(out_buf +data_size, "\n", 1);
        data_size+=1;
        len += cwx_get_kv_len(item.m_unKeyLen, item.m_uiDataLen);
    }
    out_buf[data_size]=0x00;
    cwx_output_header(conn, delay);
    ap_rwrite(out_buf, data_size, conn->m_request);
    return http_code;
}
Esempio n. 2
0
static ngx_int_t ngx_http_cwinux_process_header(ngx_http_request_t *r)
{
    ngx_http_upstream_t       *u;
    ngx_http_cwinux_ctx_t  *ctx;
    ngx_http_cwinux_loc_conf_t       *mlcf;
    size_t     recv_data_len;
    size_t     left_data_len;
    size_t     copy_data_len;
    size_t len;
    int        http_code = 200;
    CWX_KEY_VALUE_ITEM_S item;
    int  ret;
    u = r->upstream;
    mlcf = ngx_http_get_module_loc_conf(r, ngx_http_cwinux_module);
    ctx = ngx_http_get_module_ctx(r, ngx_http_cwinux_module);
    if (!ctx->header){
        if (u->buffer.last - u->buffer.pos <CWINUX_MSG_HEAD_LEN){
            return NGX_AGAIN;
        }
        if (!cwx_unpack_head((char*)u->buffer.pos, &ctx->msg_head)){
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "service sent invalid header");
            return NGX_HTTP_UPSTREAM_INVALID_HEADER;
        }
        ctx->header = true;
        ctx->recv_pos = 0;
        ctx->data = ngx_palloc(r->pool, ctx->msg_head.m_uiDataLen);
        recv_data_len = u->buffer.last - u->buffer.pos - CWINUX_MSG_HEAD_LEN;
        left_data_len = ctx->msg_head.m_uiDataLen - ctx->recv_pos;
        copy_data_len = left_data_len > recv_data_len?recv_data_len:left_data_len;
        if (left_data_len && recv_data_len){
            memcpy(ctx->data + ctx->recv_pos, u->buffer.pos + CWINUX_MSG_HEAD_LEN, copy_data_len);
            ctx->recv_pos += copy_data_len;
        }
        u->buffer.last = 0;
        if (ctx->recv_pos < ctx->msg_head.m_uiDataLen) return NGX_AGAIN;
    }else{
        recv_data_len = u->buffer.last - u->buffer.pos;
        left_data_len = ctx->msg_head.m_uiDataLen - ctx->recv_pos;
        copy_data_len = left_data_len >recv_data_len?recv_data_len:left_data_len;
        memcpy(ctx->data + ctx->recv_pos, u->buffer.pos, copy_data_len);
        ctx->recv_pos += copy_data_len;
        u->buffer.last = 0;
        if (ctx->recv_pos < ctx->msg_head.m_uiDataLen) return NGX_AGAIN;
    }
    ctx->request->headers_out.content_type=mlcf->content_type;
    ctx->request->headers_out.content_type_len=mlcf->content_type.len;
    if (mlcf->show){
        //show the package
        if (!cwx_is_valid_package(ctx->data, ctx->msg_head.m_uiDataLen)){
            ctx->out_buf = ctx->data;
            ctx->out_buf_len = ctx->msg_head.m_uiDataLen;
        }else{
            ctx->out_buf = ngx_palloc(ctx->request->pool, ctx->msg_head.m_uiDataLen * 2);
            ctx->out_buf_len = 0;
            len = 0;
            while(len < ctx->msg_head.m_uiDataLen){
                if (0>= cwx_get_key_by_index(ctx->data + len, ctx->msg_head.m_uiDataLen - len, 0, &item)) break;
                memcpy(ctx->out_buf + ctx->out_buf_len, item.m_szKey, item.m_unKeyLen);
                ctx->out_buf_len+=item.m_unKeyLen;
                ctx->out_buf[ctx->out_buf_len++] = '\n';
                ctx->out_buf_len += sprintf(ctx->out_buf+ctx->out_buf_len, "%u\n", item.m_uiDataLen);
                memcpy(ctx->out_buf + ctx->out_buf_len, item.m_szData, item.m_uiDataLen);
                ctx->out_buf_len+=item.m_uiDataLen;
                ctx->out_buf[ctx->out_buf_len++] = '\n';
                len += cwx_get_kv_len(item.m_unKeyLen, item.m_uiDataLen);
            }
            ctx->out_buf[ctx->out_buf_len]=0x00;
        }
    }else{
        ctx->out_buf = " ";
        ctx->out_buf_len = 1;
        //get code
        ret =  cwx_get_key_by_name(ctx->data, ctx->msg_head.m_uiDataLen, "code", &item);
        if (0>ret){
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                " Failure to invoke cwx_get_key_by_name(code)");
            return NGX_HTTP_UPSTREAM_FT_INVALID_HEADER;
        }else if (0 == ret){
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                " no [code] key in reply package.");
            return NGX_HTTP_UPSTREAM_FT_INVALID_HEADER;
        }
        ret = atoi(item.m_szData);
        if (0 > ret){
            http_code = NGX_HTTP_BAD_REQUEST;
        }else if (200 > ret){
            http_code = NGX_HTTP_OK;
        }
        if (NGX_HTTP_OK != http_code){
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                " Query failure, code=%d.", ret);
        }
        //get content-type
        ret = cwx_get_key_by_name(ctx->data, ctx->msg_head.m_uiDataLen, "content-type", &item);
        if (ret>0){
            ctx->request->headers_out.content_type.data=ngx_palloc(ctx->request->pool,item.m_uiDataLen);
            memcpy(ctx->request->headers_out.content_type.data, item.m_szData, item.m_uiDataLen);
            ctx->request->headers_out.content_type.len=item.m_uiDataLen;
            ctx->request->headers_out.content_type_len=item.m_uiDataLen;
        }
        //get content
        ret = cwx_get_key_by_name(ctx->data, ctx->msg_head.m_uiDataLen, "content", &item);
        if (0>ret){
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                " Failure to invoke cwx_get_key_by_name(content)");
            return NGX_HTTP_UPSTREAM_FT_INVALID_HEADER;
        }else if (0 == ret){
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                " no [content] key in reply package.");
            return NGX_HTTP_UPSTREAM_FT_INVALID_HEADER;
        }
        ctx->out_buf = ngx_palloc(ctx->request->pool, item.m_uiDataLen);
        memcpy(ctx->out_buf, item.m_szData, item.m_uiDataLen);
        ctx->out_buf_len = item.m_uiDataLen;
    }
    if (mlcf->delay){
        struct timeval  tp;
        ngx_gettimeofday(&tp);
        size_t delay= (tp.tv_sec - ctx->start_time.tv_sec)*1000 + (tp.tv_usec - ctx->start_time.tv_usec)/1000;
        ngx_table_elt_t   *h;
        h = ngx_list_push(&u->headers_in.headers);
        if (h) {
            char szBuf[32];
            sprintf(szBuf, "%u", delay);
            h->key.len = strlen("cwinux_delay");
            h->key.data = (u_char*)"cwinux_delay";
            h->value.len = strlen(szBuf);
            h->value.data = ngx_palloc(ctx->request->pool, h->value.len + 1);
            strcpy((char*)h->value.data, szBuf);
            h->lowcase_key = h->key.data;
        }
    }

    r->headers_out.content_length_n = ctx->out_buf_len;
    r->headers_out.content_length_n = ctx->out_buf_len;
    u->headers_in.status_n = http_code;
    u->state->status = http_code;
    return NGX_OK;
}