Uploaded image for project: 'Bitbucket Server'
  1. Bitbucket Server
  2. BSERV-11456

Cannot make API requests with XMLHttpRequest in Electron

    XMLWordPrintable

    Details

    • Feedback Policy:
      We collect Bitbucket feedback from various sources, and we evaluate what we've collected when planning our product roadmap. To understand how this piece of feedback will be reviewed, see our Implementation of New Features Policy.

      Description

      NOTE: Atlassian support specifically instructed me to file a bug report here. Jira prevented me from categorizing it as a bug, insisting that I contact support instead. There seems to be a lot of confusion regarding the process for entering legitimate bugs into this tracker.

      We're an Electron app and we're using XMLHttpRequest because then the behavior vis-a-vis SSL certificates and proxy settings are identical to Chrome, which is immensely helpful to our end users because as long as they can reach their Bitbucket instance in Chrome, they know that our Electron app's API integration will also work without a lot of extra configuration.

      We're trying to use Personal Access Tokens to talk to the REST API for Bitbucket Server (v5.15.0) and getting back a 500. The issue seems to be that the Origin header sent by Electron is file:// because Electron apps are not actually websites.

      The relevant line appears to throw the origin header straight into java.net.URI.create, and since file:// isn't much of a URI, it makes sense that Java is throwing an error. Note that we have a default installation with no special CORS settings.

      Unfortunately, XHR is fundamentally a browser technology, and as such changing the origin header is forbidden to prevent cross-site attacks.

      We are currently investigating using an API exposed in Electron but not exposed to browsers, which lets us do unsafe things, but a simple XHR call ought to work. Regardless of our particular issue, a well-configured server should never throw a Java error and return a 500 if it can help it, no matter how awful the request headers are.

      The full stack trace follows:

      2018-11-26 08:50:33,071 ERROR [http-nio-7990-exec-9] myusername *REDACTED* "POST /rest/api/1.0/users/myusername/repos HTTP/1.1" c.a.s.i.r.e.DefaultUnhandledExceptionMapperHelper Unhandled exception while processing REST request: "POST /rest/api/1.0/users/myusername/repos HTTP/1.1"
      java.lang.IllegalArgumentException: Expected authority at index 7: file://
          at java.net.URI.create(URI.java:852)
          at com.atlassian.applinks.cors.auth.DefaultCorsService.getApplicationLinksByOrigin(DefaultCorsService.java:50)
          at com.atlassian.applinks.cors.auth.AppLinksCorsDefaults.allowsOrigin(AppLinksCorsDefaults.java:39)
          at com.google.common.collect.Iterators.indexOf(Iterators.java:778)
          at com.google.common.collect.Iterators.any(Iterators.java:684)
          at com.google.common.collect.Iterables.any(Iterables.java:623)
          at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
          at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
          at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
          at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
          at com.atlassian.applinks.core.rest.context.ContextFilter.doFilter(ContextFilter.java:24)
          at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
          at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
          at com.atlassian.stash.internal.spring.security.StashAuthenticationFilter.doFilter(StashAuthenticationFilter.java:85)
          at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doInsideSpringSecurityChain(BeforeLoginPluginAuthenticationFilter.java:112)
          at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doFilter(BeforeLoginPluginAuthenticationFilter.java:75)
          at com.atlassian.security.auth.trustedapps.filter.TrustedApplicationsFilter.doFilter(TrustedApplicationsFilter.java:94)
          at com.atlassian.oauth.serviceprovider.internal.servlet.OAuthFilter.doFilter(OAuthFilter.java:67)
          at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
          at com.atlassian.bitbucket.internal.scm.git.lfs.servlet.filter.GitLfsLockingFilter.doFilter(GitLfsLockingFilter.java:50)
          at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
          at com.atlassian.security.auth.trustedapps.filter.TrustedApplicationsFilter.doFilter(TrustedApplicationsFilter.java:94)
          at com.atlassian.oauth.serviceprovider.internal.servlet.OAuthFilter.doFilter(OAuthFilter.java:67)
          at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
          at com.atlassian.plugin.connect.plugin.auth.oauth2.DefaultSalAuthenticationFilter.doFilter(DefaultSalAuthenticationFilter.java:69)
          at com.atlassian.plugin.connect.plugin.auth.user.ThreeLeggedAuthFilter.doFilter(ThreeLeggedAuthFilter.java:109)
          at com.atlassian.jwt.internal.servlet.JwtAuthFilter.doFilter(JwtAuthFilter.java:32)
          at com.atlassian.analytics.client.filter.DefaultAnalyticsFilter.doFilter(DefaultAnalyticsFilter.java:38)
          at com.atlassian.analytics.client.filter.AbstractHttpFilter.doFilter(AbstractHttpFilter.java:39)
          at com.atlassian.bitbucket.internal.scm.git.lfs.servlet.filter.GitLfsLockingFilter.doFilter(GitLfsLockingFilter.java:50)
          at com.atlassian.stash.internal.spring.lifecycle.LifecycleJohnsonServletFilterModuleContainerFilter.doFilter(LifecycleJohnsonServletFilterModuleContainerFilter.java:42)
          at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doBeforeBeforeLoginFilters(BeforeLoginPluginAuthenticationFilter.java:90)
          at com.atlassian.stash.internal.web.auth.BeforeLoginPluginAuthenticationFilter.doFilter(BeforeLoginPluginAuthenticationFilter.java:73)
          at com.atlassian.stash.internal.request.DefaultRequestManager.doAsRequest(DefaultRequestManager.java:90)
          at com.atlassian.stash.internal.hazelcast.ConfigurableWebFilter.doFilter(ConfigurableWebFilter.java:38)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
          at java.lang.Thread.run(Thread.java:748)
          ... 285 frames trimmed
      Caused by: java.net.URISyntaxException: Expected authority at index 7: file://
          at java.net.URI$Parser.fail(URI.java:2848)
          at java.net.URI$Parser.failExpecting(URI.java:2854)
          at java.net.URI$Parser.parseHierarchical(URI.java:3102)
          at java.net.URI$Parser.parse(URI.java:3053)
          at java.net.URI.<init>(URI.java:588)
          at java.net.URI.create(URI.java:850)
          ... 37 common frames omitted
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              bturner Bryan Turner
              Reporter:
              jjwallet Yugi Cardman
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: