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

User-Agent fails to parse Facebook in App string #4293

Open
garyfeltham opened this issue Aug 2, 2023 · 4 comments
Open

User-Agent fails to parse Facebook in App string #4293

garyfeltham opened this issue Aug 2, 2023 · 4 comments
Labels
0 - new Ticket is unclear on it's purpose or if it is valid or not

Comments

@garyfeltham
Copy link

A user agent string provided by a Facebook in-app browser causes the parsing functions not to resolve a User-Agent header.

Based on the following user agent

Mozilla/5.0 (Linux; Android 13; SM-G981B Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.138 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/425.0.0.22.49;]

and subsequent usage of

headerValueByType(User-Agent)

Any HTTP call results in

Request is missing required HTTP header 'User-Agent'```

By removing the appended FB spec, it works: `Mozilla/5.0 (Linux; Android 13; SM-G981B Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/115.0.5790.138 Mobile Safari/537.36`

This appears related to `akka.http.impl.model.parser.SimpleHeaders`

```  // http://tools.ietf.org/html/rfc7231#section-5.5.3
  def `user-agent` = rule { products ~ EOI ~> (`User-Agent`(_)) }

which feeds into HttpRequest headers. Debugging shows that the values of the headers val headers: immutable.Seq[HttpHeader], is a RawHeader('user-agent', '...') when the FB user agent string is supplied. However, if this is cleaned the header instance is indeed a User-Agent instance, hence the extraction function appears to work.

There are some other related bugs such as guardian/support-frontend#213

My current fix is to run an adaption filter when booting the server to strip out the [FB_IAB.*] on each request however the issue appears to be in the parsing of the SimpleHeaders and its ability to instantiate the User-Agent instance based on the pattern.

@garyfeltham
Copy link
Author

Coded adaption process as

  def adaptUserAgentHeader(request: HttpRequest): HttpRequest = {

    val result = request.headers.collect {
      case h@RawHeader(_) if h.lowercaseName == "user-agent" =>
        val adaptedValue = h.value.replaceAll("\\[.*?\\]$", "")
        if (adaptedValue != h.value) `User-Agent`.parseFromValueString(adaptedValue).getOrElse(h) else h
      case h@_ => h
    }

    request.withHeaders(result)
  }
   val sb = http.newServerAt(
     serverConfigNode.getString("host"),
     serverConfigNode.getInt("port")
   )
   val adaptHeadersFlow: Flow[HttpRequest, HttpRequest, NotUsed] =
     Flow[HttpRequest].map(adaptUserAgentHeader)

   val combinedFlow: Flow[HttpRequest, HttpResponse, Any] = adaptHeadersFlow.via(flow)
   sb.bindFlow(combinedFlow)

@johanandren
Copy link
Member

Is the config akka.http.parsing.modeled-header-parsing left at the default on? (If disabled then only a very small set of essential headers are parsed into model headers and the rest is left as RawHeaders)

@johanandren
Copy link
Member

Ah, sorry, you mentioned it works as expected with another user agent string, so it is something about the value then

@johanandren
Copy link
Member

Ok, reading up a bit more it seems that the FB user-agent header value is not RFC compliant. We have previously silenced logging warnings for such (#687), but in this case you want it parsed.

I'm not sure we want to change our current stance, which is to stay aligned with RFC rather than handle special cases, especially givent that it is possible to work around (thanks for sharing workaround btw).

@johanandren johanandren added the 0 - new Ticket is unclear on it's purpose or if it is valid or not label Aug 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0 - new Ticket is unclear on it's purpose or if it is valid or not
Projects
None yet
Development

No branches or pull requests

2 participants