| 335 | } |
| 336 | |
| 337 | size_t |
| 338 | TransformationPlugin::doProduce(std::string_view data) |
| 339 | { |
| 340 | LOG_DEBUG("TransformationPlugin=%p tshttptxn=%p producing output with length=%ld", this, state_->txn_, data.length()); |
| 341 | int64_t write_length = static_cast<int64_t>(data.length()); |
| 342 | if (!write_length) { |
| 343 | return 0; |
| 344 | } |
| 345 | |
| 346 | if (!state_->output_vio_) { |
| 347 | TSVConn output_vconn = TSTransformOutputVConnGet(state_->vconn_); |
| 348 | LOG_DEBUG("TransformationPlugin=%p tshttptxn=%p will issue a TSVConnWrite, output_vconn=%p.", this, state_->txn_, output_vconn); |
| 349 | if (output_vconn) { |
| 350 | // If you're confused about the following reference the traffic server transformation docs. |
| 351 | // You always write INT64_MAX, this basically says you're not sure how much data you're going to write |
| 352 | state_->output_vio_ = TSVConnWrite(output_vconn, state_->vconn_, state_->output_buffer_reader_, INT64_MAX); |
| 353 | } else { |
| 354 | LOG_ERROR("TransformationPlugin=%p tshttptxn=%p output_vconn=%p cannot issue TSVConnWrite due to null output vconn.", this, |
| 355 | state_->txn_, output_vconn); |
| 356 | return 0; |
| 357 | } |
| 358 | |
| 359 | if (!state_->output_vio_) { |
| 360 | LOG_ERROR("TransformationPlugin=%p tshttptxn=%p state_->output_vio=%p, TSVConnWrite failed.", this, state_->txn_, |
| 361 | state_->output_vio_); |
| 362 | return 0; |
| 363 | } |
| 364 | } |
| 365 | |
| 366 | // Finally we can copy this data into the output_buffer |
| 367 | int64_t bytes_written = TSIOBufferWrite(state_->output_buffer_, data.data(), write_length); |
| 368 | state_->bytes_written_ += bytes_written; // So we can set BytesDone on outputComplete(). |
| 369 | LOG_DEBUG("TransformationPlugin=%p tshttptxn=%p write to TSIOBuffer %" PRId64 " bytes total bytes written %" PRId64, this, |
| 370 | state_->txn_, bytes_written, state_->bytes_written_); |
| 371 | |
| 372 | // Sanity Checks |
| 373 | if (bytes_written != write_length) { |
| 374 | LOG_ERROR("TransformationPlugin=%p tshttptxn=%p bytes written < expected. bytes_written=%" PRId64 " write_length=%" PRId64, |
| 375 | this, state_->txn_, bytes_written, write_length); |
| 376 | } |
| 377 | |
| 378 | int connection_closed = TSVConnClosedGet(state_->vconn_); |
| 379 | LOG_DEBUG("TransformationPlugin=%p tshttptxn=%p vconn=%p connection_closed=%d", this, state_->txn_, state_->vconn_, |
| 380 | connection_closed); |
| 381 | |
| 382 | if (!connection_closed) { |
| 383 | TSVIOReenable(state_->output_vio_); // Wake up the downstream vio |
| 384 | } else { |
| 385 | LOG_ERROR( |
| 386 | "TransformationPlugin=%p tshttptxn=%p output_vio=%p connection_closed=%d : Couldn't reenable output vio (connection closed).", |
| 387 | this, state_->txn_, state_->output_vio_, connection_closed); |
| 388 | } |
| 389 | |
| 390 | return static_cast<size_t>(bytes_written); |
| 391 | } |
| 392 | |
| 393 | size_t |
| 394 | TransformationPlugin::produce(std::string_view data) |
nothing calls this directly
no test coverage detected