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; }
static ngx_int_t ngx_http_cwinux_create_request(ngx_http_request_t *r) { ngx_http_cwinux_ctx_t *ctx; ngx_http_cwinux_loc_conf_t *mlcf; ngx_str_t args; CWX_KEY_VALUE* keys; size_t buf_size; size_t pos=CWINUX_MSG_HEAD_LEN; int len; CWX_MSG_HEADER_S msg_head; ngx_buf_t *b; ngx_chain_t *cl; ngx_str_t* pargs = &args; if (r->method == NGX_HTTP_POST){ if (r->request_body && r->request_body->bufs){ if (r->request_body->bufs->next){ pargs = ngx_http_cwinux_merge_bufs(r->request_body->bufs, r->pool); }else{ args.data = r->request_body->bufs->buf->pos; args.len = r->request_body->bufs->buf->last - r->request_body->bufs->buf->pos; } } }else{ pargs = &r->args; } keys = ngx_http_cwinux_parse_args(pargs, r->pool); buf_size = pargs->len + 2048; b = ngx_create_temp_buf(r->pool, buf_size); if (b == NULL) { return NGX_ERROR; } //append ip if (-1 == (len = cwx_append_key((char*)b->pos + pos, buf_size - pos, "cwinux_ip", "0.0.0.0", strlen("0.0.0.0"), false))){ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failure to invoke cwx_append_key() to append cwinux_ip"); return NGX_ERROR; } pos += len; //append url if (-1 == (len = cwx_append_key((char*)b->pos + pos, buf_size - pos, "cwinux_url", (char*)r->uri.data, r->uri.len, false))){ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failure to invoke cwx_append_key() to append cwinux_url"); return NGX_ERROR; } pos += len; while(keys){ if ((strcmp(keys->m_key, "cwinux_ip") != 0) && (strcmp(keys->m_key, "cwinux_url") != 0)){ //append arg if (-1 == (len = cwx_append_key((char*)b->pos + pos, buf_size - pos, keys->m_key, keys->m_value, strlen(keys->m_value), false))){ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failure to invoke cwx_append_key() to append %s", keys->m_key); return NGX_ERROR; } pos += len; } keys = keys->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 = 1; cwx_pack_head(&msg_head, (char*)b->pos); b->last = b->pos + pos; mlcf = ngx_http_get_module_loc_conf(r, ngx_http_cwinux_module); ctx = ngx_http_get_module_ctx(r, ngx_http_cwinux_module); cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = b; cl->next = NULL; r->upstream->request_bufs = cl; return NGX_OK; }