WOCGISendResponse
2007/03/30 (Fri) 22:07:46 JST
if (resp != NULL) { sendResponse(resp); resp_free(resp); /* dump the response */ } #if defined(FINDLEAKS) WOFREE(url); /* just for neatness */ st_free(options); req_free(req); showleaks(); #endif return 0;
いよいよmain()の最後です。 といってもこれも簡単で、前処理で返ってきたレスポンスをブラウザに送り、そのレスポンスを解放します。 マクロの部分はメモリリークがあったときの処理です。
sendResponse()
static void sendResponse(HTTPResponse *resp) { String *resphdrs; fprintf(stdout, "Status: %d %s" CRLF, resp->status, resp->statusMsg); resphdrs = resp_packageHeaders(resp); fputs(resphdrs->text,stdout); str_free(resphdrs); fputs(CRLF,stdout); /* content_valid はHEADリクエストか空のレスポンスのとき、0になる */ if (resp->content_valid) { while (resp->content_read < resp->content_length) { fwrite(resp->content, sizeof(char), resp->content_valid, stdout); resp_getResponseContent(resp, 1); } fwrite(resp->content, sizeof(char), resp->content_valid, stdout); } fflush(stdout); }
それでは、アダプタ最後の処理を見てみましょう。 まずはデータ構造から。
String (wastring.h)
typedef struct _String { unsigned int bufferSize; /* データのバッファサイズ */ unsigned int length; /* 文字数 */ struct _String *next; /* Stringを連結するときに使う */ char *text; /* 文字列、終了はnull */ char cached; /* キャッシュされているなら真 */ } String;
可変文字列ですね。 str_と頭につく関数はこのデータを操作する関数です。
レスポンス送信で最初にすることは、HTTPヘッダの出力(CGIアダプタの出力先は標準出力)です。 HTTPヘッダは resp_packageHeaders() でString構造体にまとめてから出力します。 HTTPヘッダを1行ずつ生成し、Stringに追加していきます。
resp_packageHeaders() (response.c)
String *resp_packageHeaders(HTTPResponse *resp) { String *result; result = str_create(NULL, 1000); if (result) st_perform(resp->headers, (st_perform_callback)resp_appendHeader, result); return result; }
resp_appendHeaders() (response.c)
static void resp_appendHeader(const char *key, const char *val, String *headers) { str_append(headers, key); str_appendLiteral(headers, ": "); str_append(headers, val); str_appendLiteral(headers, "\r\n"); }
ヘッダを出力したら、次にコンテントデータを出力します。 HTTPResponseの content_valid にはコンテントデータの有効なサイズです。 HEADリクエストが来たり、空のレスポンス(コンテントデータがない)場合は 0 になります。
レスポンスのコンテントデータはアプリケーションが持っており、 resp_getResponseContent で取得します。 2番目の引数が 0 なら一度に、1 ならストリーミングで少しずつデータを取得します。 このとき取得したデータサイズの分だけ content_read が進みます。 content_length 分データを取得したら、最後に取得したデータを出力し、出力のバッファフラッシュを行って終了です。
Inverse Pages: WOCGIAdaptor