这是我的剧本:
#include "gwan.h" // G-WAN exported functions
#include <string.h> // strstr()
int init(int argc, char *argv[])
{
u32 *states = (u32*)get_env(argv, US_HANDLER_STATES);
*states = 1 << HDL_AFTER_READ;
return 0;
}
void clean(int argc, char *argv[])
{}
int main(int argc, char *argv[])
{
if((long)argv[0] == HDL_AFTER_READ)
{
xbuf_t *read_xbuf = (xbuf_t*)get_env(argv, READ_XBUF);
if(strstr(read_xbuf->ptr, "GET / HTTP/1.1"))
{
xbuf_repl(read_xbuf, "GET / HTTP/1.1", "GET /?index HTTP/1.1");
}
else
{
if(strstr(read_xbuf->ptr, ".c HTTP/1.1"))
{
int *pHTTP_status = (int*)get_env(argv, HTTP_CODE);
if(pHTTP_status)
*pHTTP_status = 404;
return 255;
}
xbuf_repl(read_xbuf, "GET /", "GET /?");
}
}
return(255);
}
您可能已经了解,我正在尝试将主页重定向到动态文件“hello.c”。 我还将每个请求重定向到动态目录(不必使用字符“?”),同时防止在URL中使用扩展名“.c”。
此脚本部分工作,但显然会导致内存分配问题。 你有什么解决方案可以提出吗?
答案 0 :(得分:1)
如果您担心性能,请不要使用strstr。它将搜索整个匹配请求。
根据您的脚本,您希望所有请求都是GET,因此最好使用strncmp,因为您只是比较前6个字符。
int main(int argc, char *argv[])
{
xbuf_t *read_xbuf = (xbuf_t*)get_env(argv, READ_XBUF);
if(strncmp(read_xbuf->ptr, "GET / ", 6) == 0)
{
xbuf_repl(read_xbuf, " / ", " /?index ");
}
else
{
int pos = 5; // Start checking after '/' in "GET /"
while(pos < 20) // Only check first 15 characters
{ // Adjust depend on longest servlet name
if(read_xbuf->ptr[pos] == '.' && read_xbuf->ptr[pos+1] == 'c') // If request contains '.' return 404
{
int *pHTTP_status = (int*)get_env(argv, HTTP_CODE);
if(pHTTP_status)
*pHTTP_status = 404;
return 255;
}
}
xbuf_repl(read_xbuf, "GET /", "GET /?");
}
return(255);
}
再次检查“.c”。您只想检查前N个字符。
如果您担心添加'?'会导致内存分配对于您需要设计servlet名称的每个请求,以便进行就地替换。这是一个链接,其中包含如何实现就地替换以获得更好性能的示例。
我没有测试过上面的代码,所以它可能不起作用,但至少你会知道如何做到这一点。此脚本也不处理管道请求。
答案 1 :(得分:0)
首先,尝试避免*.c
脚本扩展是没用的:默认情况下,G-WAN会接受/?hello
之类的请求,这些请求会自动重新映射到/?hello.c
。
其次,这不是特定于C,因为G-WAN允许您定义编程语言(在支持的16种脚本语言中)将用作“默认”语言。
第三,如果你想避免'?',你也可以定义另一个角色。在你的请求中。 G-WAN允许您在非保留字符中进行选择,从而可以使用/'hello
或/_hello
代替/?hello.cpp
(请参阅下面的所有选项)。
并且,所有这一切都可以在不为每个请求调用处理程序的情况下完成(因此它不会流失内存):
int init(int argc, char *argv[])
{
// the QUERY_CHAR character can be chosen from the following set:
// - _ . ! ~ * ' ( )
// (see RFC 2396, section "2.3. Unreserved Characters")
//
u8 *query_char = (u8*)get_env(argv, QUERY_CHAR);
*query_char = '!'; // use "/!hello.c" instead of "/?hello.c"
// by default, DEFAULT_LANG = LG_C (ANSI C)
// LG_C, LG_CPP, LG_JAVA, etc. are defined in /gwan/include/gwan.h
// and in http://gwan.com/api#env
//
u8 *lang = (u8*)get_env(argv, DEFAULT_LANG);
*lang = LG_CPP; // use "/!hello" instead of "/!hello.cpp"
return 0;
}
// if, like above, init() does not define notification states with
// get_env(argv, US_HANDLER_STATES), then the main() and clean()
// handler calls defined below will never be invoked
// (URL rewriting can't be done faster)
//
void clean(int argc, char *argv[]) { }
int main (int argc, char *argv[]) { return 255; }
所以,回到你的问题,你可以使用/'hello
而不做任何重写。