Github user phrocker commented on a diff in the pull request: https://github.com/apache/nifi-minifi-cpp/pull/158#discussion_r147838696 --- Diff: extensions/http-curl/sitetosite/HTTPProtocol.cpp --- @@ -0,0 +1,312 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "HTTPProtocol.h" + +#include <sys/time.h> +#include <stdio.h> +#include <time.h> +#include <chrono> +#include <map> +#include <string> +#include <memory> +#include <thread> +#include <random> +#include <iostream> +#include <vector> + +#include "PeersEntity.h" +#include "io/CRCStream.h" +#include "sitetosite/Peer.h" +#include "io/validation.h" + +namespace org { +namespace apache { +namespace nifi { +namespace minifi { +namespace sitetosite { + +std::shared_ptr<utils::IdGenerator> HttpSiteToSiteClient::id_generator_ = utils::IdGenerator::getIdGenerator(); + +const std::string HttpSiteToSiteClient::parseTransactionId(const std::string &uri) { + int i = 0; + for (i = uri.length() - 1; i >= 0; i--) { + if (uri.at(i) == '/') + break; + } + return uri.substr(i + 1, uri.length() - (i + 1)); +} + +std::shared_ptr<Transaction> HttpSiteToSiteClient::createTransaction(std::string &transactionID, TransferDirection direction) { + std::string dir_str = direction == SEND ? "input-ports" : "output-ports"; + std::stringstream uri; + uri << getBaseURI() << "data-transfer/" << dir_str << "/" << getPortId() << "/transactions"; + auto client = create_http_client(uri.str(), "POST"); + + client->appendHeader(PROTOCOL_VERSION_HEADER, "1"); + + client->setConnectionTimeout(5); + + client->setContentType("application/json"); + client->appendHeader("Accept: application/json"); + client->setUseChunkedEncoding(); + client->setPostFields(""); + client->submit(); + peer_->setStream(nullptr); + if (client->getResponseCode() == 201) { + // parse the headers + auto headers = client->getParsedHeaders(); + auto intent_name = headers["x-location-uri-intent"]; + if (intent_name == "transaction-url") { + auto url = headers["Location"]; + + if (IsNullOrEmpty(&url)) { + logger_->log_debug("Location is empty"); + } else { + + org::apache::nifi::minifi::io::CRCStream<SiteToSitePeer> crcstream(peer_.get()); + auto transaction = std::make_shared<HttpTransaction>(direction, crcstream); + transaction->initialize(this, url); + auto transactionId = parseTransactionId(url); + if (IsNullOrEmpty(transactionId)) + return nullptr; + transaction->setTransactionId(transactionId); + std::shared_ptr<minifi::utils::HTTPClient> client; + if (transaction->getDirection() == SEND) { + client = openConnectionForSending(transaction); + } else { + client = openConnectionForReceive(transaction); + transaction->setDataAvailable(true); + // a 201 tells us that data is available. A 200 would mean that nothing is available. + } + + client->appendHeader(PROTOCOL_VERSION_HEADER, "1"); + peer_->setStream(std::unique_ptr<io::DataStream>(new io::HttpStream(client))); + transactionID = transaction->getUUIDStr(); + logger_->log_debug("Created transaction id -%s-", transactionID); + known_transactions_[transaction->getUUIDStr()] = transaction; + return transaction; + } + } else { + logger_->log_debug("Could not create transaction, intent is %s", intent_name); + } + } else { + logger_->log_debug("Could not create transaction, received %d", client->getResponseCode()); + } + return nullptr; +} + +int HttpSiteToSiteClient::readRespond(const std::shared_ptr<Transaction> &transaction, RespondCode &code, std::string &message) { + if (current_code == FINISH_TRANSACTION) { + + if (transaction->getDirection() == SEND) { + auto stream = dynamic_cast<io::HttpStream*>(peer_->getStream()); + stream->closeStream(); + auto client = stream->getClient(); + logger_->log_info("Faking it till I makin it 2, response code %d", client->getResponseCode()); + if (client->getResponseCode() == 202) { + code = CONFIRM_TRANSACTION; + message = std::string(client->getResponseBody().data(), client->getResponseBody().size()); + } else { + code = UNRECOGNIZED_RESPONSE_CODE; + } + return 1; --- End diff -- If we return -1 we won't have an opportunity to provide an error message. -1 would be for the case where there is a comms error. here we have no need to read and write for respond. But you did remind me to change that name to readResponse.
---