zhqianwei 2011-08-01
ngx_tcc_module是一个nginx http模块,它把tcc编译器内嵌到nginx,用来编译C语言编写的网页后台脚本。
每个页面由两个文件组成:
*.csp,是主要用HTML编写的文件,里面会内嵌一些C代码。
*.c,纯C编写的代码文件,里面主要是做一些业务逻辑的处理。
下载:
https://github.com/downloads/hehaiqiang/ngwsx/ngx_tcc_module-20110720.rar
代码示例:
index.csp
<% /* This is a "c server page (CSP)" */ static int i; %> <html> <head> </head> <body> <% for (i = 0; i < 5; i++) { %> <a href="<%=url%>" target="_blank"><%=title%></a> <% } %> </body> </html>
index.c
#include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> #define NGX_DBD_OPT_NON_BLOCKING 0x01 static void row_handler(ngx_http_request_t *r); static void *dbd; static u_char *url = ""; static u_char *title = ""; static void finalize(ngx_http_request_t *r, ngx_int_t rc) { ngx_tcc_dbd_close(dbd); ngx_tcc_dbd_destroy(dbd); ngx_tcc_finalize(r, rc); } static void field_handler(ngx_http_request_t *r) { off_t offset; size_t size, total; u_char *value; ngx_int_t rc; for ( ;; ) { rc = ngx_tcc_dbd_field_read(dbd, &value, &offset, &size, &total); if (rc == NGX_AGAIN) { return; } if (rc == NGX_ERROR) { finalize(r, rc); return; } if (rc == NGX_DONE) { break; } /* TODO: value, offset, size, total */ ngx_tcc_output(r, value, size); ngx_tcc_output_str(r, " "); } ngx_tcc_output_str(r, "<br/>"); ngx_tcc_dbd_set_handler(dbd, row_handler, r); row_handler(r); } static void row_handler(ngx_http_request_t *r) { ngx_int_t rc; for ( ;; ) { rc = ngx_tcc_dbd_row_read(dbd); if (rc == NGX_AGAIN) { return; } if (rc == NGX_ERROR) { finalize(r, rc); return; } if (rc == NGX_DONE) { break; } ngx_tcc_dbd_set_handler(dbd, field_handler, r); field_handler(r); return; } url = "http://www.126.com/"; title = "126.com"; finalize(r, NGX_OK); } static void column_handler(ngx_http_request_t *r) { size_t size; u_char *buf; ngx_int_t rc; for ( ;; ) { rc = ngx_tcc_dbd_column_read(dbd); if (rc == NGX_AGAIN) { return; } if (rc == NGX_ERROR) { finalize(r, rc); return; } if (rc == NGX_DONE) { break; } buf = (u_char *) ngx_tcc_dbd_column_name(dbd); size = ngx_strlen(buf); ngx_tcc_output(r, buf, size); ngx_tcc_output_str(r, " "); } ngx_tcc_output_str(r, "<br/>"); ngx_tcc_dbd_set_handler(dbd, row_handler, r); row_handler(r); } static void result_handler(ngx_http_request_t *r) { ngx_int_t rc; rc = ngx_tcc_dbd_query(dbd); if (rc == NGX_AGAIN) { return; } if (rc == NGX_ERROR) { finalize(r, rc); return; } ngx_tcc_dbd_set_handler(dbd, column_handler, r); column_handler(r); } static void connect_handler(ngx_http_request_t *r) { ngx_int_t rc; rc = ngx_tcc_dbd_connect(dbd); if (rc == NGX_AGAIN) { return; } if (rc == NGX_ERROR) { ngx_tcc_dbd_destroy(dbd); ngx_tcc_finalize(r); return; } /* TODO: escape sql */ ngx_tcc_dbd_set_sql(dbd, "show databases", sizeof("show databases") - 1); ngx_tcc_dbd_set_handler(dbd, result_handler, r); result_handler(r); } __declspec(dllexport) void handler(ngx_http_request_t *r) { ngx_int_t rc; dbd = (void *) ngx_tcc_dbd_create(r, "libdrizzle"); ngx_tcc_dbd_set_options(dbd, NGX_DBD_OPT_NON_BLOCKING); ngx_tcc_dbd_set_tcp(dbd, "127.0.0.1", 3306); ngx_tcc_dbd_set_db(dbd, "mysql"); ngx_tcc_dbd_set_auth(dbd, "root", "123456"); ngx_tcc_dbd_set_handler(dbd, connect_handler, r); connect_handler(r); }