47 std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings. |
47 std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings. |
48 shared_ptr<relpipe::writer::RelationalWriter> relationalWriter; |
48 shared_ptr<relpipe::writer::RelationalWriter> relationalWriter; |
49 Configuration configuration; |
49 Configuration configuration; |
50 std::vector<relpipe::reader::handlers::AttributeMetadata> currentReaderMetadata; |
50 std::vector<relpipe::reader::handlers::AttributeMetadata> currentReaderMetadata; |
51 std::vector<relpipe::writer::AttributeMetadata> currentWriterMetadata; |
51 std::vector<relpipe::writer::AttributeMetadata> currentWriterMetadata; |
|
52 std::vector<relpipe::common::type::StringX> responseHeaders; |
52 size_t currentAttributeIndex = 0; |
53 size_t currentAttributeIndex = 0; |
53 size_t currentRecordNumber = 1; |
54 size_t currentRecordNumber = 1; |
|
55 |
|
56 void writeHeaders() { |
|
57 if (responseHeaders.size()) { |
|
58 relationalWriter->startRelation(L"response_header",{ |
|
59 // TODO: request ID instead of URL (or both) |
|
60 {L"url", relpipe::writer::TypeId::STRING}, |
|
61 {L"name", relpipe::writer::TypeId::STRING}, |
|
62 {L"value", relpipe::writer::TypeId::STRING}, |
|
63 }, true); |
|
64 |
|
65 for (auto s : responseHeaders) relationalWriter->writeAttribute(s); |
|
66 |
|
67 responseHeaders.clear(); |
|
68 } |
|
69 } |
54 |
70 |
55 public: |
71 public: |
56 |
72 |
57 HTTPHandler(shared_ptr<relpipe::writer::RelationalWriter> relationalWriter, Configuration configuration) : relationalWriter(relationalWriter), configuration(configuration) { |
73 HTTPHandler(shared_ptr<relpipe::writer::RelationalWriter> relationalWriter, Configuration configuration) : relationalWriter(relationalWriter), configuration(configuration) { |
58 } |
74 } |
60 virtual ~HTTPHandler() { |
76 virtual ~HTTPHandler() { |
61 } |
77 } |
62 |
78 |
63 void startRelation(relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override { |
79 void startRelation(relpipe::common::type::StringX name, std::vector<relpipe::reader::handlers::AttributeMetadata> attributes) override { |
64 |
80 |
|
81 writeHeaders(); // from previous relation |
65 |
82 |
66 relationalWriter->startRelation(name + L"_curl_info",{ |
83 relationalWriter->startRelation(name + L"_curl_info",{ |
67 {L"name", relpipe::writer::TypeId::STRING}, |
84 {L"name", relpipe::writer::TypeId::STRING}, |
68 {L"value", relpipe::writer::TypeId::STRING} |
85 {L"value", relpipe::writer::TypeId::STRING} |
69 }, true); |
86 }, true); |
70 |
87 |
71 relationalWriter->writeAttribute(L"curl version"); |
88 relationalWriter->writeAttribute(L"curl version"); |
72 relationalWriter->writeAttribute(convertor.from_bytes(curl_version())); |
89 relationalWriter->writeAttribute(convertor.from_bytes(curl_version())); |
73 |
90 |
74 relationalWriter->startRelation(name + L"_curl_response",{ |
91 relationalWriter->startRelation(name + L"_curl_response",{ |
|
92 // TODO: request ID |
|
93 // TODO: body in hexadecimal/binary format |
75 {L"url", relpipe::writer::TypeId::STRING}, |
94 {L"url", relpipe::writer::TypeId::STRING}, |
76 {L"body", relpipe::writer::TypeId::STRING}, |
95 {L"body", relpipe::writer::TypeId::STRING}, |
77 {L"response_code", relpipe::writer::TypeId::INTEGER}, |
96 {L"response_code", relpipe::writer::TypeId::INTEGER}, |
78 // {L"success", relpipe::writer::TypeId::BOOLEAN}, |
|
79 }, true); |
97 }, true); |
80 |
98 |
81 } |
99 } |
82 |
100 |
83 void attribute(const relpipe::common::type::StringX& value) override { |
101 void attribute(const relpipe::common::type::StringX& value) override { |
89 request.url = convertor.to_bytes(value); |
107 request.url = convertor.to_bytes(value); |
90 |
108 |
91 HTTPClient::Response response = http->exchange(request); |
109 HTTPClient::Response response = http->exchange(request); |
92 relpipe::common::type::Integer responseCode = response.responseCode; |
110 relpipe::common::type::Integer responseCode = response.responseCode; |
93 |
111 |
94 // std::cerr << "url = >>>" << convertor.to_bytes(value) << "<<<" << std::endl; |
|
95 // std::cerr << "body = >>>" << response.body << "<<<" << std::endl; |
|
96 |
|
97 relationalWriter->writeAttribute(value); |
112 relationalWriter->writeAttribute(value); |
98 relationalWriter->writeAttribute(convertor.from_bytes(response.body)); |
113 relationalWriter->writeAttribute(convertor.from_bytes(response.body)); |
99 relationalWriter->writeAttribute(&responseCode, typeid (responseCode)); |
114 relationalWriter->writeAttribute(&responseCode, typeid (responseCode)); |
100 // relationalWriter->writeAttribute(&response.success, typeid (response.success)); |
115 |
|
116 for (size_t i = 0; i < response.headers.size(); i += 2) { |
|
117 responseHeaders.push_back(convertor.from_bytes(request.url)); |
|
118 responseHeaders.push_back(convertor.from_bytes(response.headers[i])); |
|
119 responseHeaders.push_back(convertor.from_bytes(response.headers[i + 1])); |
|
120 } |
101 } |
121 } |
102 |
122 |
103 void endOfPipe() { |
123 void endOfPipe() { |
104 |
124 writeHeaders(); // from last relation |
105 } |
125 } |
106 |
126 |
107 }; |
127 }; |
108 |
128 |
109 } |
129 } |