Related
I have GAE flexible this app.yaml:
# [START runtime]
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT ******.wsgi
automatic_scaling:
min_num_instances: 2
max_num_instances: 2
beta_settings:
cloud_sql_instances: ******:europe-west6:*******
runtime_config:
python_version: 3
handlers:
- url: /.*
script: auto
secure: always
redirect_http_response_code: 301
# [END runtime]
After standard instance weekly restarting, I've seen some internal errors in logs and 502 errors on POST requests:
{
"insertId": "2",
"jsonPayload": {...},
"timestamp": "2022-05-14T08:34:42.512018934Z",
"severity": "ERROR",
"logName": "projects/****/logs/compute.googleapis.com%2Fshielded_vm_integrity",
"receiveTimestamp": "2022-05-14T08:34:44.518408254Z"
}
and
{
"insertId": "*******",
"jsonPayload": {
"remoteIp": "******",
"#type": "type.googleapis.com/google.cloud.loadbalancing.type.LoadBalancerLogEntry",
"statusDetails": "backend_connection_closed_before_data_sent_to_client"
},
"httpRequest": {
"requestMethod": "POST",
"requestUrl": "https://*********",
"requestSize": "2208",
"status": 502,
"responseSize": "451",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0",
"remoteIp": "*******",
"referer": "********",
"serverIp": "********"
},
"resource": {
"type": "http_load_balancer",
"labels": {
"url_map_name": "",
"target_proxy_name": "",
"zone": "global",
"project_id": "********",
"backend_service_name": "********",
"forwarding_rule_name": ""
}
},
"timestamp": "2022-05-14T08:36:28.064500Z",
"severity": "WARNING",
"logName": "projects/********/logs/requests",
"trace": "projects/********/traces/********",
"receiveTimestamp": "2022-05-14T08:36:28.882230792Z",
"spanId": "********"
}
Also I have some messages with
/readiness_check failReason:"null"
I've read Tuning NGINX behind Google Cloud Platform HTTP(S) Load Balancer But as I understand it is related to GCE(not GAE).
For the current app it is VERY important to handle every request, so I want to be confident with fixing it.
I am struggling with Xdebug + WSL2 + CakePHP 3 + VSCode. Checking the debug console it seems that I have running Xdebug correctly, but when I run a script in the browser, the Xdebug is not launched. This is the code:
Note: I forgot to mention that I am working on docker, that's why the "0.0.0.0" in the hostname parameter.
This is the xdebug.ini
zend_extension=xdebug
[xdebug]
zend_extension=xdebug
xdebug.mode=develop,debug
xdebug.client_host='host.docker.internal'
xdebug.start_with_request=yes
xdebug.client_port = 9003
xdebug.start_with_request=yes
xdebug.log=/var/log/xdebug/xdebug.log
xdebug.connect_timeout_ms=2000
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"hostname": "0.0.0.0",
"pathMappings": {
"/webroot": "${workspaceRoot}"
},
"log": true
},
{
"name": "Launch currently open script",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 0,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
},
{
"name": "Launch Built-in web server",
"type": "php",
"request": "launch",
"runtimeArgs": [
"-dxdebug.mode=debug",
"-dxdebug.start_with_request=yes",
"-S",
"localhost:0"
],
"program": "",
"cwd": "${workspaceRoot}",
"port": 9003,
"serverReadyAction": {
"pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
"uriFormat": "http://localhost:%s",
"action": "openExternally"
}
}
]
}
This is the debug console:
Listening on { address: '0.0.0.0', family: 'IPv4', port: 9003 }
<- launchResponse
Response {
seq: 0,
type: 'response',
request_seq: 2,
command: 'launch',
success: true
}
<- initializedEvent
InitializedEvent { seq: 0, type: 'event', event: 'initialized' }
-> setBreakpointsRequest
{
command: 'setBreakpoints',
arguments: {
source: {
name: 'index.php',
path: '/root/server/webroot/index.php'
},
lines: [ 40 ],
breakpoints: [ { line: 40 } ],
sourceModified: false
},
type: 'request',
seq: 3
}
<- setBreakpointsResponse
Response {
seq: 0,
type: 'response',
request_seq: 3,
command: 'setBreakpoints',
success: true,
body: {
breakpoints: [
{
verified: true,
line: 40,
source: {
name: 'index.php',
path: '/root/server/webroot/index.php'
},
id: 1
}
]
}
}
The xdebug.log file
[20] Log opened at 2022-05-16 04:42:03.776649
[20] [Step Debug] INFO: Connecting to configured address/port: host.docker.internal:9003.
[20] [Step Debug] INFO: Connected to debugging client: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port). :-)
[20] [Step Debug] -> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///var/www/html/webroot/info.php" language="PHP" xdebug:language_version="7.4.19" protocol_version="1.0" appid="20"><engine version="3.1.2"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2021 by Derick Rethans]]></copyright></init>
[20] [Step Debug] <- feature_set -i 1 -n resolved_breakpoints -v 1
[20] [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="1" feature="resolved_breakpoints" success="1"></response>
[20] [Step Debug] <- run -i 12
[20] [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="run" transaction_id="12" status="stopping" reason="ok"></response>
[20] [Step Debug] <- stop -i 13
[20] [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="stop" transaction_id="13" status="stopped" reason="ok"></response>
[20] Log closed at 2022-05-16 04:42:03.812679
UPDATE: Following this suggestion (I got from this link, by HolyGonzo) https://www.reddit.com/r/PHPhelp/comments/rqiw4h/need_help_troubleshooting_xdebug_configuration/ I added xdebug_break(); to my code, and then the debugger started working. It is pretty clear to understand that the issue it is in the VSCode configuration not in Xdebug.
SOLUTION:
After fight with this thing a few days, finally I found the issue:
In the launch.json in VSCode I updated this line and it works!!! (note that my path was wrong :( I had this "/var/www/webroot" instead of "/var/www/html/webroot").
"pathMappings": {
"/var/www/html/webroot": "${workspaceFolder}/webroot"
},
Update:
In order to allows Xdebug to look into the vendors folder, and the other folders outside /webroot, the code needs to be upated as follows (in my case, regarding to my server paths):
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 5902,
"hostname": "localhost",
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
},
"log": true
}
I'm building an API using Google Cloud Endpoints Framework v2 on Python App Engine Standard.
Using Endpoints Framework means you can automatically generate OpenAPI / Swagger documentation directly from the code.
However I am unable to work out how to generate descriptions for each of the parameters (each field in a message) in the API directly from the code.
It's possible to generate a description for the entire API but not for each individual parameter.
Using Cloud Endpoints Framework Echo as an example:
"""This is a sample Hello World API implemented using Google Cloud
Endpoints."""
# [START imports]
import endpoints
from protorpc import message_types
from protorpc import messages
from protorpc import remote
# [END imports]
# [START messages]
class EchoRequest(messages.Message):
content = messages.StringField(1)
class EchoResponse(messages.Message):
"""A proto Message that contains a simple string field."""
content = messages.StringField(1)
ECHO_RESOURCE = endpoints.ResourceContainer(
EchoRequest,
n=messages.IntegerField(2, default=1))
# [END messages]
# [START echo_api]
#endpoints.api(name='echo', version='v1')
class EchoApi(remote.Service):
#endpoints.method(
# This method takes a ResourceContainer defined above.
ECHO_RESOURCE,
# This method returns an Echo message.
EchoResponse,
path='echo',
http_method='POST',
name='echo')
def echo(self, request):
output_content = ' '.join([request.content] * request.n)
return EchoResponse(content=output_content)
#endpoints.method(
# This method takes a ResourceContainer defined above.
ECHO_RESOURCE,
# This method returns an Echo message.
EchoResponse,
path='echo/{n}',
http_method='POST',
name='echo_path_parameter')
def echo_path_parameter(self, request):
output_content = ' '.join([request.content] * request.n)
return EchoResponse(content=output_content)
#endpoints.method(
# This method takes a ResourceContainer defined above.
message_types.VoidMessage,
# This method returns an Echo message.
EchoResponse,
path='echo/getApiKey',
http_method='GET',
name='echo_api_key')
def echo_api_key(self, request):
return EchoResponse(content=request.get_unrecognized_field_info('key'))
#endpoints.method(
# This method takes an empty request body.
message_types.VoidMessage,
# This method returns an Echo message.
EchoResponse,
path='echo/getUserEmail',
http_method='GET',
# Require auth tokens to have the following scopes to access this API.
scopes=[endpoints.EMAIL_SCOPE],
# OAuth2 audiences allowed in incoming tokens.
audiences=['your-oauth-client-id.com'])
def get_user_email(self, request):
user = endpoints.get_current_user()
# If there's no user defined, the request was unauthenticated, so we
# raise 401 Unauthorized.
if not user:
raise endpoints.UnauthorizedException
return EchoResponse(content=user.email())
# [END echo_api]
# [START api_server]
api = endpoints.api_server([EchoApi])
# [END api_server]
This is the accompanying swagger documentation that has been generated:
{
"basePath": "/_ah/api",
"consumes": [
"application/json"
],
"definitions": {
"MainEchoRequest": {
"properties": {
"content": {
"type": "string"
}
},
"type": "object"
},
"MainEchoResponse": {
"properties": {
"content": {
"type": "string"
}
},
"type": "object"
}
},
"host": "echo-api.endpoints.8085-dot-3333519-dot-5002-dot-devshell.appspot.com",
"info": {
"title": "echo",
"version": "v1"
},
"paths": {
"/echo/v1/echo": {
"post": {
"operationId": "EchoApi_echo",
"parameters": [
{
"in": "body",
"name": "body",
"schema": {
"$ref": "#/definitions/MainEchoRequest"
}
},
{
"default": 1,
"format": "int64",
"in": "query",
"name": "n",
"type": "string"
}
],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
}
}
},
"/echo/v1/echo/getApiKey": {
"get": {
"operationId": "EchoApi_echoApiKey",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
}
}
},
"/echo/v1/echo/getUserEmail": {
"get": {
"operationId": "EchoApi_getUserEmail",
"parameters": [],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
},
"security": [
{
"google_id_token-c0b0c9d9": []
}
]
}
},
"/echo/v1/echo/{n}": {
"post": {
"operationId": "EchoApi_echoPathParameter",
"parameters": [
{
"in": "body",
"name": "body",
"schema": {
"$ref": "#/definitions/MainEchoRequest"
}
},
{
"default": 1,
"format": "int64",
"in": "path",
"name": "n",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "A successful response",
"schema": {
"$ref": "#/definitions/MainEchoResponse"
}
}
}
}
}
},
"produces": [
"application/json"
],
"schemes": [
"https"
],
"securityDefinitions": {
"google_id_token": {
"authorizationUrl": "",
"flow": "implicit",
"type": "oauth2",
"x-google-issuer": "https://accounts.google.com",
"x-google-jwks_uri": "https://www.googleapis.com/oauth2/v3/certs"
},
"google_id_token-c0b0c9d9": {
"authorizationUrl": "",
"flow": "implicit",
"type": "oauth2",
"x-google-audiences": "your-oauth-client-id.com",
"x-google-issuer": "https://accounts.google.com",
"x-google-jwks_uri": "https://www.googleapis.com/oauth2/v3/certs"
}
},
"swagger": "2.0"
}
In the example above I'm looking to try and include a description for the content field in the EchoResponse and EchoRequest message types.
This could be done manually by navigating the OpenAPI specification path --> /echo/v1/echo --> parameters and adding in a description key/field there -
but can it be generated through the code?
Unfortunately, Endpoints Frameworks does not currently support this. The alternative you suggested of manually adding the description is the only way right now.
I've got an app based on djangoappengine, Backbone.js and Django REST Framework that uses PATCH requests to update models via {patch: true} on a model.save call.
I've found that when testing locally the dev_appserver returns:
ERROR 2014-02-19 04:37:04,531 dev_appserver.py:3081] code 501, message Unsupported method ('PATCH')
INFO 2014-02-19 04:37:04,532 dev_appserver.py:3090] "PATCH /api/posts/5707702298738688 HTTP/1.1" 501 -
Yet when I deploy it and access it through appspot the server happily accepts the request. Which forces me to deploy every time I make a change and want to test it.
I'm running the latests version (1.89) of the Python SDK, and found and old fixed issue that seems to tackle it but it seems other people have had it.
I tried this patch but it didn't make a difference. I don't understand why the development server would reject them and not the production server, is there something I need to change?
Thanks.
To update a resource, you can use POST with the x-http-method-override to patch. This is a valid RESTful operation and using POST will be more compatible with firewall and older user agents. The data in the request should indicate what is to be updated.
var url = '/api/posts/5707702298738688'
var patch_ops = [
{ "op": "replace", "path": "/properties/", "author": text}
{ "op": "add", "path": "/replies/", {"author": text, "comment":"blah"}}
/*
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
*/
];
var xhr = jQuery.ajax({
type: "POST",
beforeSend: function (request)
{
request.setRequestHeader("X-HTTP-Method-Override", "PATCH");
},
url: url,
data: my_json_string,
dataType:"json",
success: function(data) {
return data;
},
error: function(xhr, textStatus, error){
return error;
}
});
Server handler:
def post(self, object_name):
if self.request.headers['x-http-method-override'] == 'PATCH':
# update according to patch operations
patch_ops_str= self.request.body.decode('utf-8')
try:
patch_ops = json.loads(new_area_geojson_str)
except:
self.response.set_status(400)
return self.response.out.write('{"status": "error", "reason": "JSON Parse error" }')
else:
self.response.set_status(405)
return self.response.out.write('{"status": "error", "reason": "post not accepted without x-http-method-override to PATCH" }')
Adapted from Please do not patch like an idiot
I'm occasionally seeing a failed XMLHttpRequest.send(). From Chrome's network panel I'm seeing a status of 0 - see below from the .har file. The code that runs the send() succeeds >99% of the time, but very occasionally (~ 1/300) it returns 0.
My question is: how do I catch this? Is there are callback that will catch it?
I'm currently using onload and onerror:
var xhr = new XMLHttpRequest();
xhr.onload = function(){};
xhr.onerror = function(){};
Neither of those are being called, so it's failing silently.
A few other things to note:
There is no evidence of the request in the server logs
There are no error messages in Chrome's console
The server is google app engine
Here's the .har file output. ##=redacted.
{
"startedDateTime": "2013-03-30T23:52:20.972Z",
"time": 97,
"request": {
"method": "GET",
"url": "https://www.#######.com/project/auth_upload?to_sign=PUT%0A%0A%0A%0Ax-amz-date%3ASat%2C%2030%20Mar%202013%2023%3A52%3A20%20GMT%0A/s3.#####.com/######.mp4%3FpartNumber%3D50%26uploadId%3D#################.w--&asset_id=#############&project_id=###########",
"httpVersion": "HTTP/1.1",
"headers": [
{
"name": "Referer",
"value": "https://www.######.com/console/###########"
},
{
"name": "User-Agent",
"value": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22"
}
],
"queryString": [
{
"name": "to_sign",
"value": "PUT%0A%0A%0A%0Ax-amz-date%3ASat%2C%2030%20Mar%202013%2023%3A52%3A20%20GMT%0A/s3.#######.com/############.mp4%3FpartNumber%3D50%26uploadId%3D##############"
},
{
"name": "asset_id",
"value": "###########"
},
{
"name": "project_id",
"value": "###############"
}
],
"cookies": [],
"headersSize": 595,
"bodySize": 0
},
"response": {
"status": 0,
"statusText": "",
"httpVersion": "HTTP/1.1",
"headers": [],
"cookies": [],
"content": {
"size": 0,
"compression": 0
},
"redirectURL": "",
"headersSize": 13,
"bodySize": 0
},
"cache": {},
"timings": {
"blocked": 0,
"dns": -1,
"connect": -1,
"send": -1,
"wait": -1,
"receive": null,
"ssl": -1
}
}
thanks,
tom
It seems that statusCode 0 indicates that response is empty even headers are not sent, that is something hard to figure out and you need to find it out yourself
but you said that the response doesn't arrive in your functions is because you are using load and error events for listening for the response, and actually you shouldn't entirely depend on those two errors, consider as case where timeout has occured before your request gets completed then 'timeout' event will be fired not 'error'
Instead you should use readystatechange event that will be called on every state change of request and you can also keep track of timeouts or errors related to no response received
httpRequest.onreadystatechange = stateChangeHandler;
stateChangeHandler = function() {
// The readyState can be 4 values:
// 0 - uninitialized
// 1 - loading
// 2 - loaded
// 3 - interactive
// 4 - complete
//
// readyState 0 - 3 can be completely ignored by us, as they are only updates
// about the current progress. Only on readyState 4, should we continue and
// start checking for the response status.
if (xmlHttpRequest.readyState != 4) {
return;
}
// Check HTTP Response code
if (xmlHttpRequest.status != 200) {
// response is ok process it
} else {
// there was some error
}
}
Reference:
https://developer.mozilla.org/en-US/docs/HTTP#HTTP_Response_Codes
http://www.w3.org/TR/XMLHttpRequest/#event-xhr-readystatechange
http://msdn.microsoft.com/en-us//library/ms534361%28en-us,VS.85%29.aspx
http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute