///////////////////////////////////////////////////////////////////////// Continuation to perform a background fill of a URL. This is pretty expensive (memory allocations etc.), we could eliminate maybe the std::string, but I think it's fine for now.
| 245 | // expensive (memory allocations etc.), we could eliminate maybe the |
| 246 | // std::string, but I think it's fine for now. |
| 247 | static int |
| 248 | cont_bg_fetch(TSCont contp, TSEvent event, void * /* edata ATS_UNUSED */) |
| 249 | { |
| 250 | BgFetchData *data = static_cast<BgFetchData *>(TSContDataGet(contp)); |
| 251 | int64_t avail; |
| 252 | |
| 253 | switch (event) { |
| 254 | case TS_EVENT_IMMEDIATE: |
| 255 | case TS_EVENT_TIMEOUT: |
| 256 | // Debug info for this particular bg fetch (put all debug in here please) |
| 257 | if (dbg_ctl.on()) { |
| 258 | char buf[INET6_ADDRSTRLEN]; |
| 259 | const sockaddr *sockaddress = reinterpret_cast<const sockaddr *>(&data->client_ip); |
| 260 | |
| 261 | switch (sockaddress->sa_family) { |
| 262 | case AF_INET: |
| 263 | inet_ntop(AF_INET, &(((struct sockaddr_in *)sockaddress)->sin_addr), buf, INET_ADDRSTRLEN); |
| 264 | Dbg(dbg_ctl, "Client IPv4 = %s", buf); |
| 265 | break; |
| 266 | case AF_INET6: |
| 267 | inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sockaddress)->sin6_addr), buf, INET6_ADDRSTRLEN); |
| 268 | Dbg(dbg_ctl, "Client IPv6 = %s", buf); |
| 269 | break; |
| 270 | default: |
| 271 | TSError("[%s] Unknown address family %d", PLUGIN_NAME, sockaddress->sa_family); |
| 272 | break; |
| 273 | } |
| 274 | Dbg(dbg_ctl, "Starting background fetch, replaying:"); |
| 275 | dump_headers(data->hdr_loc); |
| 276 | } |
| 277 | |
| 278 | // Setup the NetVC for background fetch |
| 279 | TSAssert(nullptr == data->vc); |
| 280 | if ((data->vc = TSHttpConnectWithPluginId(reinterpret_cast<sockaddr *>(&data->client_ip), PLUGIN_NAME, 0)) != nullptr) { |
| 281 | TSHttpHdrPrint(data->mbuf, data->hdr_loc, data->req_io_buf); |
| 282 | // We never send a body with the request. ToDo: Do we ever need to support that ? |
| 283 | TSIOBufferWrite(data->req_io_buf, "\r\n", 2); |
| 284 | |
| 285 | data->r_vio = TSVConnRead(data->vc, contp, data->resp_io_buf, INT64_MAX); |
| 286 | data->w_vio = TSVConnWrite(data->vc, contp, data->req_io_buf_reader, TSIOBufferReaderAvail(data->req_io_buf_reader)); |
| 287 | } else { |
| 288 | delete data; |
| 289 | TSError("[%s] Failed to connect to internal process, major malfunction", PLUGIN_NAME); |
| 290 | } |
| 291 | break; |
| 292 | |
| 293 | case TS_EVENT_VCONN_WRITE_COMPLETE: |
| 294 | // TSVConnShutdown(data->vc, 0, 1); |
| 295 | // TSVIOReenable(data->w_vio); |
| 296 | Dbg(dbg_ctl, "Write Complete"); |
| 297 | break; |
| 298 | |
| 299 | case TS_EVENT_VCONN_READ_READY: |
| 300 | avail = TSIOBufferReaderAvail(data->resp_io_buf_reader); |
| 301 | data->addBytes(avail); |
| 302 | TSIOBufferReaderConsume(data->resp_io_buf_reader, avail); |
| 303 | TSVIONDoneSet(data->r_vio, TSVIONDoneGet(data->r_vio) + avail); |
| 304 | TSVIOReenable(data->r_vio); |
nothing calls this directly
no test coverage detected