int HttpSM::state_common_wait_for_transform_read(...) This function handles the overlapping cases between request and response transforms which prevents code duplication
| 1227 | // transforms which prevents code duplication |
| 1228 | // |
| 1229 | int |
| 1230 | HttpSM::state_common_wait_for_transform_read(HttpTransformInfo *t_info, HttpSMHandler tunnel_handler, int event, void *data) |
| 1231 | { |
| 1232 | STATE_ENTER(&HttpSM::state_common_wait_for_transform_read, event); |
| 1233 | HttpTunnelConsumer *c = nullptr; |
| 1234 | |
| 1235 | switch (event) { |
| 1236 | case HTTP_TUNNEL_EVENT_DONE: |
| 1237 | // There are three reasons why the tunnel could signal completed |
| 1238 | // 1) there was error from the transform write |
| 1239 | // 2) there was an error from the data source |
| 1240 | // 3) the transform write completed before it sent |
| 1241 | // TRANSFORM_READ_READY which is legal and in which |
| 1242 | // case we should just wait for the transform read ready |
| 1243 | c = tunnel.get_consumer(t_info->vc); |
| 1244 | ink_assert(c != nullptr); |
| 1245 | ink_assert(c->vc == t_info->entry->vc); |
| 1246 | |
| 1247 | if (c->handler_state == HTTP_SM_TRANSFORM_FAIL) { |
| 1248 | // Case 1 we failed to complete the write to the |
| 1249 | // transform fall through to vc event error case |
| 1250 | ink_assert(c->write_success == false); |
| 1251 | } else if (c->producer->read_success == false) { |
| 1252 | // Case 2 - error from data source |
| 1253 | if (c->producer->vc_type == HT_HTTP_CLIENT) { |
| 1254 | // Our source is the client. POST can't |
| 1255 | // be truncated so forward to the tunnel |
| 1256 | // handler to clean this mess up |
| 1257 | ink_assert(t_info == &post_transform_info); |
| 1258 | return (this->*tunnel_handler)(event, data); |
| 1259 | } else { |
| 1260 | // On the response side, we just forward as much |
| 1261 | // as we can of truncated documents so |
| 1262 | // just don't cache the result |
| 1263 | ink_assert(t_info == &transform_info); |
| 1264 | t_state.api_info.cache_transformed = false; |
| 1265 | return 0; |
| 1266 | } |
| 1267 | } else { |
| 1268 | // Case 3 - wait for transform read ready |
| 1269 | return 0; |
| 1270 | } |
| 1271 | // FALLTHROUGH |
| 1272 | case VC_EVENT_ERROR: |
| 1273 | case VC_EVENT_EOS: |
| 1274 | case VC_EVENT_INACTIVITY_TIMEOUT: |
| 1275 | // Transform VC sends NULL on error conditions |
| 1276 | if (!c) { |
| 1277 | c = tunnel.get_consumer(t_info->vc); |
| 1278 | ink_assert(c != nullptr); |
| 1279 | } |
| 1280 | vc_table.cleanup_entry(t_info->entry); |
| 1281 | t_info->entry = nullptr; |
| 1282 | // In Case 1: error due to transform write, |
| 1283 | // we need to keep the original t_info->vc for transform_cleanup() |
| 1284 | // to skip do_io_close(); otherwise, set it to NULL. |
| 1285 | if (c->handler_state != HTTP_SM_TRANSFORM_FAIL) { |
| 1286 | t_info->vc = nullptr; |
nothing calls this directly
no test coverage detected