Пример #1
0
bool http_header::build_response(string& out) const
{
	out.clear();

	if (status_ > 0)
	{
		if (cgi_mode_)
			out.format("STATUS: %d\r\n", status_);
		else
		{
			out = "HTTP/1.1 ";
			out << status_ << " " << http_status(status_) << "\r\n";

			time_t now = time(NULL);
			char buf[64];
			date_format(buf, sizeof(buf), now);
			out << "Date: " << buf << "\r\n";
			out << "Server: acl\r\n";
		}
	}

	if (!cookies_.empty())
	{
		std::list<HttpCookie*>::const_iterator it = cookies_.begin();
		for (; it != cookies_.end(); ++it)
		{
			out.format_append("Set-Cookie: %s=%s",
				(*it)->getName(), (*it)->getValue());
			const std::list<HTTP_PARAM*>& params = (*it)->getParams();
			std::list<HTTP_PARAM*>::const_iterator cit = params.begin();
			for (; cit != params.end(); ++ cit)
			{
				out.format_append("; %s=%s",
					(*cit)->name, (*cit)->value);
			}
			out << "\r\n";
		}
	}

	// 添加分段响应字段
	if (range_from_ >= 0 && range_to_ >= range_from_ && range_total_ > 0)
		out << "Content-Range: bytes=" << range_from_ << '-'
			<< range_to_ << '/' << range_total_ << "\r\n";

	// 如果是 gzip 压缩数据,当非 chunked 传输时,必须取消 Content-Length 字段,
	// 同时禁止保持长连接,即: Connection: close
	if (transfer_gzip_)
	{
		out << "Content-Encoding: gzip\r\n";

		if (!chunked_transfer_ && keep_alive_)
			const_cast<http_header*>(this)->keep_alive_ = false;
		if (content_length_ > 0)
			const_cast<http_header*>(this)->content_length_ = -1;
	}

	build_common(out);
	out << "\r\n";
	return true;
}
Пример #2
0
bool http_header::build_response(string& out) const
{
	out.clear();

	if (status_ > 0)
	{
		if (cgi_mode_)
			out.format("STATUS: %d\r\n", status_);
		else
		{
			out = "HTTP/1.1 ";
			out << status_ << " " << http_status(status_) << "\r\n";

			time_t now = time(NULL);
			char buf[64];
			date_format(buf, sizeof(buf), now);
			out << "Date: " << buf << "\r\n";
		}
	}

	if (!cookies_.empty())
	{
		std::list<HttpCookie*>::const_iterator it = cookies_.begin();
		for (; it != cookies_.end(); ++it)
		{
			out.format_append("Set-Cookie: %s=%s",
				(*it)->getName(), (*it)->getValue());
			const std::list<HTTP_PARAM*>& params = (*it)->getParams();
			std::list<HTTP_PARAM*>::const_iterator cit = params.begin();
			for (; cit != params.end(); ++ cit)
			{
				out.format_append("; %s=%s",
					(*cit)->name, (*cit)->value);
			}
			out << "\r\n";
		}
	}

	build_common(out);
	out << "\r\n";
	return true;
}
Пример #3
0
bool http_header::build_request(string& buf) const
{
	if (url_ == NULL || *url_ == 0)
	{
		logger_error("url empty");
		return (false);
	}

	buf.format("%s %s", method_s_, url_);

	if (!params_.empty())
	{
		buf << '?';
		acl::string tmp;
		int i = 0;
		std::list<HTTP_PARAM*>::const_iterator it = params_.begin();
		for (; it != params_.end(); ++it)
		{
			if (i > 0)
				buf += '&';
			else
				i++;

			// 需要对参数进行 URL 编码

			tmp.url_encode((*it)->name);
			buf += tmp.c_str();

			// 允许参数值为空指针
			if ((*it)->value == NULL)
				continue;

			buf += '=';

			// 允许参数值为空串
			if (*((*it)->value) == 0)
				continue;

			tmp.url_encode((*it)->value);
			buf += tmp.c_str();
		}
	}
	buf += " HTTP/1.1\r\n";
	if (accept_compress_)
		// 因为目前的 zlib_stream 仅支持于此
		buf += "Accept-Encoding: gzip\r\n";

	if (host_[0] != 0)
		buf.format_append("Host: %s\r\n", host_);

	if (!cookies_.empty())
	{
		buf += "Cookie: ";
		std::list<HttpCookie*>::const_iterator it = cookies_.begin();
		for (; it != cookies_.end(); ++it)
		{
			if (it != cookies_.begin())
				buf += "; ";
			buf << (*it)->getName() << "=" << (*it)->getValue();
		}
		buf += "\r\n";
	}

	// 添加分段请求字段
	if (range_from_ >= 0)
	{
		buf << "Range: bytes=" << range_from_ << '-';
		if (range_to_ >= range_from_)
			buf << range_to_;
		buf += "\r\n";
	}

	build_common(buf);
	buf += "\r\n";

	return (true);
}