| 66 | } |
| 67 | |
| 68 | static int |
| 69 | body_transform(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */) |
| 70 | { |
| 71 | TSHttpTxn txn = static_cast<TSHttpTxn>(TSContDataGet(contp)); |
| 72 | BodyBuilder *data = AuxDataMgr::data(txn).body_builder.get(); |
| 73 | if (!data) { |
| 74 | return TS_ERROR; |
| 75 | } |
| 76 | if (TSVConnClosedGet(contp)) { |
| 77 | // write connection destroyed. |
| 78 | return 0; |
| 79 | } |
| 80 | |
| 81 | TSVIO src_vio = TSVConnWriteVIOGet(contp); |
| 82 | |
| 83 | switch (event) { |
| 84 | case TS_EVENT_ERROR: { |
| 85 | // Notify input vio of this error event |
| 86 | TSContCall(TSVIOContGet(src_vio), TS_EVENT_ERROR, src_vio); |
| 87 | return 0; |
| 88 | } |
| 89 | case TS_EVENT_VCONN_WRITE_COMPLETE: { |
| 90 | TSVConnShutdown(TSTransformOutputVConnGet(contp), 0, 1); |
| 91 | return 0; |
| 92 | } |
| 93 | case TS_EVENT_VCONN_WRITE_READY: |
| 94 | Dbg(dbg_ctl_xform, "body_transform(): Event is TS_EVENT_VCONN_WRITE_READY"); |
| 95 | // fall through |
| 96 | default: |
| 97 | if (!data->output_buffer.get()) { |
| 98 | data->output_buffer.reset(TSIOBufferCreate()); |
| 99 | data->output_reader.reset(TSIOBufferReaderAlloc(data->output_buffer.get())); |
| 100 | data->output_vio = TSVConnWrite(TSTransformOutputVConnGet(contp), contp, data->output_reader.get(), INT64_MAX); |
| 101 | } |
| 102 | |
| 103 | if (data->wrote_prebody == false) { |
| 104 | Dbg(dbg_ctl_xform, "body_transform(): Writing prebody headers..."); |
| 105 | std::string prebody = getPreBody(txn); |
| 106 | TSIOBufferWrite(data->output_buffer.get(), prebody.data(), prebody.length()); // write prebody |
| 107 | data->wrote_prebody = true; |
| 108 | data->nbytes += prebody.length(); |
| 109 | } |
| 110 | |
| 111 | TSIOBuffer src_buf = TSVIOBufferGet(src_vio); |
| 112 | |
| 113 | if (!src_buf) { |
| 114 | // upstream continuation shuts down write operation. |
| 115 | data->wrote_body = true; |
| 116 | writePostBody(txn, data); |
| 117 | return 0; |
| 118 | } |
| 119 | |
| 120 | int64_t towrite = TSVIONTodoGet(src_vio); |
| 121 | Dbg(dbg_ctl_xform, "body_transform(): %" PRId64 " bytes of body is expected", towrite); |
| 122 | int64_t avail = TSIOBufferReaderAvail(TSVIOReaderGet(src_vio)); |
| 123 | towrite = towrite > avail ? avail : towrite; |
| 124 | if (towrite > 0) { |
| 125 | TSIOBufferCopy(TSVIOBufferGet(data->output_vio), TSVIOReaderGet(src_vio), towrite, 0); |
nothing calls this directly
no test coverage detected