mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-01 07:13:56 +08:00
update 2026-09-24 16:56:26
This commit is contained in:
1 parent
b31a5c3878
commit
e4cee331e9
6885 files changed
+3240523
No files matched your search
@@ -0,0 +1,24 @@
|
||||
Copyright (C) 2016-2020, by Jie Wu "AlexWoo" <wj19840501@gmail.com>.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
ngx_addon_name=ngx_client_module
|
||||
|
||||
|
||||
CORE_MODULES="$CORE_MODULES \
|
||||
ngx_client_module \
|
||||
ngx_http_client_module \
|
||||
"
|
||||
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
|
||||
$ngx_addon_dir/ngx_client.c \
|
||||
$ngx_addon_dir/ngx_http_client.c \
|
||||
"
|
||||
|
||||
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
|
||||
$ngx_addon_dir/ngx_client.h \
|
||||
$ngx_addon_dir/ngx_http_client.h \
|
||||
"
|
||||
|
||||
CFLAGS="$CFLAGS -I $ngx_addon_dir"
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (C) AlexWoo(Wu Jie) wj19840501@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_CLIENT_H_INCLUDED_
|
||||
#define _NGX_CLIENT_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_event.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
typedef struct ngx_client_session_s ngx_client_session_t;
|
||||
|
||||
typedef void (* ngx_client_connect_pt)(ngx_client_session_t *s);
|
||||
typedef void (* ngx_client_recv_pt)(ngx_client_session_t *s);
|
||||
typedef void (* ngx_client_send_pt)(ngx_client_session_t *s);
|
||||
typedef void (* ngx_client_closed_pt)(ngx_client_session_t *s);
|
||||
|
||||
|
||||
struct ngx_client_session_s {
|
||||
ngx_peer_connection_t peer;
|
||||
ngx_str_t server; /* server original address */
|
||||
in_port_t port; /* server port */
|
||||
|
||||
ngx_connection_t *connection;
|
||||
|
||||
ngx_pool_t *pool;
|
||||
ngx_log_t log;
|
||||
|
||||
void *data; /* save ctx for callback */
|
||||
|
||||
ngx_chain_t *out; /* save data unsend */
|
||||
|
||||
/* configured part */
|
||||
|
||||
/* timer for connecting to server */
|
||||
ngx_msec_t connect_timeout;
|
||||
|
||||
/* timer for sending buffer full */
|
||||
ngx_msec_t send_timeout;
|
||||
|
||||
/*
|
||||
* data will be postponed until nginx has at least
|
||||
* postpone_output bytes of data to send
|
||||
*/
|
||||
size_t postpone_output;
|
||||
|
||||
/* use dynamic resolver mechanism for resolving domain */
|
||||
unsigned dynamic_resolver:1;
|
||||
|
||||
unsigned tcp_nodelay:1; /* TCP_NODELAY */
|
||||
unsigned tcp_nopush:1; /* TCP_CORK */
|
||||
|
||||
/* runtime part */
|
||||
|
||||
size_t recv; /* client recv bytes */
|
||||
|
||||
unsigned connected:1; /* client connected to server */
|
||||
unsigned closed:1; /* client has been closed */
|
||||
|
||||
ngx_event_t close; /* for async close */
|
||||
|
||||
/* callback */
|
||||
|
||||
ngx_client_connect_pt client_connected; /* connect successd */
|
||||
ngx_client_recv_pt client_recv; /* recv msg from peer */
|
||||
ngx_client_send_pt client_send; /* send msg to peer */
|
||||
ngx_client_closed_pt client_closed; /* finalize connection */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* create a client session
|
||||
*
|
||||
* return value:
|
||||
* return client session for successd, return NULL for failed
|
||||
* paras:
|
||||
* peer: server address and port, address could be domain or ip
|
||||
* local: set if need to bind local address, or set NULL
|
||||
* udp: set 1, use udp, set 0, use tcp
|
||||
* log: for logging error when create client session failed
|
||||
*/
|
||||
ngx_client_session_t *ngx_client_create(ngx_str_t *peer, ngx_str_t *local,
|
||||
ngx_flag_t udp, ngx_log_t *log);
|
||||
|
||||
|
||||
/*
|
||||
* connect to client server, should use client session created by
|
||||
* ngx_client_create. before connect to server, user can set paras in
|
||||
* configured part.
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
* paras:
|
||||
* s: client session created by ngx_client_create
|
||||
*/
|
||||
void ngx_client_connect(ngx_client_session_t *s);
|
||||
|
||||
|
||||
/*
|
||||
* send data to server
|
||||
*
|
||||
* return value:
|
||||
* NGX_ERROR: write error, client session will be closed
|
||||
* NGX_AGAIN: data not sent completely, it will save in client session out
|
||||
* NGX_OK: data sent completely
|
||||
* paras:
|
||||
* s: client session
|
||||
* out: data for sending
|
||||
*/
|
||||
ngx_int_t ngx_client_write(ngx_client_session_t *s, ngx_chain_t *out);
|
||||
|
||||
|
||||
/*
|
||||
* read data from server
|
||||
*
|
||||
* return value:
|
||||
* NGX_ERROR: read error, client session will be closed
|
||||
* NGX_DECLINED: buf for receiving data is full
|
||||
* NGX_AGAIN: no data for reading
|
||||
* 0: server closed
|
||||
* >0: bytes read into buffer
|
||||
* paras:
|
||||
* s: client session
|
||||
* b: buffer for receiving data
|
||||
*/
|
||||
ngx_int_t ngx_client_read(ngx_client_session_t *s, ngx_buf_t *b);
|
||||
|
||||
|
||||
/*
|
||||
* keepalive client connection, and destroy session
|
||||
* if use client connect the same ip:port,
|
||||
* new client session will reuse the connection
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
* paras:
|
||||
* s: client session
|
||||
*/
|
||||
void ngx_client_set_keepalive(ngx_client_session_t *s);
|
||||
|
||||
|
||||
/*
|
||||
* close client session
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
* paras:
|
||||
* s: client session
|
||||
*/
|
||||
void ngx_client_close(ngx_client_session_t *s);
|
||||
|
||||
|
||||
/*
|
||||
* paras:
|
||||
* r: http request to query status of client
|
||||
*/
|
||||
ngx_chain_t *ngx_client_state(ngx_http_request_t *r, unsigned detail);
|
||||
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (C) AlexWoo(Wu Jie) wj19840501@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_HTTP_CLIENT_H_INCLUDE_
|
||||
#define _NGX_HTTP_CLIENT_H_INCLUDE_
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
#include "ngx_client.h"
|
||||
#include "ngx_toolkit_misc.h"
|
||||
|
||||
|
||||
// http client method
|
||||
#define NGX_HTTP_CLIENT_GET 0
|
||||
#define NGX_HTTP_CLIENT_HEAD 1
|
||||
#define NGX_HTTP_CLIENT_POST 2
|
||||
#define NGX_HTTP_CLIENT_PUT 3
|
||||
#define NGX_HTTP_CLIENT_DELETE 4
|
||||
#define NGX_HTTP_CLIENT_MKCOL 5
|
||||
#define NGX_HTTP_CLIENT_COPY 6
|
||||
#define NGX_HTTP_CLIENT_MOVE 7
|
||||
#define NGX_HTTP_CLIENT_OPTIONS 8
|
||||
#define NGX_HTTP_CLIENT_PROPFIND 9
|
||||
#define NGX_HTTP_CLIENT_PROPPATCH 10
|
||||
#define NGX_HTTP_CLIENT_LOCK 11
|
||||
#define NGX_HTTP_CLIENT_UNLOCK 12
|
||||
#define NGX_HTTP_CLIENT_PATCH 13
|
||||
#define NGX_HTTP_CLIENT_TRACE 14
|
||||
|
||||
// http client version
|
||||
#define NGX_HTTP_CLIENT_VERSION_9 0
|
||||
#define NGX_HTTP_CLIENT_VERSION_10 1
|
||||
#define NGX_HTTP_CLIENT_VERSION_11 2
|
||||
#define NGX_HTTP_CLIENT_VERSION_20 3
|
||||
|
||||
// http client opt
|
||||
#define NGX_HTTP_CLIENT_OPT_CONNECT_TIMEOUT 0
|
||||
#define NGX_HTTP_CLIENT_OPT_SEND_TIMEOUT 1
|
||||
#define NGX_HTTP_CLIENT_OPT_POSTPONE_OUTPUT 2
|
||||
#define NGX_HTTP_CLIENT_OPT_DYNAMIC_RESOLVER 3
|
||||
#define NGX_HTTP_CLIENT_OPT_TCP_NODELAY 4
|
||||
#define NGX_HTTP_CLIENT_OPT_TCP_NOPUSH 5
|
||||
#define NGX_HTTP_CLIENT_OPT_HEADER_TIMEOUT 6
|
||||
|
||||
|
||||
typedef void (* ngx_http_client_handler_pt)(void *r, ngx_http_request_t *hcr);
|
||||
|
||||
|
||||
/* create and set http request */
|
||||
|
||||
/*
|
||||
* create a http request for sending to server
|
||||
*
|
||||
* return value:
|
||||
* return http request for successd, return NULL for failed
|
||||
*
|
||||
* paras:
|
||||
* log: error in create will use this log
|
||||
* method: http client method
|
||||
* url: full request url like "http://test.com/index.html?hello=world"
|
||||
* headers: http request header for sending
|
||||
* send_body: callback for sending body
|
||||
* request: who send http request
|
||||
*/
|
||||
ngx_http_request_t *ngx_http_client_create(ngx_log_t *log,
|
||||
ngx_uint_t method, ngx_str_t *url, ngx_keyval_t *headers,
|
||||
ngx_http_client_handler_pt send_body, void *request);
|
||||
|
||||
/*
|
||||
* add cleanup as ngx_http_cleanup_add
|
||||
*/
|
||||
ngx_http_cleanup_t *ngx_http_client_cleanup_add(ngx_http_request_t *r,
|
||||
size_t size);
|
||||
|
||||
/*
|
||||
* set read handler for http client, should set before send request,
|
||||
* otherwise body from server will discard
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
* read_handler: handler for setting
|
||||
*/
|
||||
void ngx_http_client_set_read_handler(ngx_http_request_t *r,
|
||||
ngx_http_client_handler_pt read_handler);
|
||||
|
||||
/*
|
||||
* set http headers
|
||||
*
|
||||
* return value:
|
||||
* NGX_OK for successd, NGX_ERROR for failed
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
* headers: headers set into r
|
||||
* if value is not null, will set or modify the header
|
||||
* if value is null string, will delete the header
|
||||
*/
|
||||
ngx_int_t ngx_http_client_set_headers(ngx_http_request_t *r,
|
||||
ngx_keyval_t *headers);
|
||||
|
||||
/*
|
||||
* set write handler for http client, if set,
|
||||
* will use this handler for sending body,
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
* write_handler: handler for setting
|
||||
*/
|
||||
void ngx_http_client_set_write_handler(ngx_http_request_t *r,
|
||||
ngx_http_client_handler_pt write_handler);
|
||||
|
||||
/*
|
||||
* set write handler for http client, if set,
|
||||
* will use this handler for sending body,
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
* write_handler: handler for setting
|
||||
*/
|
||||
void ngx_http_client_set_version(ngx_http_request_t *r, ngx_uint_t version);
|
||||
|
||||
/*
|
||||
* set http client option
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
* opt: http client opt
|
||||
* NGX_HTTP_CLIENT_OPT_CONNECT_TIMEOUT:
|
||||
* connect server timer
|
||||
* NGX_HTTP_CLIENT_OPT_SEND_TIMEOUT:
|
||||
* send data timer when buffer full
|
||||
* NGX_HTTP_CLIENT_OPT_POSTPONE_OUTPUT:
|
||||
* size threshold to send
|
||||
* NGX_HTTP_CLIENT_OPT_DYNAMIC_RESOLVER:
|
||||
* whether use dynamic resolver to resolv domain
|
||||
* NGX_HTTP_CLIENT_OPT_TCP_NODELAY:
|
||||
* whether set TCP_NODELAY
|
||||
* NGX_HTTP_CLIENT_OPT_TCP_NOPUSH:
|
||||
* whether set TCP_CORK
|
||||
* NGX_HTTP_CLIENT_OPT_HEADER_TIMEOUT:
|
||||
* timer for waiting response header from server
|
||||
* value: http client opt value want to set
|
||||
*/
|
||||
void ngx_http_client_setopt(ngx_http_request_t *r, unsigned opt,
|
||||
ngx_uint_t value);
|
||||
|
||||
/* send http request */
|
||||
|
||||
/*
|
||||
* send http request
|
||||
*
|
||||
* return value:
|
||||
* NGX_OK for successd, NGX_ERROR for failed
|
||||
*
|
||||
* paras:
|
||||
* r: http request for seding, create by ngx_http_client_create
|
||||
*/
|
||||
ngx_int_t ngx_http_client_send(ngx_http_request_t *r);
|
||||
|
||||
/*
|
||||
* create and send http GET request to server
|
||||
*
|
||||
* return value:
|
||||
* return http request for successd, return NULL for failed
|
||||
*
|
||||
* paras:
|
||||
* log: error in create will use this log
|
||||
* url: full request url like "http://test.com/index.html?hello=world"
|
||||
* headers: http request header for sending
|
||||
* request: who send http request
|
||||
*/
|
||||
ngx_http_request_t *ngx_http_client_get(ngx_log_t *log, ngx_str_t *url,
|
||||
ngx_keyval_t *headers, void *request);
|
||||
|
||||
/*
|
||||
* create and send http HEAD request to server
|
||||
*
|
||||
* return value:
|
||||
* return http request for successd, return NULL for failed
|
||||
*
|
||||
* paras:
|
||||
* log: error in create will use this log
|
||||
* url: full request url like "http://test.com/index.html?hello=world"
|
||||
* headers: http request header for sending
|
||||
* request: who send http request
|
||||
*/
|
||||
ngx_http_request_t *ngx_http_client_head(ngx_log_t *log, ngx_str_t *url,
|
||||
ngx_keyval_t *headers, void *request);
|
||||
|
||||
/*
|
||||
* create and send http POST request to server
|
||||
*
|
||||
* return value:
|
||||
* return http request for successd, return NULL for failed
|
||||
*
|
||||
* paras:
|
||||
* log: error in create will use this log
|
||||
* url: full request url like "http://test.com/index.html?hello=world"
|
||||
* headers: http request header for sending
|
||||
* send_body: callback for sending body
|
||||
* request: who send http request
|
||||
*/
|
||||
ngx_http_request_t *ngx_http_client_post(ngx_log_t *log, ngx_str_t *url,
|
||||
ngx_keyval_t *headers, ngx_http_client_handler_pt send_body, void *request);
|
||||
|
||||
|
||||
/* get response */
|
||||
|
||||
/*
|
||||
* get http response version
|
||||
*
|
||||
* return value:
|
||||
* http response version
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
*/
|
||||
ngx_uint_t ngx_http_client_http_version(ngx_http_request_t *r);
|
||||
|
||||
/*
|
||||
* get http response status code
|
||||
*
|
||||
* return value:
|
||||
* http response status code like 200, 500
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
*/
|
||||
ngx_uint_t ngx_http_client_status_code(ngx_http_request_t *r);
|
||||
|
||||
/*
|
||||
* get http response header's value
|
||||
*
|
||||
* return value:
|
||||
* http response header's value
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
* key: http header like "Host", "Content-Type"
|
||||
*/
|
||||
ngx_str_t *ngx_http_client_header_in(ngx_http_request_t *r, ngx_str_t *key);
|
||||
|
||||
/*
|
||||
* read http response body
|
||||
*
|
||||
* return value:
|
||||
* NGX_AGAIN: read part of data
|
||||
* 0: tcp connection disconnect, need finalize request with 1
|
||||
* NGX_ERROR: tcp connection error disconnect, need finalize request with 1
|
||||
* NGX_DONE: response body has been read, could finalize request with 0
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
* in: where read data put
|
||||
*/
|
||||
ngx_int_t ngx_http_client_read_body(ngx_http_request_t *r, ngx_chain_t **in);
|
||||
|
||||
/*
|
||||
* get receive bytes
|
||||
*
|
||||
* return value:
|
||||
* bytes receive from server
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
*/
|
||||
off_t ngx_http_client_rbytes(ngx_http_request_t *r);
|
||||
|
||||
/*
|
||||
* get send bytes
|
||||
*
|
||||
* return value:
|
||||
* bytes send to server
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
*/
|
||||
off_t ngx_http_client_wbytes(ngx_http_request_t *r);
|
||||
|
||||
|
||||
/* end request */
|
||||
|
||||
/*
|
||||
* detach http client request with it's creator,
|
||||
* all read and write handler will not be triggered
|
||||
*
|
||||
* return value:
|
||||
* bytes send to server
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
*/
|
||||
void ngx_http_client_detach(ngx_http_request_t *r);
|
||||
|
||||
/*
|
||||
* finalize http client request
|
||||
*
|
||||
* return value:
|
||||
* void
|
||||
*
|
||||
* paras:
|
||||
* r: http client request
|
||||
* closed: set to 1, will close connection to server
|
||||
* set to 0, will keep connection to server alive
|
||||
*/
|
||||
void ngx_http_client_finalize_request(ngx_http_request_t *r, ngx_flag_t closed);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
ngx_addon_name=ngx_client_test_module
|
||||
|
||||
HTTP_MODULES="$HTTP_MODULES \
|
||||
ngx_client_test_module \
|
||||
ngx_http_client_test_module \
|
||||
ngx_client_stat_module \
|
||||
"
|
||||
|
||||
NGX_ADDON_SRCS="$NGX_ADDON_SRCS
|
||||
$ngx_addon_dir/ngx_client_test_module.c \
|
||||
$ngx_addon_dir/ngx_http_client_test_module.c \
|
||||
$ngx_addon_dir/ngx_client_stat_module.c \
|
||||
"
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
user root;
|
||||
worker_processes 4;
|
||||
|
||||
#error_log logs/error.log;
|
||||
#error_log logs/error.log notice;
|
||||
error_log logs/error.log info;
|
||||
|
||||
#pid logs/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
resolver 192.168.84.254;
|
||||
dynamic_refresh_interval 5m;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
# '$status $body_bytes_sent "$http_referer" '
|
||||
# '"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
#access_log logs/access.log main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
#keepalive_timeout 0;
|
||||
keepalive_timeout 65;
|
||||
|
||||
#gzip on;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
root html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
location /client_test {
|
||||
client_test;
|
||||
}
|
||||
|
||||
location /http_client_test {
|
||||
http_client_test;
|
||||
}
|
||||
|
||||
location /client_stat {
|
||||
client_stat;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) AlexWoo(Wu Jie) wj19840501@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_event.h>
|
||||
#include <ngx_http.h>
|
||||
#include "ngx_client.h"
|
||||
#include "ngx_rbuf.h"
|
||||
#include "ngx_poold.h"
|
||||
#include "ngx_timerd.h"
|
||||
#include "ngx_event_timer_module.h"
|
||||
#include "ngx_event_resolver.h"
|
||||
#include "ngx_dynamic_resolver.h"
|
||||
|
||||
|
||||
static char *ngx_client_stat(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_client_stat_commands[] = {
|
||||
|
||||
{ ngx_string("client_stat"),
|
||||
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
|
||||
ngx_client_stat,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_module_t ngx_client_stat_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
||||
NULL, /* create location configuration */
|
||||
NULL /* merge location configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_client_stat_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_client_stat_module_ctx, /* module context */
|
||||
ngx_client_stat_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_client_stat_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_chain_t **ll, *out;
|
||||
ngx_buf_t *b;
|
||||
size_t len;
|
||||
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
ngx_http_send_header(r);
|
||||
|
||||
ll = &out;
|
||||
|
||||
len = sizeof("--------------------------------------------------\n") - 1
|
||||
+ sizeof("ngx_worker: ngx_process_slot: pid: \n") - 1
|
||||
+ 3 * NGX_OFF_T_LEN;
|
||||
|
||||
*ll = ngx_alloc_chain_link(r->pool);
|
||||
if (*ll == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
(*ll)->next = NULL;
|
||||
|
||||
b = ngx_create_temp_buf(r->pool, len);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
(*ll)->buf = b;
|
||||
|
||||
b->last = ngx_snprintf(b->last, len,
|
||||
"--------------------------------------------------\n"
|
||||
"ngx_worker: %i ngx_process_slot: %i pid: %i\n",
|
||||
ngx_worker, ngx_process_slot, ngx_pid);
|
||||
|
||||
if (*ll) {
|
||||
ll = &(*ll)->next;
|
||||
}
|
||||
*ll = ngx_rbuf_state(r, 1);
|
||||
|
||||
if (*ll) {
|
||||
ll = &(*ll)->next;
|
||||
}
|
||||
*ll = ngx_event_timer_state(r);
|
||||
|
||||
if (*ll) {
|
||||
ll = &(*ll)->next;
|
||||
}
|
||||
*ll = ngx_event_resolver_state(r);
|
||||
|
||||
if (*ll) {
|
||||
ll = &(*ll)->next;
|
||||
}
|
||||
*ll = ngx_dynamic_resolver_state(r);
|
||||
|
||||
if (*ll) {
|
||||
ll = &(*ll)->next;
|
||||
}
|
||||
*ll = ngx_poold_state(r, 1);
|
||||
|
||||
if (*ll) {
|
||||
ll = &(*ll)->next;
|
||||
}
|
||||
*ll = ngx_timerd_state(r, 1);
|
||||
|
||||
if (*ll) {
|
||||
ll = &(*ll)->next;
|
||||
}
|
||||
*ll = ngx_client_state(r, 1);
|
||||
|
||||
(*ll)->buf->last_buf = 1;
|
||||
|
||||
return ngx_http_output_filter(r, out);
|
||||
}
|
||||
|
||||
static char *
|
||||
ngx_client_stat(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
|
||||
clcf->handler = ngx_client_stat_handler;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
#include "ngx_client.h"
|
||||
|
||||
|
||||
static char *ngx_client_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_client_test_commands[] = {
|
||||
|
||||
{ ngx_string("client_test"),
|
||||
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
|
||||
ngx_client_test,
|
||||
0,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_module_t ngx_client_test_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
||||
NULL, /* create location configuration */
|
||||
NULL /* merge location configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_client_test_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_client_test_module_ctx, /* module context */
|
||||
ngx_client_test_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
ngx_client_test_connected(ngx_client_session_t *s)
|
||||
{
|
||||
ngx_buf_t *b;
|
||||
size_t len;
|
||||
ngx_chain_t out;
|
||||
ngx_http_request_t *r;
|
||||
ngx_event_t *wev;
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, &s->log, 0, "client connected");
|
||||
|
||||
r = s->data;
|
||||
wev = s->peer.connection->write;
|
||||
|
||||
len = sizeof("nginx client test\n") - 1;
|
||||
b = ngx_create_temp_buf(s->pool, len);
|
||||
|
||||
if (b == NULL) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
b->last = ngx_copy(b->last, "nginx client test\n", len);
|
||||
b->last_buf = 1;
|
||||
|
||||
out.buf = b;
|
||||
out.next = NULL;
|
||||
|
||||
ngx_client_write(s, &out);
|
||||
|
||||
ngx_handle_write_event(wev, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ngx_client_test_recv(ngx_client_session_t *s)
|
||||
{
|
||||
ngx_buf_t *b;
|
||||
ngx_int_t n;
|
||||
ngx_connection_t *c;
|
||||
ngx_str_t recv;
|
||||
ngx_http_request_t *r;
|
||||
|
||||
c = s->peer.connection;
|
||||
r = s->data;
|
||||
|
||||
b = ngx_create_temp_buf(s->pool, 4096);
|
||||
if (b == NULL) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
n = c->recv(c, b->pos, b->end - b->last);
|
||||
if (n == NGX_AGAIN) {
|
||||
ngx_log_error(NGX_LOG_ERR, &s->log, 0, "client recv NGX_AGAIN");
|
||||
return;
|
||||
}
|
||||
|
||||
if (n == NGX_ERROR || n == 0) {
|
||||
ngx_log_error(NGX_LOG_ERR, &s->log, 0, "client recv NGX_ERROR");
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
ngx_client_close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
b->last += n;
|
||||
|
||||
recv.data = b->pos;
|
||||
recv.len = b->last - b->pos;
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, &s->log, 0, "client recv %d: %V, %z",
|
||||
n, &recv, recv.len);
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
|
||||
ngx_client_set_keepalive(s);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ngx_client_test_send(ngx_client_session_t *s)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, &s->log, 0, "client send");
|
||||
}
|
||||
|
||||
static void
|
||||
ngx_client_test_closed(ngx_client_session_t *s)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ERR, &s->log, 0, "client closed");
|
||||
}
|
||||
|
||||
static ngx_int_t
|
||||
ngx_client_test_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_client_session_t *s;
|
||||
ngx_str_t echo;
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "client test handler");
|
||||
|
||||
if (ngx_http_arg(r, (u_char *) "echo", sizeof("echo") - 1, &echo)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_HTTP_BAD_REQUEST;
|
||||
}
|
||||
|
||||
s = ngx_client_create(&echo, NULL, 0, r->connection->log);
|
||||
if (s == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
//ci->dynamic_resolver = 0;
|
||||
//ci->recvbuf = 4096;
|
||||
|
||||
s->client_connected = ngx_client_test_connected;
|
||||
s->client_recv = ngx_client_test_recv;
|
||||
s->client_send = ngx_client_test_send;
|
||||
s->client_closed = ngx_client_test_closed;
|
||||
s->data = r;
|
||||
|
||||
ngx_client_connect(s);
|
||||
|
||||
++r->count;
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_client_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
|
||||
clcf->handler = ngx_client_test_handler;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (C) AlexWoo(Wu Jie) wj19840501@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include "ngx_http_client.h"
|
||||
#include "ngx_rbuf.h"
|
||||
|
||||
|
||||
static char *ngx_http_client_test(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_client_test_commands[] = {
|
||||
|
||||
{ ngx_string("http_client_test"),
|
||||
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
|
||||
ngx_http_client_test,
|
||||
0,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_module_t ngx_http_client_test_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
||||
NULL, /* create location configuration */
|
||||
NULL /* merge location configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_http_client_test_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_client_test_module_ctx, /* module context */
|
||||
ngx_http_client_test_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_client_test_recv_body(void *request, ngx_http_request_t *hcr)
|
||||
{
|
||||
ngx_http_request_t *r;
|
||||
ngx_chain_t *cl = NULL;
|
||||
ngx_chain_t **ll;
|
||||
ngx_int_t rc;
|
||||
|
||||
r = request;
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"http client test recv body");
|
||||
|
||||
rc = ngx_http_client_read_body(hcr, &cl);
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"http client test recv body, rc %i %i, %O",
|
||||
rc, ngx_errno, ngx_http_client_rbytes(hcr));
|
||||
|
||||
if (rc == 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
for (ll = &cl; (*ll)->next; ll = &(*ll)->next);
|
||||
|
||||
(*ll)->buf->last_buf = 1;
|
||||
}
|
||||
|
||||
ngx_http_output_filter(r, cl);
|
||||
|
||||
ngx_http_run_posted_requests(r->connection);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"all body has been read");
|
||||
ngx_http_client_finalize_request(hcr, 0);
|
||||
}
|
||||
|
||||
done:
|
||||
ngx_http_finalize_request(r, NGX_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
ngx_http_client_test_recv(void *request, ngx_http_request_t *hcr)
|
||||
{
|
||||
ngx_http_request_t *r;
|
||||
static ngx_str_t content_type = ngx_string("Content-Type");
|
||||
static ngx_str_t connection = ngx_string("Connection");
|
||||
static ngx_str_t unknown = ngx_string("Unknown");
|
||||
ngx_str_t *ct, *con;
|
||||
|
||||
r = request;
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"http client test recv, connection: %p", hcr->connection);
|
||||
|
||||
r->headers_out.status = 200;
|
||||
|
||||
ngx_http_client_set_read_handler(hcr, ngx_http_client_test_recv_body);
|
||||
|
||||
ngx_http_send_header(r);
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"status_code: %ui http_version: %ui",
|
||||
ngx_http_client_status_code(hcr),
|
||||
ngx_http_client_http_version(hcr));
|
||||
|
||||
ct = ngx_http_client_header_in(hcr, &content_type);
|
||||
con = ngx_http_client_header_in(hcr, &connection);
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "Content-Type: %V", ct);
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "Connection: %V", con);
|
||||
|
||||
if (ngx_http_client_header_in(hcr, &unknown) == NULL) {
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "no header Unknown");
|
||||
}
|
||||
|
||||
ngx_http_client_test_recv_body(request, hcr);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_client_test_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_request_t *hcr;
|
||||
static ngx_str_t request_url = ngx_string("http://101.200.241.232/");
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"http client test handler");
|
||||
|
||||
// Default header Host, User-Agent, Connection(below HTTP/1.1), Accept, Date
|
||||
hcr = ngx_http_client_create(r->connection->log, NGX_HTTP_CLIENT_GET,
|
||||
&request_url, NULL, NULL, r);
|
||||
|
||||
// add Connection, delete Date, Modify Host, add new header
|
||||
ngx_str_t value;
|
||||
|
||||
value.data = (u_char *) "World";
|
||||
value.len = sizeof("World") - 1;
|
||||
|
||||
ngx_keyval_t headers[] = {
|
||||
{ ngx_string("Host"), ngx_string("www.test.com") },
|
||||
{ ngx_string("Connection"), ngx_string("upgrade") },
|
||||
{ ngx_string("Date"), ngx_null_string },
|
||||
{ ngx_string("Hello"), value },
|
||||
{ ngx_null_string, ngx_null_string } // must end with null str
|
||||
};
|
||||
ngx_http_client_set_headers(hcr, headers);
|
||||
|
||||
ngx_http_client_set_read_handler(hcr, ngx_http_client_test_recv);
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"http client test before send");
|
||||
|
||||
ngx_http_client_send(hcr);
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"http client test after send");
|
||||
|
||||
// ngx_http_client_detach(hcr);
|
||||
// return NGX_HTTP_FORBIDDEN;
|
||||
|
||||
++r->count;
|
||||
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_client_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
|
||||
clcf->handler = ngx_http_client_test_handler;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
func handleConnection(c net.Conn) {
|
||||
b := make([]byte, 4096)
|
||||
|
||||
for {
|
||||
n, err := c.Read(b)
|
||||
if err != nil {
|
||||
fmt.Print("Read Error ", err)
|
||||
c.Close()
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print("recv ", n, " data:", string(b))
|
||||
|
||||
c.Write(b[0:n])
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
ln, err := net.Listen("tcp", ":10000")
|
||||
if err != nil {
|
||||
fmt.Print("Listen Error ", err)
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
fmt.Print("Accept Error ", err)
|
||||
continue
|
||||
}
|
||||
|
||||
go handleConnection(conn)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user