<p class="MsoNormal"><span lang="EN-US">Now I’m using ragel to build a http parser.</span></p>
<p class="MsoNormal"><span lang="EN-US">One requirement of the parser is to parse
all the http headers, which would be used by another module.</span></p>
<p class="MsoNormal"><span lang="EN-US">For some common headers, the header value
would be parsed directly by ragel. </span></p>
<p class="MsoNormal"><span lang="EN-US">For other headers, only mark the header
name and value.</span></p>
<p class="MsoNormal"><span lang="EN-US">Here is my ragel script:</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span lang="EN-US">message_header =(</span></p>
<p class="MsoNormal"><span lang="EN-US">
("Content-Length"i ":" LWS* digit+ $on_content_length)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("Transfer-Encoding"i ":" LWS* ("Chunked"i %
{request->transfer_encoding = HTTP_TE_CHUNKED;} | any* > start_TE %
finish_TE))</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("Connection"i ":" LWS* ("Keep-alive"i %
{request->connection = HTTP_CONNECTION_KEEP_ALIVE;} | "Close"i %
{request->connection = HTTP_CONNECTION_CLOSE;}))</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("Host"i ":" LWS* field_content >start_host %<b>finish_host</b>
%/break_host)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("Accept"i ":" LWS* field_content >start_accept %
finish_accept %/break_accept)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("Accept-Charset"i ":" LWS* field_content
>start_accept_charset % finish_accept_charset %/break_accept_charset)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("Accept-Encoding"i ":" LWS* field_content
>start_accept_encoding % finish_accept_encoding %/break_accept_encoding)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("Accept-Language"i ":" LWS* field_content
>start_accept_language % finish_accept_language %/break_accept_language)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("User-Agent"i ":" LWS* field_content
>start_user_agent % finish_user_agent %/break_user_agent)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("Referer"i ":" LWS* field_content >start_referer %
finish_referer %/break_referer)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ("X-Forward-For"i ":" LWS* field_content
>start_x_forward_for % finish_x_forward_for %/break_x_forward_for)</span></p>
<p class="MsoNormal"><span lang="EN-US">
| ((token) >start_header_name %finish_header_name
%/break_header_name":" LWS* field_content % <b>header_end</b>)</span></p>
<p class="MsoNormal"><span lang="EN-US">
) :>CRLF;</span></p>
<p class="MsoNormal"><span lang="EN-US">Here there is a nondeterminism between
token and the common header names.</span></p>
<p class="MsoNormal"><span lang="EN-US">For example, when a Host header value
finished, the header’s action finish_host and the “token” action header_end
will be triggered.</span></p>
<p class="MsoNormal"><span lang="EN-US">How can I resolve this kind of problem?</span></p><p class="MsoNormal"><span lang="EN-US"><br></span></p><p class="MsoNormal"><span lang="EN-US">Thanks.</span></p><p class="MsoNormal">
<span lang="EN-US"><br></span></p><p class="MsoNormal"><span lang="EN-US">Hongbin.</span></p><p class="MsoNormal"><span lang="EN-US"><br></span></p>