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