Opened 7 months ago

Closed 7 months ago

#2327 closed defect (duplicate)

Adding cross-domain configuration in HTTP2 is invalid

Reported by: yl-yue Owned by:
Priority: critical Milestone: nginx-1.21
Component: nginx-core Version:
Keywords: http2, cors Cc: yl-yue
uname -a: docker pull nginx:1.21.6
nginx -V: docker pull nginx:1.21.6

Description

Invalid configuration as follows:

    server {
        listen       8080 http2;
        server_name  localhost;
    
        location / {
            add_header 'Access-Control-Allow-Origin' $http_origin always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Headers' 'keep-alive,user-agent,cache-control,content-type,x-user-agent,x-grpc-web,grpc-timeout,device-tag';
    
            if ($request_method = 'OPTIONS') {
                return 204;
            }
            
            grpc_pass grpc://192.168.0.12:31201;
        }
    }

After debugging, the add_header command in http1.1 takes effect. After http2 is added, the add_header command becomes invalid

Change History (5)

comment:1 by Maxim Dounin, 7 months ago

Could you please clarify what do you mean by "the add_header command becomes invalid"? That is, what you do you do, what you expect to happen, and what happens instead.

The configuration you've provided seems to work fine: the headers specified are properly returned to the client. Note though that HTTP/2 without SSL is not going to work with browsers, and will require special options for other clients, such as curl --http2-prior-knowledge http://127.0.0.1:8080/.

in reply to:  1 comment:2 by yl-yue, 7 months ago

Replying to Maxim Dounin:

Could you please clarify what do you mean by "the add_header command becomes invalid"? That is, what you do you do, what you expect to happen, and what happens instead.

The configuration you've provided seems to work fine: the headers specified are properly returned to the client. Note though that HTTP/2 without SSL is not going to work with browsers, and will require special options for other clients, such as curl --http2-prior-knowledge http://127.0.0.1:8080/.

I expect that after the above configuration is added, the following results can be returned successfully to solve the CORS problem:

access-control-allow-headers: ...
access-control-allow-methods: GET, PUT, DELETE, POST, OPTIONS
access-control-allow-origin: http://*.*.com
access-control-expose-headers: grpc-status,grpc-message
access-control-max-age: 1728000

But actually, the response headers doesn't have any.

When I replace configuration

listen       8080 http2;

with

listen       8080;

The headers response works fine, but I expect it to work in HTTP2 as well.

comment:3 by Maxim Dounin, 7 months ago

But actually, the response headers doesn't have any.

Could you please show the request you are using for testing, and the response received?

comment:4 by yl-yue, 7 months ago

Http2 not configured with SSL causes the add_header configuration to be invalid

listen       8080 http2;

Therefore, http2 must be used in conjunction with SSL, but in practical development (e.g. GRPC protocol) http2 does not have to be used with SSL

listen       8080 ssl http2;

comment:5 by Maxim Dounin, 7 months ago

Resolution: duplicate
Status: newclosed

Using listen ... http2; without ssl configures listening socket to use HTTP/2 with prior knowledge. Browsers are not able to talk via sockets configured this way, though other clients can properly use such sockets as long as properly configured, see curl example above. Duplicate of #808.

Note: See TracTickets for help on using tickets.