HSCGI – 一个 SCGI 服务器

最新状态
还在构想当中,还没有实现。

代码仓库
http://git.heiher.info/hscgi.git

CGI 协议
http://en.wikipedia.org/wiki/Common_Gateway_Interface

SCGI 协议
http://en.wikipedia.org/wiki/Simple_Common_Gateway_Interface
http://www.python.ca/scgi/protocol.txt

HSCGI 服务器
HSCGI 是 SCGI 服务器的一个实现,它定义了模块接口类,用户通过编写其模块实现具体的功能。HSCGI 的模块分为两种类型 Handler 和 Filter 。

Handler 模块
这种类型的模块用于实现具体的处理功能,它定义了两个操作接口:
check : 检查当前的 Request 是否应该处理。
dispatch : 处理当前的 Request,生成 Response。

Filter 模块
这种类型的模块用于处理 Handler 模块生成的 Response,它定义了两个操作接口:
check : 检查当前的 Response 是否应该处理。
dispatch : 处理当前的 Response。

架构图

未解决问题
1. 高效的异步I/O。
2. 基于流的数据处理。
3. Request 缓冲区太大。
4. Inet Socket 鉴权。

Over!

GObject 初始化可失败类的派生类模板

此模板派生于 GObject 类,并实现了 GInitableIface 接口,其函数调用序列如下

** (process:1755): DEBUG: hev_iobj_new
** (process:1755): DEBUG: hev_iobj_class_init // 只有首次实例化被调用
** (process:1755): DEBUG: hev_iobj_initable_iface_init // 只有首次实例化被调用
** (process:1755): DEBUG: hev_iobj_constructor
** (process:1755): DEBUG: hev_iobj_init
** (process:1755): DEBUG: hev_iobj_constructed
** (process:1755): DEBUG: hev_iobj_initable_init
** (process:1755): DEBUG: hev_iobj_dispose
** (process:1755): DEBUG: hev_iobj_finalize

无论其初始化是否成功,其函数调用都是如上,当初始化失败(hev_iobj_initable_init 函数返回 FALSE),hev_iobj_new 函数返回 NULL,并设置参数 error。调用者通过其 error 参数判断错误类型。

源代码下载

编译

gcc -o hev-test hev-test.c hev-iobj.c `pkg-config --cflags --libs gio-2.0`

Over!

映射 Socket 到 Standard IO

演示一下 Unix 系统的 C 程序中如何将 Socket 映射到标准IO。

/* sock2stdio.c
 * Heiher <admin@heiher.info>
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
 
int main(int argc, char * argv[])
{
	int sock, client, addrlen;
	struct sockaddr_in this_addr, peer_addr;
	unsigned short port = 9000;
	pid_t cpid;
 
	addrlen = sizeof(struct sockaddr_in);
	memset(&this_addr, 0, addrlen);
	memset(&peer_addr, 0, addrlen);
 
	this_addr.sin_port = htons(port);
	this_addr.sin_family = AF_INET;
	this_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	bind(sock, (struct sockaddr*)&this_addr, addrlen);
	listen(sock, 5);
 
	while(-1 != (client=accept(sock, (struct sockaddr*)&peer_addr, &addrlen)))
	{
		cpid = fork();
		if(0 > cpid)
		{
			perror("fork() failed!");
 
			return 1;
		}
		else if(0 == cpid)	/* child */
		{
			close(0);
			close(1);
			close(2);
			dup2(client, 0);
			dup2(client, 1);
			dup2(client, 2);
			close(client);
 
			execl("/bin/dd", "/bin/dd", "bs=1", NULL);
 
			return 0;
		}
	}
 
	return 0;
}
gcc -o sock2stdio sock2stdio.c
./sock2stdio
nc localhost 9000
hello  # Input
hello  # Output

Over!

Nginx 模块 HTTP OwnerMatch

我编写了一个 Nginx 模块 HTTP OwnerMatch 解决了 Nginx 虚拟主机间可通过链接型文件(硬链接和符号链接)跨站访问的问题。通过这个模块可以指定每个虚拟主机的每个 Location 可以或不可以访问的哪些用户的文件。

配置文件实例

location / {
          root   html;
          index  index.html index.htm;
          omallow heiher;  # 允许访问隶属于 heiher 的文件 
          omallow guest sftp;  # 允许访问隶属于 guest:sftp 的文件 
          omdeny all;         #  不允许访问其它任何文件
}

源代码仓库

git clone git://github.com/heiher/nginx.git

Over!

HevBrowser

HevBrowser 是一个 WebKit 内核的 Mini 浏览器,它可以在页面加载完成后执行用户指定的 js 脚本。

快捷键
Esc : 停止加载当前页面
F5 : 重新加载当前页面
F6 : 切换焦点到地址栏
F7 : 执行用户指定脚本
F8 : 显示结果输出窗口

更新日志
2010-08-16 : 增加字符编码支持
2010-08-15 : 0.0.1

代码仓库
http://git.heiher.info/hevbrowser.git

二进制程序
hevbrowser-0.0.1.tar.gz (用户名: guest 密码: guest*)

Over!

一个 SSL 客户端实例

源代码

/* ssl-test.c
 * Heiher <admin@heiher.info>
 */
 
#include <stdio.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
 
int main(int argc, char * argv[])
{
	BIO * bio = NULL;
	SSL * ssl = NULL;
	SSL_CTX * ctx = NULL;
	char buf[512];
	char * request = 
		"GET /sftp/ HTTP/1.1\r\n"
		"Host: www.heiher.info:443\r\n"
		"User-Agent: Mozilla/5.0 (X11; U; Linux mips64; en-US; rv:1.9.1.10)"
				" Gecko/20100623 Iceweasel/3.5.10 (like Firefox/3.5.10)\r\n"
		"Accept: text/html,application/xhtml+xml,application/xml;"
				"q=0.9,*/*;q=0.8\r\n"
		"Accept-Language: en-us,en;q=0.5\r\n"
		"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
		"Connection: close\r\n"
		"\r\n";
 
	/* ssl init */
	SSL_load_error_strings();
	ERR_load_BIO_strings();
	OpenSSL_add_all_algorithms();
 
	SSL_library_init();
 
	/* create ssl context */
	ctx = SSL_CTX_new(SSLv23_client_method());
	/* load the trust certificate store */
	if(!SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ssl/certs"))
	{
		printf("load certs failed!\r\n");
	}
	/* create the connection */
	bio = BIO_new_ssl_connect(ctx);
	/* set up the BIO object */
	BIO_get_ssl(bio, &ssl);
	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
 
	/* open a secure connection */
	BIO_set_conn_hostname(bio, "www.heiher.info:443");
	if(0 >= BIO_do_connect(bio))
	{
		printf("connect failed!\r\n");
		return -1;
	}
 
	if(X509_V_OK != SSL_get_verify_result(ssl))
	{
		/* print warning message */
	}
 
	/* send request message */
	if(0 >= BIO_write(bio, request, strlen(request)))
	{
		if(!BIO_should_retry(bio))
		{
			/* handle failed write here */
		}
		/* do something to handle the retry */
	}
 
	/* recv response message & print */
	while(1)
	{
		int len = BIO_read(bio, buf, 512);
 
		if(0 == len)
		{
			/* handle closed connection */
			break;
		}
		else if(0 >= len)
		{
			if(!BIO_should_retry(bio))
			{
				/* handle failed read here */
			}
			/* do something to handle the retry */
		}
		else
		{
			/* write to stdout */
			write(1, buf, len);
		}
	}
 
	/* free */
	BIO_free_all(bio);
	SSL_CTX_free(ctx);
 
	return 0;
}

编译命令

gcc `pkg-config --cflags --libs libssl` -o ssl-test ssl-test.c

Over!

GCGI – A CGI library in C

GCGI 是一款开放源代码的、使用C语言实现的、面向对象的 CGI 库,它基于 GObject。

功能
发送 Status
发送 Content-Type
发送 Location
获取环境变量
设置环境变量
GET请求字段解析
POST请求字段解析
支持文件上传、下载

后期功能
Cookies 支持
Session 支持

代码仓库

git clone http://git.heiher.info/gcgi.git

Over!