Support for 'origin' header value? #5025

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

Projects

None yet

5 participants

@jas-

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
Zend Framework 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

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

@macnibblet

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
Zend Framework member

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

@jas-

@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

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

@jas-

@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
Zend Framework 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-

@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

@weierophinney getallheaders is apache specific before 5.4.0

@jas-

@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
Zend Framework member

Closed with #5029.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment