Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for gone links #48067

Merged
merged 1 commit into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion src/handler/httpsession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ class HttpSession::Private : public QObject
Proxying,
SendingQueue,
Holding,
Closing
Closing,
SendingGone,
};

enum Priority
Expand Down Expand Up @@ -165,6 +166,7 @@ class HttpSession::Private : public QObject
QString errorMessage;
QUrl currentUri;
QUrl nextUri;
QUrl goneUri;
bool needUpdate;
Priority needUpdatePriority;
UpdateAction *pendingAction;
Expand Down Expand Up @@ -231,6 +233,12 @@ class HttpSession::Private : public QObject

if(!instruct.nextLink.isEmpty())
nextUri = currentUri.resolved(instruct.nextLink);

// only work with a gone link provided at initialization time. this
// way each request can have a unique gone link, and still share
// instructions from next link fetches
if(!instruct.goneLink.isEmpty())
goneUri = currentUri.resolved(instruct.goneLink);
}

~Private()
Expand Down Expand Up @@ -1168,6 +1176,23 @@ class HttpSession::Private : public QObject
stats->removeConnection(cid, false);
}

if(!goneUri.isEmpty())
{
state = SendingGone;
prepareOutReq(goneUri);
outReq->start("POST", goneUri, HttpHeaders());
outReq->endBody();
return;
}

finished();
}

void finished()
{
ZhttpRequest::Rid rid = req->rid();
QByteArray cid = rid.first + ':' + rid.second;

log_debug("httpsession: cleaning up %s", cid.data());
cleanup();

Expand Down Expand Up @@ -1361,6 +1386,25 @@ class HttpSession::Private : public QObject
}
}
}
else if(state == SendingGone)
{
// response should be empty
if(outReq->bytesAvailable() > 0)
{
outReq_error();
return;
}

if(outReq->isFinished())
{
logRequest(outReq->requestMethod(), outReq->requestUri(), outReq->requestHeaders(), outReq->responseCode(), 0);

cleanupOutReq();

finished();
return;
}
}
else
{
// unexpected state
Expand Down Expand Up @@ -1558,6 +1602,11 @@ private slots:
doError();
}
}
else if(state == SendingGone)
{
log_debug("httpsession: failed to request gone link");
finished();
}
else
{
// unexpected state
Expand Down
6 changes: 6 additions & 0 deletions src/handler/instruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ Instruct Instruct::fromResponse(const HttpResponseData &response, bool *ok, QStr

QUrl nextLink;
int nextLinkTimeout = -1;
QUrl goneLink;
foreach(const HttpHeaderParameters &params, response.headers.getAllAsParameters("Grip-Link"))
{
if(params.count() < 2)
Expand Down Expand Up @@ -332,6 +333,10 @@ Instruct Instruct::fromResponse(const HttpResponseData &response, bool *ok, QStr
nextLinkTimeout = DEFAULT_NEXTLINK_TIMEOUT;
}
}
else if(rel == "gone")
{
goneLink = link;
}
}

newResponse.headers.clear();
Expand Down Expand Up @@ -806,6 +811,7 @@ Instruct Instruct::fromResponse(const HttpResponseData &response, bool *ok, QStr
i.response = newResponse;
i.nextLink = nextLink;
i.nextLinkTimeout = nextLinkTimeout;
i.goneLink = goneLink;

if(ok)
*ok = true;
Expand Down
1 change: 1 addition & 0 deletions src/handler/instruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class Instruct
HttpResponseData response;
QUrl nextLink;
int nextLinkTimeout;
QUrl goneLink;

Instruct() :
holdMode(NoHold),
Expand Down
2 changes: 1 addition & 1 deletion src/proxy/proxyutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ void manipulateRequestHeaders(const char *logprefix, void *object, HttpRequestDa

requestData->headers.removeAll("Grip-Feature");
requestData->headers += HttpHeader("Grip-Feature",
"status, session, link:next, filter:skip-self, filter:skip-users, filter:require-sub, filter:build-id, filter:var-subst");
"status, session, link:next, link:gone, filter:skip-self, filter:skip-users, filter:require-sub, filter:build-id, filter:var-subst");

if(!idata.sid.isEmpty())
{
Expand Down