functions-framework-java icon indicating copy to clipboard operation
functions-framework-java copied to clipboard

`HttpRequest.getPath()` does not include Function name (expected: `/my-gcp-function/helloworld/`, actual `/helloworld`)

Open aSemy opened this issue 4 years ago • 0 comments

I've got a GCP Cloud Function, called call-handler. It's got a HTTP trigger. The trigger URL is

https://**location**projectname**.cloudfunctions.net/call-handler

I need to reconstruct the original URL that triggered call-handler. Let's say the original request is

https://**location**projectname**.cloudfunctions.net/call-handler/helloworld

When I log the output of HttpRequest.getPath(), it returns /helloworld, but I need it to be /call-handler/helloworld. This is what the Javadoc says it should be.

The path part of the URI for this request, without any query. If the full URI is
{@code http://foo.com/bar/baz?this=that}, then this method will return {@code /bar/baz}.

The same goes for HttpRequest.getUri(). It returns http://**location**projectname**.cloudfunctions.net/helloworld. (Note that it returns http, which is why I need to reconstruct the original request.)

Issues

The Javadoc isn't accurate, or the code is bugged?

I've posted a work around below, but it would be really useful if this library provided helper functions to accurate generate all the information.

Workaround

A programmatic way of reconstructing the original request URL is to join these strings, in order

  1. value of Header X-Forwarded-Proto (docs for headers)
  2. ://
  3. value of Header Host
  4. / (prefix for the cloud function name)
  5. environment variable K_SERVICE (docs for env-vars)
  6. HttpRequest.getPath():
    1. IFF getPath() has 1 or more elements: prepend with /
    2. join each element with /
    3. Note: no trailing /
  7. HttpRequest.getQuery():
    1. IFF getQuery() has 1 or more elements: prepend with ?
    2. join each element with &

In my case, step by step it would be

  1. https
  2. https://
  3. https://**location**projectname**.cloudfunctions.net
  4. https://**location**projectname**.cloudfunctions.net/
  5. https://**location**projectname**.cloudfunctions.net/call-handler
  6. https://**location**projectname**.cloudfunctions.net/call-handler/helloworld
    step by step of path construction:
    1. /
    2. /helloworld
    3. ...
  7. https://**location**projectname**.cloudfunctions.net/call-handler/helloworld (no change, no query params)
    1. (getQuery() is empty)
    2. (no elements to join)

It was a lot of work to figure all that out, so I thought I'd share, in case it helps someone else.

aSemy avatar Apr 21 '21 17:04 aSemy