/** * Prepare reception of query hit data by building an appropriate RX stack. * * @return TRUE if we may continue with the download, FALSE if the search * was already closed in the GUI. */ gboolean browse_host_dl_receive( struct browse_ctx *bc, gnet_host_t *host, wrap_io_t *wio, const char *vendor, guint32 flags) { g_assert(bc != NULL); if (bc->closed) return FALSE; gnet_host_copy(&bc->host, host); bc->vendor = atom_str_get(vendor); /* * Freeing of the RX stack must be asynchronous: each time we establish * a new connection, dismantle the previous stack. Otherwise the RX * stack will be freed when the corresponding download structure is * reclaimed. */ if (bc->rx != NULL) { rx_free(bc->rx); bc->rx = NULL; } { struct rx_link_args args; args.cb = &browse_rx_link_cb; args.bws = bsched_in_select_by_addr(gnet_host_get_addr(&bc->host)); args.wio = wio; bc->rx = rx_make(bc, &bc->host, rx_link_get_ops(), &args); } if (flags & BH_DL_CHUNKED) { struct rx_chunk_args args; args.cb = &browse_rx_chunk_cb; bc->rx = rx_make_above(bc->rx, rx_chunk_get_ops(), &args); } if (flags & BH_DL_INFLATE) { struct rx_inflate_args args; args.cb = &browse_rx_inflate_cb; bc->rx = rx_make_above(bc->rx, rx_inflate_get_ops(), &args); } rx_set_data_ind(bc->rx, browse_data_ind); rx_enable(bc->rx); return TRUE; }
/** * Prepare reception of THEX data by building an appropriate RX stack. * * @return TRUE if we may continue with the download. */ bool thex_download_receive(struct thex_download *ctx, filesize_t content_length, gnet_host_t *host, struct wrap_io *wio, uint32 flags) { g_assert(ctx != NULL); gnet_host_copy(&ctx->host, host); /* * Freeing of the RX stack must be asynchronous: each time we establish * a new connection, dismantle the previous stack. Otherwise the RX * stack will be freed when the corresponding download structure is * reclaimed. */ if (ctx->rx != NULL) { rx_free(ctx->rx); ctx->rx = NULL; } /* * If there is a Content-Length indication in the HTTP reply, it is * supplied here and will be used as a limit of the data we'll read. * * If there was none (for instance if the output is chunked), then 0 * is given and we'll use a hardwired maximum. */ if (content_length > MAX_INT_VAL(size_t)) return FALSE; ctx->max_size = content_length ? (size_t) content_length : THEX_DOWNLOAD_MAX_SIZE; { struct rx_link_args args; args.cb = &thex_rx_link_cb; args.bws = bsched_in_select_by_addr(gnet_host_get_addr(&ctx->host)); args.wio = wio; ctx->rx = rx_make(ctx, &ctx->host, rx_link_get_ops(), &args); } if (flags & THEX_DOWNLOAD_F_CHUNKED) { struct rx_chunk_args args; args.cb = &thex_rx_chunk_cb; ctx->rx = rx_make_above(ctx->rx, rx_chunk_get_ops(), &args); } if (flags & THEX_DOWNLOAD_F_INFLATE) { struct rx_inflate_args args; args.cb = &thex_rx_inflate_cb; ctx->rx = rx_make_above(ctx->rx, rx_inflate_get_ops(), &args); } rx_set_data_ind(ctx->rx, thex_download_data_ind); rx_enable(ctx->rx); return TRUE; }