title: Enabling CORS on Google App Engine for a Django Application
body: <p>I have been trying to enable CORS headers on Google app engine but none of the methods that I found over the internet worked for me.</p>
  
  <p>My application is on Python/Django and I want my frontend application (which is hosted separately) to be able to make API calls to my backend platform on Google App Engine.</p>
  
  <p>The January 2017 release notes say that </p>
  
  <blockquote>
    <p>We are changing the behavior of the Extensible Service Proxy (ESP) to deny cross-origin resource sharing (CORS) requests by default</p>
  </blockquote>
  
  <p>It can be seen<a href="https://cloud.google.com/endpoints/docs/release-notes" rel="noreferrer">here</a></p>
  
  <p>And the solution to enable CORS given by them is to add the following snippet to the service's OpenAPI configuration.</p>
  
  <pre><code>"host": "echo-api.endpoints.YOUR_PROJECT_ID.cloud.goog",
  "x-google-endpoints": [
      {
        "name": "echo-api.endpoints.YOUR_PROJECT_ID.cloud.goog",
        "allowCors": "true"
      }
   ],
  ...
  </code></pre>
  
  <p>So I followed <a href="https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/endpoints/getting-started" rel="noreferrer">this</a> example and created two files in my code base </p>
  
  <p>openapi.yml :</p>
  
  <pre><code>swagger: "2.0"
  info:
    description: "Google Cloud Endpoints APIs"
    title: "APIs"
    version: "1.0.0"
  host: "echo-api.endpoints.&lt;PROJECT-ID&gt;.cloud.goog"  
  x-google-endpoints:
   - name: "echo-api.endpoints.&lt;PROJECT-ID&gt;.cloud.goog"
     allowCors: "true"
  paths:
    "/api/v1/sign-up":
      post:
        description: "Sends an email for verfication"
        operationId: "signup"
        produces:
        - "application/json"
        responses:
          200:
            description: "OK"
        parameters:
        - description: "Email address of the user"
          in: body
          name: email
          required: true
          schema:
            type: string
        - description: "password1"
          in: body
          name: password1
          required: true
          schema:
            type: string
        - description: "password2"
          in: body
          name: password2
          required: true
          schema:
            type: string
  </code></pre>
  
  <p>openapi-appengine.yml:</p>
  
  <pre><code>swagger: "2.0"
  info:
    description: "Google Cloud Endpoints API fo localinsights backend server"
    title: "Localinsights APIs"
    version: "1.0.0"
  host: "&lt;PROJECT-ID&gt;.appspot.com"
  </code></pre>
  
  <p>Then I ran this command:</p>
  
  <pre><code>gcloud service-management deploy openapi.yml
  </code></pre>
  
  <p>Then I edited my app.yml file to make it look like this (The addition was endpoints_api_service. Before adding this, the app was getting deployed without any errors):</p>
  
  <pre><code>runtime: python
  env: flex
  entrypoint: gunicorn -b :$PORT myapp.wsgi
  
  beta_settings:
      cloud_sql_instances: &lt;cloud instance&gt;
  
  runtime_config: 
    python_version: 3
  
  automatic_scaling:
    min_num_instances: 1
    max_num_instances: 1
  
  resources:
    cpu: 1
    memory_gb: 0.90
    disk_size_gb: 10  
  
  env_variables:
    DJANGO_SETTINGS_MODULE: myapp.settings.staging
    DATABASE_URL: &lt;dj-database-url&gt;
  
  endpoints_api_service:
    name: "&lt;PROJECT-ID&gt;.appspot.com"
    config_id: "&lt;CONFIG-ID&gt;"
  </code></pre>
  
  <p>Then I just deployed the application with </p>
  
  <pre><code>gcloud app deploy
  </code></pre>
  
  <p>Now, the app got deployed successfully but it is behaving strangely. All the requests which are supposed to return a 200 response still throw CORS error but the ones which return a 400 status do work.</p>
  
  <p>For example - The sign up API expects these fields - email, password1, password2 where password1 should be same as password2. Now when I send correct parameters, I get HTTP 502 saying</p>
  
  <blockquote>
    <p>No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin {origin-url} is therefore not allowed access. The response had HTTP status code 502</p>
  </blockquote>
  
  <p>But when I send password1 not same as password2, I get HTTP 400 response which I am sure is coming from my code because the response is a dictionary written in the code if password1 and password2 do not match. Also in this case, the headers have Access-Control-Allow-Origin as * but in the former case, that was not true</p>
  
  <p>I also checked my nginx error logs and it says </p>
  
  <blockquote>
    <p>*27462 upstream prematurely closed connection while reading response header</p>
  </blockquote>
  
  <p>What am I doing wrong here?
  Is this the right way to enable CORS in GAE?</p>