G-WAN处理程序重写解决方案



下面是我的脚本:

#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"。

此脚本部分有效,但显然会导致内存分配问题。你有什么解决办法吗?

如果您担心性能,请不要使用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名称,以便可以进行就地替换。这里有一个关于如何实现就地替换以提高性能的示例链接。

G-WAN中的RESTful uri

我没有测试上面的代码,所以它可能不工作,但至少你会得到一个想法,如何做到这一点。此外,脚本不处理管道请求。

首先,尝试避免*.c脚本扩展是无用的:默认情况下,G-WAN接受像/?hello这样的请求,这些请求会自动重新映射到/?hello.c

第二,这不是特定于C,因为G-WAN允许您定义哪种编程语言(在支持的16种脚本语言中)将被用作"默认"语言。

第三,如果你想避免'?在你的请求中。G-WAN允许您在非保留字符中进行选择,从而可以使用use /'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不做任何重写。

相关内容

  • 没有找到相关文章

最新更新