Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Support for 'origin' header value? #5025

Closed
jas- opened this issue Aug 26, 2013 · 12 comments
Closed

Support for 'origin' header value? #5025

jas- opened this issue Aug 26, 2013 · 12 comments
Labels
Milestone

Comments

@jas-
Copy link

jas- commented Aug 26, 2013

Perhaps I am missing something but the protected array of headers returned with the commonly used Zend\Http\Headers::getHeaders() call does not seem to include the 'origin' header key/value pair.

Is this by design? I would think this header would be exposed to the Zend\Mvc\Controller\AbstractRestfulController in order to protect a RestFul API with a whitelist of allowed applications based on this header value during OPTIONS request types.

Any insight is appreciated as I very well may be doing something wrong or using the wrong method of accessing this key during requests. Thanks

@Ocramius
Copy link
Member

@jas- this shouldn't land in the base MVC imo. @Orkin is working on https://github.com/zf-fr/zfr-cors for this, which is a better place where to handle these REST-specific problems.

@Orkin
Copy link
Contributor

Orkin commented Aug 26, 2013

@jas The feature will be merge propably since end of this week ;)

@macnibblet
Copy link
Contributor

In most cases the Origin header is not sent by the browser, So that is most likely the reason you cannot see the origin header.

But in general Zf2 will never hide any information from the user so if you cannot see the origin header in the Request::getHeaders() then it has not been sent by the browser.

@Ocramius
Copy link
Member

@jas- sorry, didn't understand the original question, my bad :) Forget about the CORS stuff, it's unrelated

@jas-
Copy link
Author

jas- commented Aug 26, 2013

@macnibblet Strange... here are the headers during the request:

Request Headersview source
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Access-Control-Request-He...    content-md5,content-type,x-alt-referer,x-requested-with
Access-Control-Request-Me...    GET
Connection  keep-alive
Host    inventory.dev:8080
Origin  http://local.dev:8080
User-Agent  Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0

And here is the contents of the request as seen from print_r(\Zend\Http\Request::getHeaders()) as you can see there is nothing for Origin even though tcpdump & firebug all show the header being sent and registered with the browser.

Zend\Http\PhpEnvironment\Request Object
(
    [baseUrl:protected] => 
    [basePath:protected] => 
    [requestUri:protected] => /cors
    [serverParams:protected] => Zend\Stdlib\Parameters Object
        (
            [storage:ArrayObject:private] => Array
                (
                    [REDIRECT_APPLICATION_ENV] => development
                    [REDIRECT_STATUS] => 200
                    [APPLICATION_ENV] => development
                    [HTTP_HOST] => inventory.dev:8080
                    [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0
                    [HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
                    [HTTP_ACCEPT_LANGUAGE] => null
                    [HTTP_ACCEPT_ENCODING] => gzip, deflate
                    [HTTP_CONNECTION] => keep-alive
                    [PATH] => /sbin:/usr/sbin:/bin:/usr/bin
                    [SERVER_SIGNATURE] => <address>Apache/2.2.15 (CentOS) Server at inventory.dev Port 8080</address>

                    [SERVER_SOFTWARE] => Apache/2.2.15 (CentOS)
                    [SERVER_NAME] => inventory.dev
                    [SERVER_ADDR] => 10.0.2.15
                    [SERVER_PORT] => 8080
                    [REMOTE_ADDR] => 10.0.2.2
                    [DOCUMENT_ROOT] => /var/www/html/test/public
                    [SERVER_ADMIN] => root@localhost
                    [SCRIPT_FILENAME] => /var/www/html/test/public/index.php
                    [REMOTE_PORT] => 51598
                    [REDIRECT_URL] => /cors
                    [GATEWAY_INTERFACE] => CGI/1.1
                    [SERVER_PROTOCOL] => HTTP/1.1
                    [REQUEST_METHOD] => GET
                    [QUERY_STRING] => 
                    [REQUEST_URI] => /cors
                    [SCRIPT_NAME] => /index.php
                    [PHP_SELF] => /index.php
                    [REQUEST_TIME_FLOAT] => 1377516623.155
                    [REQUEST_TIME] => 1377516623
                )

        )

    [envParams:protected] => Zend\Stdlib\Parameters Object
        (
            [storage:ArrayObject:private] => Array
                (
                )

        )

    [method:protected] => GET
    [uri:protected] => Zend\Uri\Http Object
        (
            [validHostTypes:protected] => 19
            [user:protected] => 
            [password:protected] => 
            [scheme:protected] => http
            [userInfo:protected] => 
            [host:protected] => inventory.dev
            [port:protected] => 8080
            [path:protected] => /cors
            [query:protected] => 
            [fragment:protected] => 
        )

    [queryParams:protected] => 
    [postParams:protected] => 
    [fileParams:protected] => 
    [version:protected] => 1.1
    [headers:protected] => Zend\Http\Headers Object
        (
            [pluginClassLoader:protected] => 
            [headersKeys:protected] => Array
                (
                    [0] => host
                    [1] => useragent
                    [2] => accept
                    [3] => acceptlanguage
                    [4] => acceptencoding
                    [5] => connection
                )

            [headers:protected] => Array
                (
                    [0] => Array
                        (
                            [name] => Host
                            [line] => Host: inventory.dev:8080
                        )

                    [1] => Array
                        (
                            [name] => User-Agent
                            [line] => User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0
                        )

                    [2] => Array
                        (
                            [name] => Accept
                            [line] => Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
                        )

                    [3] => Array
                        (
                            [name] => Accept-Language
                            [line] => Accept-Language: null
                        )

                    [4] => Array
                        (
                            [name] => Accept-Encoding
                            [line] => Accept-Encoding: gzip, deflate
                        )

                    [5] => Array
                        (
                            [name] => Connection
                            [line] => Connection: keep-alive
                        )

                )

        )

    [metadata:protected] => Array
        (
        )

    [content:protected] => 
)

@macnibblet
Copy link
Contributor

@jas- What happens if you remove all the logic from your index.php and replace it with a simple print_r(get_headers());

@jas-
Copy link
Author

jas- commented Aug 26, 2013

@macnibblet Here are some results, as you can see using the get_headers() seems to be the problem as it does not retrieve all available headers with the request.

Results of get_headers(), no Origin field in request.

Array
(
    [0] => HTTP/1.1 200 OK
    [1] => Date: Mon, 26 Aug 2013 12:22:28 GMT
    [2] => Server: Apache/2.2.21 (Unix) mod_jk/1.2.32
    [3] => Vary: Cookie,Accept-Encoding
    [4] => Pragma: no-cache
    [5] => Expires: Wed, 31 Dec 1969 23:59:59 GMT
    [6] => Cache-Control: no-cache, no-store, must-revalidate, max-age=0
    [7] => Content-Length: 4711
    [8] => Connection: close
    [9] => Content-Type: text/html;charset=UTF-8
)

Results of getallheaders(), the Origin field is present within request.

Array
(
    [Host] => inventory.dev:8080
    [Connection] => keep-alive
    [Origin] => http://local.dev:8080
    [Content-MD5] => OWY4MzkxODM1NzRlYTg4MzJmMmFmOWU0MjViZjYyOWE=
    [User-Agent] => Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36
    [Content-Type] => application/json; charset=utf8
    [Accept] => application/json, text/javascript, */*; q=0.01
    [X-Requested-With] => XMLHttpRequest
    [X-Alt-Referer] => comm.js
    [Referer] => http://local.dev:8080/index.html
    [Accept-Encoding] => gzip,deflate,sdch
    [Accept-Language] => en-US,en;q=0.8
)

And the raw $_SERVER super global also contains the HTTP_ORIGIN key/value pair

Array
(
    [REDIRECT_APPLICATION_ENV] => development
    [REDIRECT_STATUS] => 200
    [APPLICATION_ENV] => development
    [HTTP_HOST] => inventory.dev:8080
    [HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0
    [HTTP_ACCEPT] => application/json, text/javascript, */*; q=0.01
    [HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.5
    [HTTP_ACCEPT_ENCODING] => gzip, deflate
    [CONTENT_TYPE] => application/json; charset=utf8
    [HTTP_X_REQUESTED_WITH] => XMLHttpRequest
    [HTTP_X_ALT_REFERER] => comm.js
    [HTTP_CONTENT_MD5] => OWY4MzkxODM1NzRlYTg4MzJmMmFmOWU0MjViZjYyOWE=
    [HTTP_REFERER] => http://local.dev:8080/index.html
    [HTTP_ORIGIN] => http://local.dev:8080
    [HTTP_CONNECTION] => keep-alive
    [PATH] => /sbin:/usr/sbin:/bin:/usr/bin
    [SERVER_SIGNATURE] => <address>Apache Server at inventory.dev Port 8080</address>
    [SERVER_SOFTWARE] => Apache/2.2.15 (CentOS)
    [SERVER_NAME] => inventory.dev
    [SERVER_ADDR] => 10.0.2.15
    [SERVER_PORT] => 8080
    [REMOTE_ADDR] => 10.0.2.2
    [DOCUMENT_ROOT] => /var/www/html/test/public
    [SERVER_ADMIN] => root@localhost
    [SCRIPT_FILENAME] => /var/www/html/test/public/index.php
    [REMOTE_PORT] => 52628
    [REDIRECT_URL] => /cors
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => 
    [REQUEST_URI] => /cors
    [SCRIPT_NAME] => /index.php
    [PHP_SELF] => /index.php
    [REQUEST_TIME_FLOAT] => 1377520585.005
    [REQUEST_TIME] => 1377520585
)

A quick grep of the vendor\ZF2\library folder doesn't show any calls to the get_headers() function except in debugging & testing scripts.

@weierophinney
Copy link
Member

@jas- Perhaps we should change Zend\Http\PhpEnvironment\Request to use getallheaders() when populating the Headers instance. Would you be interested in creating a pull request with this change?

@jas-
Copy link
Author

jas- commented Aug 26, 2013

@weierophinney Wouldn't it best be suited as a plugin since Zend\Http\Headers defaults to $class = ($this->getPluginClassLoader()->load($key)) ?: 'Zend\Http\Header\GenericHeader'; (which doesn't include the HTTP_ORIGIN key/value)?

Perhaps adding to the other static plugins for available header key/value pairs as defined in Zend\Http\HeaderLoader?

@macnibblet
Copy link
Contributor

@weierophinney getallheaders is apache specific before 5.4.0

@jas-
Copy link
Author

jas- commented Sep 2, 2013

@weierophinney I have opened a pull request for this. The support has been added to the 'Zend\Http\Headers' namespace. Even though the current status of the RFC is a draft and in anticipation that it will 'hopefully' will be added to the current RFC-2616 header field specification.

@weierophinney
Copy link
Member

Closed with #5029.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants