in src/outgoing_request.c [573:688]
apr_status_t serf_connection__request_requeue(serf_request_t *request)
{
serf_request_t *discard;
serf_request_t **pr;
/* For some reason, somebody wants to restart this request, that was
at least partially written and partially read. Most likely to
slightly change it. (E.g. to add auth headers).
To handle this we have to do two things: we have to handle remaining
incoming data on the existing request. And we have to make the request
ready to write it again.. preferably as the first new request.
*/
/* Setup a new request to handle discarding the remaining body */
discard = create_request(request->conn,
NULL, NULL,
request->priority,
request->ssltunnel);
discard->respool = request->respool;
discard->allocator = request->allocator;
discard->req_bkt = request->req_bkt;
discard->resp_bkt = request->resp_bkt;
discard->setup = NULL; /* Already setup */
discard->setup_baton = NULL;
discard->acceptor = NULL;
discard->acceptor_baton = NULL; /* Already accepted */
discard->handler = discard_response_handler;
discard->handler_baton = NULL;
discard->protocol_baton = request->protocol_baton;
discard->auth_done = request->auth_done;
discard->auth_baton = request->auth_baton;
discard->writing = request->writing;
if (discard->respool) {
apr_pool_cleanup_kill(discard->respool, request, clean_resp);
apr_pool_cleanup_register(discard->respool, discard,
clean_resp, apr_pool_cleanup_null);
}
if (request->depends_on) {
/* Update request dependencies */
discard->depends_on = request->depends_on;
for (pr = &discard->depends_on->depends_first;
*pr;
pr = &(*pr)->depends_next)
{
if (*pr == request) {
*pr = discard;
discard->depends_next = request->depends_next;
request->depends_next = NULL;
request->depends_on = NULL;
break;
}
}
}
if (request->depends_first) {
serf_request_t *r;
for (r = request->depends_first; r; r = r->depends_next) {
r->depends_on = discard;
}
discard->depends_first = request->depends_first;
request->depends_first = NULL;
}
/* And now make the discard request take the place of the old request */
for (pr = &request->conn->written_reqs; *pr; pr = &(*pr)->next) {
if (*pr == request) {
*pr = discard;
discard->next = request->next;
request->next = NULL;
if (!discard->next)
request->conn->written_reqs_tail = discard;
break;
}
}
/* Tell the protocol handler (if any) that we are no longer looking at the
request */
if (request->conn->perform_cancel_request)
request->conn->perform_cancel_request(discard, SERF_ERROR_HTTP2_CANCEL);
/* And now unhook the existing request */
request->allocator = NULL;
request->respool = NULL;
request->req_bkt = NULL;
request->resp_bkt = NULL;
request->writing = SERF_WRITING_NONE;
request->auth_baton = NULL;
request->protocol_baton = NULL;
request->acceptor = NULL;
request->acceptor_baton = NULL;
request->handler = NULL;
request->handler_baton = NULL;
request->auth_done = false;
if (discard->depends_first || discard->depends_on) {
serf_connection_request_prioritize(request, discard, 0xFFFF,
TRUE);
}
insert_priority_request(request);
return APR_SUCCESS;
}