Did REST interface just start enforcing Content-Type?

Tuesday, 10 April 2012 · 4 messages · last reply 12 Apr 2012
CD
Charles Duffy10 Apr 2012 04:41 #
Howdy -- The following is arguably a bug in my REST bindings rather than the server, but it worked as of the 7.2 release but fails as of the current 7.2.1 snapshot. A request akin to the following: POST /rest HTTP/1.1 Host: 127.0.0.1:8984 Content-Length: 86 Authorization: Basic cmVhZG9ubHk6cmVhZG9ubHk= Content-Type: application/x-www-form-urlencoded Accept-Encoding: identity, deflate, compress, gzip Accept: */* User-Agent: python-requests/0.10.6
<rest:query xmlns:rest="http://basex.org/rest
"><rest:text>1+1</rest:text></rest:query>
Yields the following response: HTTP/1.1 400 Bad Request Content-Length: 40 Server: Jetty(6.1.26) Unknown option '<REST:QUERY XMLNS:REST'. ...but did not do so previously.
DP
Dimitar Popov10 Apr 2012 08:37 #
Quoted text · 19:41:30 · 30 lines
Am Montag, 9. April 2012, 19:41:30 schrieb Charles Duffy: > Howdy -- > > The following is arguably a bug in my REST bindings rather than the server, > but it worked as of the 7.2 release but fails as of the current 7.2.1 > snapshot. > > A request akin to the following: > > POST /rest HTTP/1.1 > Host: 127.0.0.1:8984 > Content-Length: 86 > Authorization: Basic cmVhZG9ubHk6cmVhZG9ubHk= > Content-Type: application/x-www-form-urlencoded > Accept-Encoding: identity, deflate, compress, gzip > Accept: */* > User-Agent: python-requests/0.10.6 > > <rest:query xmlns:rest="http://basex.org/rest > "><rest:text>1+1</rest:text></rest:query> > > Yields the following response: > > HTTP/1.1 400 Bad Request > Content-Length: 40 > Server: Jetty(6.1.26) > > Unknown option '<REST:QUERY XMLNS:REST'. > > ...but did not do so previously.
I sent some changes in the REST interface yesterday - you may try them. Basically HTTP 400 is almost alwayst thrown by the REST implementation when something is wrong (500 not that much ;) ). In my patch, I've also added more debug messages so that if you enable the debug flag it's be more easy to find the reason for the error. Regards, Dimitar
CD
Charles Duffy12 Apr 2012 02:06 #
Quoted text · Dimitar Popov · 7 lines
On 04/10/2012 01:37 AM, Dimitar Popov wrote: > I sent some changes in the REST interface yesterday - you may try > them. Basically HTTP 400 is almost alwayst thrown by the REST > implementation when something is wrong (500 not that much ;) ). In my > patch, I've also added more debug messages so that if you enable the > debug flag it's be more easy to find the reason for the error. > Regards, Dimitar
Dimitar -- I'm still reproducing this with 7.2.1-pre-20120411.230549 (today's snapshot). That said, with DEBUG enabled, there _is_ a stack trace: org.basex.core.BaseXException: Unknown option '<REST:COMMAND XMLNS:REST'. org.basex.core.Command.execute(Command.java:76) org.basex.server.LocalSession.execute(LocalSession.java:134) org.basex.server.Session.execute(Session.java:38) org.basex.http.rest.RESTCode.parseOption(RESTCode.java:128) org.basex.http.rest.RESTCode.parseOptions(RESTCode.java:111) org.basex.http.rest.RESTPost.run(RESTPost.java:32) org.basex.http.rest.RESTServlet.run(RESTServlet.java:14) org.basex.http.BaseXServlet.service(BaseXServlet.java:34) javax.servlet.http.HttpServlet.service(HttpServlet.java:820) org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1221) org.mortbay.servlet.UserAgentFilter.doFilter(UserAgentFilter.java:78) org.mortbay.servlet.GzipFilter.doFilter(GzipFilter.java:131) org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212) org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399) org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766) org.mortbay.jetty.handler.HandlerList.handle(HandlerList.java:49) org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) org.mortbay.jetty.Server.handle(Server.java:326) org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945) org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756) org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
DP
Dimitar Popov12 Apr 2012 02:15 #
Quoted text · Dimitar Popov · 44 lines
Am Mittwoch, 11. April 2012, 17:06:30 schrieb Charles Duffy: > On 04/10/2012 01:37 AM, Dimitar Popov wrote: > > I sent some changes in the REST interface yesterday - you may try > > them. Basically HTTP 400 is almost alwayst thrown by the REST > > implementation when something is wrong (500 not that much ;) ). In my > > patch, I've also added more debug messages so that if you enable the > > debug flag it's be more easy to find the reason for the error. > > Regards, Dimitar > > Dimitar -- > > I'm still reproducing this with 7.2.1-pre-20120411.230549 (today's > snapshot). > > That said, with DEBUG enabled, there _is_ a stack trace: > > org.basex.core.BaseXException: Unknown option '<REST:COMMAND XMLNS:REST'. > org.basex.core.Command.execute(Command.java:76) > org.basex.server.LocalSession.execute(LocalSession.java:134) > org.basex.server.Session.execute(Session.java:38) > org.basex.http.rest.RESTCode.parseOption(RESTCode.java:128) > org.basex.http.rest.RESTCode.parseOptions(RESTCode.java:111) > org.basex.http.rest.RESTPost.run(RESTPost.java:32) > org.basex.http.rest.RESTServlet.run(RESTServlet.java:14) > org.basex.http.BaseXServlet.service(BaseXServlet.java:34) > javax.servlet.http.HttpServlet.service(HttpServlet.java:820) > org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) > > org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1221) > org.mortbay.servlet.UserAgentFilter.doFilter(UserAgentFilter.java:78) > org.mortbay.servlet.GzipFilter.doFilter(GzipFilter.java:131) > > org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212) > org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399) > org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) > org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766) > org.mortbay.jetty.handler.HandlerList.handle(HandlerList.java:49) > org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) > org.mortbay.jetty.Server.handle(Server.java:326) > org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) > > org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945) > org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756) > org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
Ok, I think I have an idea what's going on. The problem seems to be in the HTTP client, specifically the "Content-Type: application/x-www-form-urlencoded" header. Since form values are encoded using "key=value", Jetty interprets <rest:query xmlns:rest="http://basex.org/rest"><rest:text>1+1</rest:text></rest:query> as key: '<rest:query xmlns:rest' and value: '"http://basex.org/rest"><rest:text>1+1</rest:text></rest:query>' I can reproduce the issue if I explicitly set the content type to application/x-www-form-urlencoded
Quoted text · Charles Duffy · 7 lines
>>> import requests >>> from requests.auth import HTTPBasicAuth >>> payload = '<rest:query xmlns:rest="http://basex.org/rest"><rest:text>1+1</rest:text></rest:query>' >>> url = 'http://localhost:8984/rest' >>> auth = HTTPBasicAuth('admin', 'admin') >>> headers = {'Content-Type':'application/x-www-form-urlencoded'} >>> r = requests.post(url, data=payload, auth=auth, headers=headers)
Without content type or with content type = "application/xml" it works fine. I haven't looked in the code to see what might have changed this behavior, but I think the current code is ok. Please, try setting the content type to the correct one (i.e. "application/xml") and see if it will work for you. Regards, Dimitar

⚡Generated with XQuery