php_http_message_parser_state_t php_http_message_parser_state_push(php_http_message_parser_t *parser, unsigned argc, ...)
{
- php_http_message_parser_state_t state;
+ php_http_message_parser_state_t state = PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE;
va_list va_args;
unsigned i;
- /* short circuit */
- ZEND_PTR_STACK_RESIZE_IF_NEEDED((&parser->stack), argc);
+ if (argc > 0) {
+ /* short circuit */
+ ZEND_PTR_STACK_RESIZE_IF_NEEDED((&parser->stack), argc);
- va_start(va_args, argc);
- for (i = 0; i < argc; ++i) {
- state = va_arg(va_args, php_http_message_parser_state_t);
- zend_ptr_stack_push(&parser->stack, (void *) state);
+ va_start(va_args, argc);
+ for (i = 0; i < argc; ++i) {
+ state = va_arg(va_args, php_http_message_parser_state_t);
+ zend_ptr_stack_push(&parser->stack, (void *) state);
+ }
+ va_end(va_args);
}
- va_end(va_args);
return state;
}
if (!buf->data) {
php_http_buffer_resize_ex(buf, 0x1000, 1, 0);
}
- while (!php_stream_eof(s)) {
+ while (1) {
size_t justread = 0;
#if DBG_PARSER
fprintf(stderr, "#SP: %s (f:%u)\n", php_http_message_parser_state_name(state), flags);
#endif
+ /* resize if needed */
+ if (buf->free < 0x1000) {
+ php_http_buffer_resize_ex(buf, 0x1000, 1, 0);
+ }
switch (state) {
case PHP_HTTP_MESSAGE_PARSER_STATE_START:
case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER:
case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE:
/* read line */
php_stream_get_line(s, buf->data + buf->used, buf->free, &justread);
+ /* if we fail reading a whole line, try a single char */
+ if (!justread) {
+ int c = php_stream_getc(s);
+
+ if (c != EOF) {
+ char s[1] = {c};
+ justread = php_http_buffer_append(buf, s, 1);
+ }
+ }
php_http_buffer_account(buf, justread);
break;
state = php_http_message_parser_parse(parser, buf, flags, message);
} else if (php_stream_eof(s)) {
return php_http_message_parser_parse(parser, buf, flags | PHP_HTTP_MESSAGE_PARSER_CLEANUP, message);
- } else {
+ } else {
return state;
}
}
zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_LENGTH"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH TSRMLS_CC);
zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_CHUNKED"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED TSRMLS_CC);
zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_BODY_DONE"), PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE TSRMLS_CC);
+ zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_UPDATE_CL"), PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL TSRMLS_CC);
zend_declare_class_constant_long(php_http_message_parser_class_entry, ZEND_STRL("STATE_DONE"), PHP_HTTP_MESSAGE_PARSER_STATE_DONE TSRMLS_CC);
return SUCCESS;