Skip to content

Requests fail when the endpoint string contains case-insensitive "http" #85

@Azeirah

Description

@Azeirah

I was receiving GuzzleHttp\Exception\ClientException "BadRequest" exceptions for a large amount of the requests I was sending.

Client error: `GET https://graph.microsoft.com/me/calendarview/delta?$deltatoken={{{redacted_deltatoken}}}` resulted in a `400 Bad Request` response:
{
  "error": {
    "code": "BadRequest",
    "message": "Invalid version",
    "innerError": {
      "request-id":  (truncated...)

The request logged in the exception log was clearly wrong:

GET https://graph.microsoft.com/me/calendarview/delta?$deltatoken={{{redacted_deltatoken}}}

The problem here is that it's missing the api version parameter. But that was definitely set, why is it missing?

After two days of searching, it finally occurred to me that this part of the code is why this request is failing so bad.

Deltatokens are base-64 encoded strings. A delta token can contain the characters h, t and p. After taking a careful look at the actual deltatoken logged by my logger, I found the sequence htTP somewhere in the token.

Unfortunately, this isn't an extremely rare or one-off exception, I had several hundred instances of this exact exception.

TL;DR

stripos (found here) checks the endpoint for the (case-insensitive) string 'http', some endpoints or endpoint parameters can randomly contain the string http (or case-insensitive, like HtTP ...), and will be treated as an opaque URL, which results in a BadRequest exception.

Proposed solution?

I think the whole _getRequestUrl function is defective as a whole, I think the intention was that as you pass a full url like http://blablabla.com/bla that it would use that url instead, but it is only the endpoint, calling new GraphRequest('GET', 'http://blablabla.com/bla, ...) would result in a request sent to https://graph.microsoft.com/http://blablabla.com/bla, which doesn't make any sense to me.

I think the stripos check can just be removed.

Instead, if there is a reason for that check, check if http is found in the beginning of the string instead! i.e. stripos($this->endpoint, "http") === 0

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions