--- a/src/HTTPHandler.h Sun Mar 13 20:50:25 2022 +0100
+++ b/src/HTTPHandler.h Tue Mar 15 01:47:05 2022 +0100
@@ -44,18 +44,29 @@
class HTTPHandler : public relpipe::reader::handlers::RelationalReaderStringHandler {
private:
+
+ class HeaderDefinition {
+ public:
+ // TODO: filters/patterns/condition
+ relpipe::common::type::StringX name;
+ relpipe::common::type::StringX value;
+ };
+
std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
shared_ptr<relpipe::writer::RelationalWriter> relationalWriter;
Configuration configuration;
+ relpipe::common::type::StringX currentRelationName;
std::vector<relpipe::reader::handlers::AttributeMetadata> currentReaderMetadata;
std::vector<relpipe::writer::AttributeMetadata> currentWriterMetadata;
+ HeaderDefinition requestHeader;
+ std::vector<HeaderDefinition> requestHeaders;
std::vector<relpipe::common::type::StringX> responseHeaders;
size_t currentAttributeIndex = 0;
size_t currentRecordNumber = 1;
void writeHeaders() {
if (responseHeaders.size()) {
- relationalWriter->startRelation(L"response_header",{
+ relationalWriter->startRelation(L"header",{
// TODO: request ID instead of URL (or both)
{L"url", relpipe::writer::TypeId::STRING},
{L"name", relpipe::writer::TypeId::STRING},
@@ -77,29 +88,48 @@
}
void startRelation(relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override {
-
writeHeaders(); // from previous relation
- relationalWriter->startRelation(name + L"_curl_info",{
- {L"name", relpipe::writer::TypeId::STRING},
- {L"value", relpipe::writer::TypeId::STRING}
- }, true);
+ currentRelationName = name;
+ currentReaderMetadata = attributes;
- relationalWriter->writeAttribute(L"curl version");
- relationalWriter->writeAttribute(convertor.from_bytes(curl_version()));
+ if (currentRelationName == L"header") {
+ // TODO: analyze header attributes
+ } else if (currentRelationName == L"request") {
+ relationalWriter->startRelation(L"response",{
+ // TODO: request ID
+ // TODO: body in hexadecimal/binary format
+ {L"url", relpipe::writer::TypeId::STRING},
+ {L"body", relpipe::writer::TypeId::STRING},
+ {L"code", relpipe::writer::TypeId::INTEGER},
+ }, true);
+ }
+ }
- relationalWriter->startRelation(name + L"_curl_response",{
- // TODO: request ID
- // TODO: body in hexadecimal/binary format
- {L"url", relpipe::writer::TypeId::STRING},
- {L"body", relpipe::writer::TypeId::STRING},
- {L"response_code", relpipe::writer::TypeId::INTEGER},
- }, true);
+ void attribute(const relpipe::common::type::StringX& value) override {
+ if (currentRelationName == L"header") headerAttribute(value);
+ else if (currentRelationName == L"request") requestAttribute(value);
+ else throw std::invalid_argument("Unsupported relation: " + convertor.to_bytes(currentRelationName));
+ }
+
+private:
+
+ void headerAttribute(const relpipe::common::type::StringX& value) {
+ if (currentReaderMetadata[currentAttributeIndex].getAttributeName() == L"name") requestHeader.name = value;
+ else if (currentReaderMetadata[currentAttributeIndex].getAttributeName() == L"value") requestHeader.value = value;
+ else throw std::invalid_argument("Unsupported attribute in the header relation: " + convertor.to_bytes(currentReaderMetadata[currentAttributeIndex].getAttributeName() + L" = " + value));
+
+ currentAttributeIndex++;
+
+ if (currentAttributeIndex % currentReaderMetadata.size() == 0) {
+ currentAttributeIndex = 0;
+ requestHeaders.push_back(requestHeader);
+ requestHeader = HeaderDefinition();
+ }
}
- void attribute(const relpipe::common::type::StringX& value) override {
-
+ void requestAttribute(const relpipe::common::type::StringX& value) {
std::shared_ptr<HTTPClient> http(HTTPClient::open());
HTTPClient::Request request;
@@ -113,6 +143,10 @@
// request.headers.push_back("application/xml");
// request.headers.push_back("User-Agent");
// request.headers.push_back("curl/7.58.0");
+ for (const HeaderDefinition& h : requestHeaders) {
+ request.headers.push_back(convertor.to_bytes(h.name));
+ request.headers.push_back(convertor.to_bytes(h.value));
+ }
HTTPClient::Response response = http->exchange(request);
relpipe::common::type::Integer responseCode = response.responseCode;
@@ -128,6 +162,8 @@
}
}
+public:
+
void endOfPipe() {
writeHeaders(); // from last relation
}