aboutsummaryrefslogtreecommitdiff
path: root/src/curlheadercontainer.cpp
blob: f6c572c21ba13a5f7feeba78e12e4b5bf43bd77b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "curlheadercontainer.h"

#include <curl/curl.h>

#include "utils.h"

namespace newsboat {

std::unique_ptr<CurlHeaderContainer> CurlHeaderContainer::register_header_handler(
	CurlHandle& curlHandle)
{
	return std::unique_ptr<CurlHeaderContainer>(new CurlHeaderContainer(curlHandle));
}

const std::vector<std::string>& CurlHeaderContainer::get_header_lines() const
{
	return mHeaderLines;
}

std::vector<std::string> CurlHeaderContainer::get_header_lines(const std::string& key)
const
{
	std::vector<std::string> values;
	std::string search_string = utils::to_lowercase(key) + ":";

	for (const auto& header_line : mHeaderLines) {
		if (utils::to_lowercase(header_line).find(search_string) == 0) {
			std::string value = header_line.substr(search_string.length());
			utils::trim(value);
			values.push_back(value);
		}
	}
	return values;
}

CurlHeaderContainer::CurlHeaderContainer(CurlHandle& curlHandle)
	: mCurlHandle(curlHandle)
{
	curl_easy_setopt(mCurlHandle.ptr(), CURLOPT_HEADERDATA, this);
	curl_easy_setopt(mCurlHandle.ptr(), CURLOPT_HEADERFUNCTION,
		&CurlHeaderContainer::handle_headers);
}

CurlHeaderContainer::~CurlHeaderContainer()
{
	curl_easy_setopt(mCurlHandle.ptr(), CURLOPT_HEADERDATA, nullptr);
	curl_easy_setopt(mCurlHandle.ptr(), CURLOPT_HEADERFUNCTION, nullptr);
}

size_t CurlHeaderContainer::handle_headers(char* buffer, size_t size, size_t nitems,
	void* data)
{
	auto header_container = static_cast<CurlHeaderContainer*>(data);
	const auto header_line = std::string(buffer, nitems * size);

	header_container->handle_header(header_line);

	return nitems * size;
}

void CurlHeaderContainer::handle_header(const std::string& line)
{
	if (line.find("HTTP/") == 0) {
		// Reset headers if a new response is detected (there might be multiple responses per request in case of a redirect)
		mHeaderLines.clear();
	}

	mHeaderLines.push_back(line);
}

} // namespace newsboat