Grails
  1. Grails
  2. GRAILS-3792

Problem with content negotiation (withFormat)

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 1.1-beta2
    • Fix Version/s: 1.1-beta3
    • Component/s: Controllers
    • Labels:
      None

      Description

      after upgraded from 1.0.4 to 1.1beta2, text/json handling of withFormat doesn't work.

      it works only when a format=json parameter is explicitly specified

      also refer to the following thread:
      http://www.nabble.com/content-negotiation-for-json-td21256603.html

        Activity

        Hide
        Graeme Rocher added a comment -

        Tried the following controller:

        import grails.converters.*
        
        class TestController {
        
        	def index = {
        		
        		withFormat {
        			html { render "html" }
        			json { render "json" }
        		}
        	}
        
        }
        

        With the following script:

        url = new URL("http://localhost:8080/json/test/index") 
        conn = url.openConnection() 
        conn.addRequestProperty("content-type","application/json") 
        println conn.content.text
        

        And the response was "json". So it appears to work as expected. Please attach a sample that reproduces the problem if it is still a problem

        Show
        Graeme Rocher added a comment - Tried the following controller: import grails.converters.* class TestController { def index = { withFormat { html { render "html" } json { render "json" } } } } With the following script: url = new URL( "http: //localhost:8080/json/test/index" ) conn = url.openConnection() conn.addRequestProperty( "content-type" , "application/json" ) println conn.content.text And the response was "json". So it appears to work as expected. Please attach a sample that reproduces the problem if it is still a problem
        Hide
        Mingfai Ma added a comment -

        Could it support both application/json and text/json?

        By google this, it seems some frameworks use text/json by default and they'll just fail to work against grails

        Show
        Mingfai Ma added a comment - Could it support both application/json and text/json? By google this, it seems some frameworks use text/json by default and they'll just fail to work against grails
        Hide
        Graeme Rocher added a comment - - edited

        It does. This script works fine too:

        url = new URL("http://localhost:8080/json/test/index") 
        conn = url.openConnection() 
        conn.addRequestProperty("content-type","text/json") 
        println conn.content.text
        
        Show
        Graeme Rocher added a comment - - edited It does. This script works fine too: url = new URL( "http: //localhost:8080/json/test/index" ) conn = url.openConnection() conn.addRequestProperty( "content-type" , "text/json" ) println conn.content.text
        Hide
        Mingfai Ma added a comment -

        didn't test but just read my email thread. i got problem when the http request has http header of 'Accept: text/json'.

        Just quickly check the HTTP Header definition:
        http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

        14.1 Accept
        The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as in the case of a request for an in-line image.

        14.17 Content-Type
        The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET.

        It seems to me the withFormat should use 'Accept' rather than 'Content-Type' to determine response. Accept means, the client ask for content of particular type, but 'content-type' refers to the content-type that is being sent in the request. it doesn't hurt to support 'content-type' but it shouldn't ignore 'accept'

        Show
        Mingfai Ma added a comment - didn't test but just read my email thread. i got problem when the http request has http header of 'Accept: text/json'. Just quickly check the HTTP Header definition: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 14.1 Accept The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as in the case of a request for an in-line image. 14.17 Content-Type The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET. It seems to me the withFormat should use 'Accept' rather than 'Content-Type' to determine response. Accept means, the client ask for content of particular type, but 'content-type' refers to the content-type that is being sent in the request. it doesn't hurt to support 'content-type' but it shouldn't ignore 'accept'
        Hide
        Mingfai Ma added a comment -

        btw, accept could be complex:
        Accept: text/;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */;q=0.5

        i only expect, 'Accept: text/json' should work...

        Show
        Mingfai Ma added a comment - btw, accept could be complex: Accept: text/ ;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */ ;q=0.5 i only expect, 'Accept: text/json' should work...
        Hide
        Graeme Rocher added a comment - - edited

        This script works fine:

        url = new URL("http://localhost:8080/json/test/index") 
        conn = url.openConnection() 
        conn.addRequestProperty("accept","application/json") 
        println conn.content.text
        

        If the grails.mime.use.accept.header setting in Config.groovy is set to true. Since Grails 1.1 it is disable by default:

        grails.mime.use.accept.header=true
        
        Show
        Graeme Rocher added a comment - - edited This script works fine: url = new URL( "http: //localhost:8080/json/test/index" ) conn = url.openConnection() conn.addRequestProperty( "accept" , "application/json" ) println conn.content.text If the grails.mime.use.accept.header setting in Config.groovy is set to true. Since Grails 1.1 it is disable by default: grails.mime.use.accept.header= true
        Hide
        Graeme Rocher added a comment -

        correction to last comment

        Show
        Graeme Rocher added a comment - correction to last comment

          People

          • Assignee:
            Graeme Rocher
            Reporter:
            Mingfai Ma
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development