3

これが私のスクリプトです:

#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」を使用しないようにしながら、すべてのリクエストを動的ディレクトリにリダイレクトしています (文字「?」を使用する必要はありません)。

このスクリプトは部分的に機能しますが、明らかにメモリ割り当ての問題を引き起こします。提案する解決策はありますか?

4

2 に答える 2

1

パフォーマンスが心配な場合は、strstr を使用しないでください。一致するリクエスト全体を検索します。

スクリプトに基づいて、すべてのリクエストが GET であると予想しているため、最初の 6 文字のみを比較しているため、strncmp を使用することをお勧めします。

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 文字だけをチェックしたい。

'?' を追加することによるメモリ割り当てが心配な場合 インプレース置換が発生するように、サーブレット名を設計する必要があるすべてのリクエストに対して。これは、パフォーマンスを向上させるためにインプレース置換を実現する方法のサンプルがあるリンクです。

G-WAN の RESTful URI

私は上記のコードをテストしていないので、うまくいかないかもしれませんが、少なくともその方法については理解できるでしょう。また、スクリプトはパイプラインのリクエストを処理しません。

于 2013-03-15T23:37:06.977 に答える
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書き換えを行わずに使用できます。

于 2013-03-14T07:12:15.887 に答える