OP-Engineering / link-preview-js

⛓ Extract web links information: title, description, images, videos, etc. [via OpenGraph], runs on mobiles and node.
MIT License
770 stars 124 forks source link

Crash: getLinkPreview crashes when resolving LinkedIn profile urls #144

Closed arshad-slate closed 1 year ago

arshad-slate commented 1 year ago

Describe the bug getLinkPreview crashes while resolving LinkedIn profile urls. Eg:- https://www.linkedin.com/in/jk-digital-design?utm_source=share&utm_campaign=share_via&utm_content=profile&utm_medium=ios_app

Desktop (please complete the following information):

Smartphone (please complete the following information):

It crashes with following error: RangeError: Failed to construct 'Response': The status provided (0) is outside the range [200, 599].


node_modules/whatwg-fetch/dist/fetch.umd.jsResponse             480 16
node_modules/whatwg-fetch/dist/fetch.umd.jssetTimeout$argument_0 554 22
node_modules/react-native/Libraries/Core/Timers/JSTimers.js_allocateCallback$argument_0 214 17
node_modules/react-native/Libraries/Core/Timers/JSTimers.js_callTimer           112 6
node_modules/react-native/Libraries/Core/Timers/JSTimers.jscallTimers           357 6
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js__callFunction       417 26
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js__guard$argument_0   114 11
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js__guard              368 8
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.jscallFunctionReturnFlushedQueue 113 9
[native code]value                 
}```
ospfranco commented 1 year ago

Not an issue with the library, that linked in page is returning a 999 http (request denied) header. Here is the output of curl:

$ curl -v https://www.linkedin.com/in/jk-digital-design\?utm_source\=share\&utm_campaign\=share_via\&utm_content\=profile\&utm_medium\=ios_app
*   Trying 13.107.42.14:443...
* Connected to www.linkedin.com (13.107.42.14) port 443 (#0)
* ALPN: offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: C=US; ST=California; L=Sunnyvale; O=LinkedIn Corporation; CN=www.linkedin.com
*  start date: Jun  2 00:00:00 2023 GMT
*  expire date: Dec  2 23:59:59 2023 GMT
*  subjectAltName: host "www.linkedin.com" matched cert's "www.linkedin.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA
*  SSL certificate verify ok.
* using HTTP/2
* h2 [:method: GET]
* h2 [:scheme: https]
* h2 [:authority: www.linkedin.com]
* h2 [:path: /in/jk-digital-design?utm_source=share&utm_campaign=share_via&utm_content=profile&utm_medium=ios_app]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* Using Stream ID: 1 (easy handle 0x155812000)
> GET /in/jk-digital-design?utm_source=share&utm_campaign=share_via&utm_content=profile&utm_medium=ios_app HTTP/2
> Host: www.linkedin.com
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/2 999
< cache-control: no-cache, no-store
< pragma: no-cache
< content-length: 1530
< content-type: text/html
< expires: Thu, 01 Jan 1970 00:00:00 GMT
< set-cookie: trkCode=bf; Max-Age=5
< set-cookie: trkInfo=AQEgzTPdi3fTvwAAAYsDCbIoUtXtNL8sLbIdW5uDYCvQDkedWhA6HYHRXqwFrTVPRIjE1fu7ozX63nUN4jYp7xiRjQY2C8IY66vsy9VRTRKr0UJYrpxrD_Z1ex4oLAQWBJ-BHLU=; Max-Age=5
< set-cookie: rtc=AQFywTcHGKUO6wAAAYsDCbIoPBu5EmKKxsY0AzORtYlbg4qX85sJIAD3O3cIUA7PW0dcJZd2hw-EqPQGb8oHouGiQvIbFWpeWhkFIiuOJbnoJXwVmQ86XnN8eIrECSjiXu7xuJfvwAknz5ldNrhocJdw64f82BajXSBZ-wSfUEyCm6MlTOrwEAWg2CWgYEUXlNFfyI05Nj5oj6ITlRvueU-a6b4=; Max-Age=120; path=/; domain=.linkedin.com
< x-li-fabric: prod-lor1
< x-li-pop: afd-prod-lor1-x
< x-li-proto: http/2
< x-li-uuid: AAYHA93pxbiYhsHSi9ybPA==
< x-cache: CONFIG_NOCACHE
< x-msedge-ref: Ref A: C200A437F65B4D7C983BB2DE8DB8CF1A Ref B: MUC30EDGE0112 Ref C: 2023-10-06T03:30:49Z
< date: Fri, 06 Oct 2023 03:30:49 GMT
<
<html><head>
<script type="text/javascript">
window.onload = function() {
  // Parse the tracking code from cookies.
  var trk = "bf";
  var trkInfo = "bf";
  var cookies = document.cookie.split("; ");
  for (var i = 0; i < cookies.length; ++i) {
    if ((cookies[i].indexOf("trkCode=") == 0) && (cookies[i].length > 8)) {
      trk = cookies[i].substring(8);
    }
    else if ((cookies[i].indexOf("trkInfo=") == 0) && (cookies[i].length > 8)) {
      trkInfo = cookies[i].substring(8);
    }
  }

  if (window.location.protocol == "http:") {
    // If "sl" cookie is set, redirect to https.
    for (var i = 0; i < cookies.length; ++i) {
      if ((cookies[i].indexOf("sl=") == 0) && (cookies[i].length > 3)) {
        window.location.href = "https:" + window.location.href.substring(window.location.protocol.length);
        return;
      }
    }
  }

  // Get the new domain. For international domains such as
  // fr.linkedin.com, we convert it to www.linkedin.com
  // treat .cn similar to .com here
  var domain = location.host;
  if (domain != "www.linkedin.com" && domain != "www.linkedin.cn") {
    var subdomainIndex = location.host.indexOf(".linkedin");
    if (subdomainIndex != -1) {
      domain = "www" + location.host.substring(subdomainIndex);
    }
  }

  window.location.href = "https://" + domain + "/authwall?trk=" + trk + "&trkInfo=" + trkInfo +
      "&original_referer=" + document.referrer.substr(0, 200) +
      "&sessionRedirect=" + encodeURIComponent(window.location.href);
}
</script>
</head></html>
* Connection #0 to host www.linkedin.com left intact