Exemple #1
0
Request MyParser::parseRequest(char* http, int nbytes) const {
  const char* CRLF = "\r\n";
  std::istringstream iss(http);
  //MSG("Input: %s", iss.str().c_str());
  Request request;

  // start line
  std::string start_line;
  std::getline(iss, start_line);
  //MSG("start=%s", start_line.c_str());
  request.startline = parseStartLine(start_line);

  // headers
  std::string header_line;
  std::vector<Header> headers;
  while (true) {
    std::getline(iss, header_line);
    if (isHeader(header_line)) {
      Header header = parseHeader(header_line);
      headers.push_back(header);
      //MSG("header=%s", header_line.c_str());
    } else {
      break;
    }
  }
  request.headers = headers;

  // body
  std::string ending = "";
  request.body = "";
  std::string line;
  while (std::getline(iss, line)) {
    line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
    request.body.append(ending);
    request.body.append(line);
    ending = "\n";
  }

  return request;  
}
Exemple #2
0
static int appendByte(char c, HttpMessage *msg)
{
	int ret = 1;
	ParserData *pd = (ParserData *)msg->pri_data;

	switch (pd->state) {
		case HTTP_STARTLINE:
			_append(c, msg);
			if (c == '\r') {
				pd->last_state = HTTP_STARTLINE;
				pd->state = HTTP_CR;
			}
			break;

		case HTTP_HEADERS:
			_append(c, msg);
			if (c == '\r') {
				pd->last_state = HTTP_HEADERS;
				pd->state = HTTP_CR;
			}
			break;

		case HTTP_CR:
			_append(c, msg);
			if (c == '\n') {
				pd->state = HTTP_CRLF;

				// blank line ?
				if (!strncmp(pd->linedata, "\r\n", 2)) {
					if (_getmsglen(msg) > 0) {
						pd->state = HTTP_BODY;
					}
					else {
						pd->state = HTTP_COMPLETE;
					}
				}
			}
			else {
				pd->state = pd->last_state;
			}
			break;

		case HTTP_CRLF:
			if (isblank(c)) {
				char *p;
				// LSW
				pd->state = HTTP_LSW;

				p = strstr(pd->linedata, "\r\n");
				if (p) {
					pd->line_datasize = p-pd->linedata;
				}
			}
			else {
				if (pd->last_state == HTTP_STARTLINE) {
					parseStartLine(msg);
				}
				else {
					parseHeaderLine(msg);
				}

				pd->line_datasize = 0;
				_append(c, msg);

				if (c == '\r')
					pd->state = HTTP_CR;
				else
					pd->state = HTTP_HEADERS;
			}
			break;

		case HTTP_LSW:
			if (!isblank(c)) {
				pd->state = pd->last_state;
				_append(c, msg);
			}
			break;

		case HTTP_BODY:
			msg->body = (char *)realloc(msg->body, msg->bodylen+1);
			msg->body[msg->bodylen] = c;
			msg->bodylen++;
			if (_getmsglen(msg) == msg->bodylen)
				pd->state = HTTP_COMPLETE;
			break;

		case HTTP_COMPLETE:
			break;
	}

	return ret;
}
Exemple #3
0
HttpParserImpl::ParseState HttpParserImpl::parseHttp(const char*& cur_pos, const char* end)
{
    const char* line = nullptr;
    const char* line_end = nullptr;
    bool b_line = false;
    
    if(HTTP_READ_LINE == read_state_)
    {// try to get status line
        while ((b_line = getLine(cur_pos, end, line, line_end)) && line == line_end && str_buf_.empty())
            ;
        if(b_line && (line != line_end || !str_buf_.empty())) {
            if(!parseStartLine(line, line_end)) {
                read_state_ = HTTP_READ_ERROR;
                return PARSE_STATE_ERROR;
            }
            read_state_ = HTTP_READ_HEAD;
        } else {
            // need more data
            if(saveData(cur_pos, end) != KUMA_ERROR_NOERR) {
                return PARSE_STATE_ERROR;
            }
            cur_pos = end; // all data was consumed
            return PARSE_STATE_CONTINUE;
        }
    }
    if(HTTP_READ_HEAD == read_state_)
    {
        while ((b_line = getLine(cur_pos, end, line, line_end)))
        {
            if(line == line_end && bufferEmpty())
            {// blank line, header completed
                onHeaderComplete();
                if(paused_) {
                    return PARSE_STATE_CONTINUE;
                }
                if(hasBody() && !upgrade_) {
                    read_state_ = HTTP_READ_BODY;
                } else {
                    read_state_ = HTTP_READ_DONE;
                    onComplete();
                    return PARSE_STATE_DONE;
                }
                break;
            }
            parseHeaderLine(line, line_end);
        }
        if(HTTP_READ_HEAD == read_state_)
        {// need more data
            if(saveData(cur_pos, end) != KUMA_ERROR_NOERR) {
                return PARSE_STATE_ERROR;
            }
            cur_pos = end; // all data was consumed
            return PARSE_STATE_CONTINUE;
        }
    }
    if(HTTP_READ_BODY == read_state_ && cur_pos < end)
    {// try to get body
        if(is_chunked_) {
            return parseChunk(cur_pos, end);
        } else {
            uint32_t cur_len = uint32_t(end - cur_pos);
            if(has_content_length_ && (content_length_ - total_bytes_read_) <= cur_len)
            {// data enough
                const char* notify_data = cur_pos;
                uint32_t notify_len = content_length_ - total_bytes_read_;
                cur_pos += notify_len;
                total_bytes_read_ = content_length_;
                read_state_ = HTTP_READ_DONE;
                KUMA_ASSERT(!destroy_flag_ptr_);
                bool destroyed = false;
                destroy_flag_ptr_ = &destroyed;
                if(cb_data_) cb_data_(notify_data, notify_len);
                if(destroyed) {
                    return PARSE_STATE_DESTROY;
                }
                destroy_flag_ptr_ = nullptr;
                onComplete();
                return PARSE_STATE_DONE;
            }
            else
            {// need more data, or read untill EOF
                const char* notify_data = cur_pos;
                total_bytes_read_ += cur_len;
                cur_pos = end;
                if(cb_data_) cb_data_(notify_data, cur_len);
                return PARSE_STATE_CONTINUE;
            }
        }
    }
    return HTTP_READ_DONE == read_state_?PARSE_STATE_DONE:PARSE_STATE_CONTINUE;
}