In my GCP project am a doing a Host and path rules redirect on one of my load balancers. I am trying to get the redirect to pass the query parameters, but it is not.
Essentially trying to do:
subdomain.domain.com?foo=bar -> www.domain.com/path?foo=bar.
The redirect works to the path, but it does not keep the query params. From what I can see here, it should work.
https://cloud.google.com/load-balancing/docs/https/traffic-management#redirects
Redirect to a different URL formed by modifying the host, path, or both the host and path portion of the URL, and either stripping out or retaining any query parameters.
In Google Cloud, the stripQuery field can also be used with a Load Balancer, specifically the GCP HTTP(S) Load Balancer. This feature allows you to configure whether the query string present in the incoming request's URL will be included or removed when the request is forwarded to a backend service.
When stripQuery is set to false, the query string will be included in
the path when forwarding traffic to the backend service.
i.e: if a request is made to "example.com/path?key=value", and stripQuery is set to false, the request will be forwarded to the backend service as if it were made to "example.com/path?key=value".
By disabling the stripQuery feature in Google Cloud Load balancer we can forward the query params to the new host we have redirected to.
Here is a configuration YAML we can use to redirect the site to another site preserving the query parameters.
defaultService: projects/example/global/backendServices/example-test
name: example-matcher1
routeRules:
- urlRedirect:
stripQuery: false
hostRedirect: ie.example.com
redirectResponseCode: MOVED_PERMANENTLY_DEFAULT
If you are using DefaultRedirect in Advanced host and path rule:
You should uncheck the Strip query in Google Cloud Load Balancer Edit Page for Advanced Route Rules Routing Rules .
Reference:
enter image description here
I followed the guide to set up an external global, app engine based, load balancer. I linked it to Google's CDN by ticking the little box in the LB configuration settings.
Now, when I load my domain name, it says CANNOT GET /. The request returns a 404, along with some C S P: The page’s settings blocked the loading of a resource at inline (“default-src”). error messages.
It was working well before adding the CDN. So, I'm assuming my app server configuration is fine.
In the Load Balancer details, there is a little chart under the Monitoring section, with how traffic flows.
It shows traffic coming from the 3 global regions, going to the frontend of the LB, then to / (unknown) and / (unmatched) as URL Rule, then to the backend service I defined, and finally to a backend instance labelled NO_BACKEND_SELECTED.
I'm guessing the issue comes either from the URL Rule or Backend Instance, but there is little in the doc. to troubleshoot.
I followed the doc. to setup the LB. Settings are pretty simple using App Engine, so there is little room for wrong doing. But I may have missed something still.
In the 'create serverless NEG', I did select App Engine, and default as the service name (although i'm not sure what default actually means).
Any idea what's missing ?
EDIT :
So, in the load balancing menu, I go to the 'Backends' section at the top, and select my backend. Here I have the list of 'General properties' of my backend. Except, under 'Backends', it says the following : Backends contain instance groups of VMs or network endpoint groups. This backend service has no backends yet edit
From there, I can click the edit link, which redirects me to the 'Backend service edit' menu. I DO have a backend selected in there. I did create a serverless NEG using App Engine.
So, what's missing ? Is there anything wrong with Google's serverless backend ?
I wanna help you with the issue that you are facing.
If the responses from your external backend are not cached by Cloud CDN
Ensure that:
-You have enabled Cloud CDN on the backend service containing the NEG that points to your external backend by setting enableCDN to true. (DONE as per your description).
-Responses served by your external backend meet Cloud CDN caching requirements. For example, you are sending Cache-Control: public, max-age=3600 response headers from the origin.
The current implementation of Cloud CDN stores responses in cache if all of the following are true.
Attribute:
Served by
Requirement:
Backend service, backend bucket, or an external backend with Cloud CDN enabled
Attribute:
In response to
Requirement:
GET request
Attribute:
Status code
Requirement:
200, 203, 204, 206, 300, 301, 302, 307, 308, 404, 405, 410, 421, 451, or 501.
Attribute:
Freshness
Requirement:
The response has a Cache-Control header with a max-age or s-maxage directive, or an Expires header with a timestamp in the future.
For cacheable responses without an age (for example, with no-cache), the public directive must be explicitly provided.
With the CACHE_ALL_STATIC cache mode, if no freshness directives are present, a successful response with static content type is still eligible for caching.
With the FORCE_CACHE_ALL cache mode, any successful response is eligible for caching.
If negative caching is enabled and the status code matches one for which negative caching specifies a TTL, the response is eligible for caching, even without explicit freshness directives.
Attribute:
Content
Requirement:
Contains a valid Content-Length, Content-Range, or Transfer-Encoding: chunked header.
For example, a Content-Length header that correctly matches the size of the response.
Attribute:
Size
Requirement:
Less than or equal to the maximum size.
For responses with sizes between 10 MB and 5 TB, see the additional cacheability constraints described in byte range requests.
Please validate the URL Mapping too:
This is an example as reference adapt this according your project.
Create a YAML file /tmp/http-lb.yaml, making sure to substitute PROJECT_ID with your project ID.
When a user requests path /*, the path gets rewritten in the backend to the actual location of the content, which is /love-to-fetch/*.
defaultService: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendBuckets/cats
hostRules:
- hosts:
- '*'
pathMatcher: path-matcher-1
name: http-lb
pathMatchers:
- defaultService: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendBuckets/cats
name: path-matcher-1
pathRules:
- paths:
- /*
routeAction:
urlRewrite:
pathPrefixRewrite: /love-to-fetch/
service: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendBuckets/dogs
tests:
- description: Test routing to backend bucket, dogs
host: example.com
path: /love-to-fetch/test
service: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendBuckets/dogs
Validate the URL map.
gcloud compute url-maps validate --source /tmp/http-lb.yaml
If the tests pass and the command outputs a success message, save the changes to the URL map.
Update the URL map.
gcloud compute url-maps import http-lb \
--source /tmp/http-lb.yaml \
--global
Using URL maps
I have been testing GCP's API Gateway and found a problem in handling my Django's REST APIs running on GAE.
I got ERR_TOO_MANY_REDIRECTS error when accessed the API with the URL generated by the Gateway (it's like https://gw--fake-test-xyz9ry1.uk.gateway.dev/hello).
My Gateway's API Config looks like below (Note: all URLs are fake):
swagger: '2.0'
info:
title: test-01
description: Sample APIs through API Gateway with GAE
version: 1.0.0
schemes:
- https
produces:
- application/json
paths:
/hello:
get:
summary: Just a simple get function
operationId: hello
x-google-backend:
address: https://myfakeapp.uk.a.appspot.com/hello/
responses:
'200':
description: A successful response
schema:
type: string
I confirmed that the access to the original GAE's API (https://myfakeapp.uk.a.appspot.com/hello/) worked fine.
My guess was that Django's APPEND_SLASH setting was trying to append a slash and it caused the redirection trouble.
To solve it, I set APPEND_SLASH = False in settings.py in Django and redeployed the GAE app and recreated the Gateway.
Since the URL with slash was set in the x-google-backend address, I thought the Gateway would transfer the request to that address.
When I accessed the API with the GW's URL, however, the response was 404 error saying the request URL was https://myfakeapp.uk.a.appspot.com/hello (Note that there is no trailing slash in this URL).
The slash in the x-google-backend address value in API Config seemed to be ignored.
How can I map Django's APIs to the Gateway's URLs without problems?
I was able to map my Cloud Run's API (which is Flask-based) to the Gateway, but I need to use the APIs by Django running on GAE.
I had the same issue deploying Django Rest Framework #DRF with Google API Gateway. and here is how I solved it:
Setting APPEND_SLASH = False in your settings.py file.
Removed slashes from urls inside the code itself.
Make sure to remove slashes in API paths.
Here is a snippet from the config file:
paths:
/movie:
get:
x-google-backend:
address: https://XXXXXXX.a.run.app/api/v1/movie
NOTE:
This will led to 404 when calling the backend directly if a trailing slash enforced from, may be, the browser, but curl will continue works fine.
I have a zuul routing app deployed on the cloud. Below in my application.yml
---
spring:
profiles: default
zuul:
routes:
cloud:
path: /cardsvcs/acs/**
sensitiveHeaders:
url: https://vst0.mapi.checkFin.com/
stripPrefix: false
ribbon:
eureka:
enabled: false
Routing works perfectly fine and I also get the response headers back from the back end service. The requestContext originResponseHeaders also have all the cookies as part of setCookie header. But these cookies are not visible on the Postman response after routing.
Do we need to gets the cookies from this header in the filter and map them again?
Please try the below.
zuul.sensitiveHeaders: Authorization
The sentive-headers that are configured in zuul are not passed to downstream servers. And below three headers are defaults.
zuul.sensitiveHeaders: Cookie,Set-Cookie,Authorization
To pass cookie related headers to your downstream server, you need to redefine above propeprties.
Please refer to the section 'Cookies and Sensitive Headers' in the the linked doc : http://cloud.spring.io/spring-cloud-static/Dalston.RELEASE/
So I need to debug the startup of an Azure Web Role Service running MVC that has been configured to use SSL.
Ive got the endpoints set in the .csdef , I'm running in Admin mode, I've got IIS Express selected.
My app gets to Application_Start() where it successfully
RegisterAllAreas();
ConfigureIdentity();
WebApiConfig.Register(GlobalConfig);
RegisterRoutes();
RegisterBundles();
App_start returns successfully - and the next thing I hit is the App_error exception
ID1059: Cannot Authenticate the user because the URL Scheme is not https and requiredSSL is set to True in the configuration.
the URL showing is http: // localhost:4680 which I know is wrong since it should be https since for the WebApp project I've got the following properties set
SSL Enabled = True
SSL URL - https: // localhost:44303
URL is http: // localhost4680
If I right click on the WebApp project and go to the WEB tab, under Servers I've got set IIS as the server
projectURL is http: // localhost:4680
I've tried changing the Project URL to
https: // localhost:4680
https: // Localhost:444
https: // localhost:443
https: // localhost:44300
https: // Localhost:44303
and all of those blow up before they get to Application_start()
I've tried googling this everywhere and I know what I'm missing is something really simple. but for the life of me I cannot remember what it is (I've not had to debug this in 6 mos - and I'm more of a back-end SQL server guy)