HTTP Header parser
pz325 opened this issue · comments
using /r/n to parse HTTP header can be faulty. Would suggest using finite state machine strategy.
Please find the following snippet, hope it helps.
Cheers,
Ping
/**
* parse HTTP header
*/
public function parseHeader():void
{
_data.position = 0;
var response:String = _data.readUTFBytes(_data.length);
_cursor = 0;
while(_cursor < response.length)
{
var ch:String = response.charAt(_cursor);
switch(_state)
{
case RESPONSE_START:
if (ch == "H")
{
_state = RESPONSE_VERSION;
_version += ch;
}
break;
case RESPONSE_VERSION:
if (ch == " ")
{
_state = RESPONSE_WAIT_STATUS;
//_logger.debug("version: " + _version);
}
else
{
_version += ch;
}
break;
case RESPONSE_WAIT_STATUS:
if (ch != " ")
{
_state = RESPONSE_STATUS_CODE;
_statusCode += ch;
}
break;
case RESPONSE_STATUS_CODE:
if (ch == " ")
{
_state = RESPONSE_WAIT_STATUS_INFO;
//_logger.debug("status code: " + _statusCode);
}
else
{
_statusCode += ch;
}
break;
case RESPONSE_WAIT_STATUS_INFO:
if (ch != " ")
{
_state = RESPONSE_STATUS_INFO;
_statusInfo += ch;
}
break;
case RESPONSE_STATUS_INFO:
if (ch == "\r")
{
_state = RESPONSE_CR;
//_logger.debug("status info: " + _statusInfo);
}
else
{
_statusInfo += ch;
}
break;
case RESPONSE_CR:
if (ch == "\n")
{
_state = RESPONSE_LF;
}
break;
case RESPONSE_LF:
if (ch == "\r")
{
_state = RESPONSE_HDR_ALMOST_DONE;
}
else
{
_state = RESPONSE_KEY;
_keyTemp += ch;
}
break;
case RESPONSE_KEY:
if (ch == ":")
{
_state = RESPONSE_KEY_SPACE;
_key = _keyTemp;
_keyTemp = "";
//_logger.debug("KEY: " + _key);
}
else
{
_keyTemp += ch;
}
break;
case RESPONSE_KEY_SPACE:
if (ch != " ")
{
_state = RESPONSE_VALUE;
_valueTemp += ch;
}
break;
case RESPONSE_VALUE:
if (ch != "\r")
{
_valueTemp += ch;
}
else
{
_state = RESPONSE_CR;
_value = _valueTemp;
_valueTemp = "";
_httpHeader.add(_key, _value);
//_logger.debug("VALUE: " + _value);
}
break;
case RESPONSE_HDR_ALMOST_DONE:
if (ch == "\n")
{
_state = RESPONES_HDR_DONE;
}
break;
} // end of switch
_cursor ++;
if (_state == RESPONES_HDR_DONE) break;
} // end of while
_httpResponse = new HttpResponse(_version, _statusCode, _statusInfo, _httpHeader);
}
BTW: thanks for your effort!