Handling Http HEAD requests and header content - spring 3.1 mvc - java

I got a lot of 405 errors because I haven't support HEAD requests yet. Now while I try to fix this issue, the following question come to my head:
a) Is there an easier way to support HEAD for GET-URLs/resources?
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields
#RequestMapping(value = "/**/p/{productCode}", method = RequestMethod.GET)
public String productDetail(#PathVariable("productCode"), final Model model, final HttpServletRequest request) {
// some stuff...
return ControllerConstants.GET_PRODUCT_DETAIL;
}
or do I have to put a mapping for every Method?
#RequestMapping(value = "/**/p/{productCode}", method = RequestMethod.HEAD)
public String productDetailHead() {
final HttpHeaders headers = new HttpHeaders();
return new ResponseEntity(null, headers, HttpStatus.OK);
}
b) What HTTP header attributes for HEAD should be supported? (rule of thumb?)
My actually reponse with:
curl -I http://localhost:9001
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: _seaT.tenantID_=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
Set-Cookie: JSESSIONID=D07B464BBA02DC4148F00C5A08421B51; Path=/
Content-Length: 0
Date: Thu, 05 Dec 2013 13:41:42 GMT
Additional Info:
Webshop, STS 3.1, JDK 6, JSR 2.5
Thanks.

Answering you (b) question. As a rule of thumb all header attributes/directives that are passed during a GET method should also be passed during a HEAD method call, and that is what the HTTP standard says.
The HEAD method is identical to GET except that the server MUST NOT
return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

same question is here : Spring 3.0 HEAD Requests
shortly refer this : http://axelfontaine.com/blog/http-head.html

Related

Getting error -> Invalid header field name, with 32 [duplicate]

I am new to Flutter and I am trying to call my ASP.NET server web API.
From the logs on my server, everything goes fine but Android Studio throws an exception: "invalid header field name".
Here is the code in dart:
import 'package:http/http.dart' as http;
...
_getService() async {
String result;
try {
var url = 'http://192.168.1.14:34263/api/Mobile/test/1';
Future<http.Response> response = http.get( url );
result = response.toString();
} catch(exception){
result = exception.toString();
debugPrint(result);
}
...
}
Here is the response header (obtained via Chrome):
Access-Control-Allow-Headers:accept, authorization, Content-Type
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: WWW-Authenticate
Cache-Control: no-cache
Content-Encoding: deflate
Content-Length:79
Content-Type: application/xml; charset=utf-8
Date: Thu, 08 Mar 2018 01:01:25 GMT
Expires:-1
Pragma:no-cache
Server:MyTestServer
X-Content-Type-Options:NOSNIFF
X-Permitted-Cross-Domain-Policies:master-only
X-SourceFiles:=?UTF-8?BDpcTXlJbmNyZWRpYmxlRHJlc3NpbmdcTXlJbmNyZWRpYmxlRHJlc3NpbmdcTXlJbmNyZWRpYmxlRHJlc3NpbmdcYXBpXE1vYmlsZVxjb3Vjb3VcMQ==?=
X-XSS-Protection:1;mode=block
Here is the answer which is returned:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">test</string>
Can anyone tell me what am I doing wrong?
Many thanks
Ok, I finally found out, by debugging the code.
In fact, my server added a series of field names in the response's header (via the Web.config) and the last character of one of these field names was a space.
As a result, the http_parser.dart threw an exception since spaces are no authorized characters in header field name.
Nothing was detected by Chrome (or any browser) nor by Postman.
I had similar problem and after some heavy debugging
I removed these headers from nginx:
#add_header X−Content−Type−Options nosniff;
#add_header X−Frame−Options SAMEORIGIN;
#add_header X−XSS−Protection 1;
and it works fine. So most likely it's backend - header related issue

Adding extra server call on Springboot application causing issue with CORS

For context, I have been working on a springboot application with a ReactJS frontend. The ReactJS frontend connects to the springboot application, and the application makes calls to another server to get the requested data to display on the front end. I had gotten to a point where I was able to make a post request with a JSON payload, get the requested data in the form of another JSON payload, and display it to the frontend with no issues.
I had to implement a change, and add one more variable to the object that was being returned to the front end. And now the browser is telling me that:
Access to fetch at [url] been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
All that is different is the addition of the data to the object being returned, and the fact I am making another call to the server where the data is stored.
Here is the Response header when I dont make the additional call, and I get back the JSON payload
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: *
Set-Cookie: [I erased the cookie after pasting]
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 83363
Date: Thu, 09 Jul 2020 18:05:40 GMT
Keep-Alive: timeout=60
Here is the Response Header when I make the additional call
HTTP/1.1 500
Connection: close
Date: Thu, 09 Jul 2020 18:13:24 GMT
Ive debugged the backend, and no errors are thrown on the server side, and nothing happens while processing the data. I have all of a sudden just started getting the issue with CORS.
The following is my post request that has been working so far
fetch(url, {
headers: {
'Content-Type': 'text/plain',
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br',
},
method: 'post',
body: JSON.stringify(jsonData)
})
Im sure I have enabled everything I had to do on the Springboot side for CORS considering It works all the time except for when trying to get the extra data. If there is something I am missing I would like to know, and if this issue can be clarified by reading documentation on springboot and cors please point me in that direction.
Note:
I have also tried adding
#Configuration
#EnableWebMvc
public class SpringBootConfiguration implements WebMvcConfigurer{
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
to my application, but that does not seem to work either. This is all still fairly new to me, so I am unsure what is going wrong.
Thank you.
The header was too large now with the added data it seems. So all I had to do was increase the max-http-header-size in my application.properties. I can now get the full JSON payload with zero issues. I was too focused on the error on the frontend side that I neglected to go deep enough into the backend to see what was happening.
I added in my application.properties
server.max-http-header-size = 48000
I didnt actually set it to 48000, its much lower than that, I found the answer here
How to set max-http-header-size in spring boot 2.x application
I had issues with CORS andthe snippet you gave was something I had tried but it ended up breaking some other endpoints for unknown reasons. You can add #CrossOrigin(origins = "URL", allowedHeaders = "*") to your controllers.
Such as
#Controller
#CrossOrigin(origins = "localhost", allowedHeaders = "*")
public class Controller

HTTP Delete, Response Status: 405 (Method Not Allowed)

when sending http delete to my server this happens
Response Status: 405 (Method Not Allowed)
header look like this
Date: Sat, 31 Jan 2015 19:17:47 GMT
Server: WildFly/8
Connection: keep-alive
X-Powered-By: Undertow/1
Content-Length: 0
Allow: HEAD, POST, GET, OPTIONS, PUT
I suspect that I have to enable access to http delete method, but don't know how.
this is my delete method
#DELETE
#Path("/{id}")
public boolean deleteItem(#PathParam("id") long itemId);
this is the url for delete
wrong: http://192.168.2.101:8080/DataAccessRemoteWebapp/rest/dataitem/id=1
right: http://192.168.2.101:8080/DataAccessRemoteWebapp/rest/dataitem/1
I am using jax-rs
import javax.ws.rs.DELETE;
The annotation #Path("/{id})" requires the id directly after the / and so it won't match your test URL
http://192.168.2.101:8080/DataAccessRemoteWebapp/rest/dataitem/id=1
Instead, remove the id=:
http://192.168.2.101:8080/DataAccessRemoteWebapp/rest/dataitem/1
This old post on stackoverflow can respond to you question :
URL = /contacts/delete/contactname
405 because
It seems delete is always behave as submit (Post method) and you are
trying >to call as like get method from the URL. This is not possible
to call the >post method as like get. if you really want to call this
web service from >the browser to test, just download a Mozilla plugin
(Poster) which will help >you to submit the web service in your all
method types.

Restlet Can't parse payload of a GET request

I am using Restlet in java as a simple client to make calls to a RESTful service provided by tastypie (python django)
I am monitoring the payload through tcpmon and I am seeing the following payload get returned however i can't get at the data in the payload.
Client calls
ClientResource resource = new ClientResource("http://localhost/someplace/");
String rep = resource.get(String.class);
Payload
HTTP/1.0 200 OK
Date: Thu, 12 Jul 2012 20:22:12 GMT
Server: WSGIServer/0.1 Python/2.7.1
Vary: Cookie
Content-Type: application/json; charset=utf-8
Set-Cookie: sessionid=63c5ea23113073e489cb8920819f37d; expires=Thu, 26-Jul-2012 20:22:12 GMT; httponly; Max-Age=1209600; Path=/
{"jsonData": "someData"}
When i debug into restlet i notice that the InboundWay.createEntity(..) is setting the data to EmptyRepresentation due to the lack of length, chunkEncoding, or connection headers. Why is this? Why can't I just stream the data?
Does any one know why this is happening? Is there a better client? So far tried jersey and Resteasy with limited success. (jeresy has a bug where it is trying to mark and reset a autoCloseSteam, and resteasy was just a pain to use as a client) I was hoping not to have to write an HTTPClient.
Did a bit more digging it looks like RESTLET is doing something quite silly in my oppinion.
It is looking a the response headers and trying to find if it knows the size, or if its chunkedEncoding, or if the Connection:closed is specified. Otherwise it does NOT try to parse the payload ... Does anyone know why this is? I didn't realize that those headers are required in any way. Why can't we use the ClosingInputStream when the connection close is not specified...
Restlet Code
public Representation createInboundEntity(Series<Parameter> headers) {
Representation result = null;
long contentLength = HeaderUtils.getContentLength(headers);
boolean chunkedEncoding = HeaderUtils.isChunkedEncoding(headers);
// In some cases there is an entity without a content-length header
boolean connectionClosed = HeaderUtils.isConnectionClose(headers);
// Create the representation
if ((contentLength != Representation.UNKNOWN_SIZE && contentLength != 0)
|| chunkedEncoding || connectionClosed) {
InputStream inboundEntityStream = getInboundEntityStream(
contentLength, chunkedEncoding);
ReadableByteChannel inboundEntityChannel = getInboundEntityChannel(
contentLength, chunkedEncoding);
...

Httpclient / JSONObject

I am trying to autologin sending a JSONObject. Im gettign the reposnse as 302 Moved Temporarily which means I should redirect to another url. But my response.toString() shows "Location: /". Below is the code.
String input_text = "https://www.hautelook.com/v3/credential";
HttpPost httpost = new HttpPost(input_text);
String data = "{\"screen_resolution\":{\"height\":1080,\"width\":1920}}";
JSONObject jo=new JSONObject();
jo.put("email","sfhgfjk");
jo.put("passsword","dfjhsdkj");
jo.put("meta",data);
StringEntity se = new StringEntity( "JSON: " + json.toString());
se.setContentEncoding("UTF-8");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpost.setEntity(se);
HttpResponse response = httpclient.execute(httpost);
entity = response.getEntity();
What would be wrong?
This is the response.
response HTTP/1.1 302 Moved Temporarily [Server: nginx, Content-Type: text/html,
Location: /, Content-Encoding: gzip, Content-Length: 20, Expires: Thu, 16 Feb 2
012 19:07:55 GMT, Cache-Control: max-age=0, no-cache, no-store, Pragma: no-cache
, Date: Thu, 16 Feb 2012 19:07:55 GMT, Connection: keep-alive, Set-Cookie: PHPSE
SSID=vmoqeksits8ccukvnf7k4rdv75; path=/]
You can always verify if this is correct manually by issuing the request via CURL, or even your browser. For example, typing https://www.hautelook.com/v3/credential into a browser location bar causes a redirect to https://www.hautelook.com (with a nice little login dialog being shown by jQuery). So you know at least, that the behavior is consistent.
This can mean one of several things:
The endpoint you are using is incorrect (this is probably not the
case)
The authentication information you are supplying is incorrect (also
unlikely, because we would expect a 401 unauthorized in that case)
The way you are passing the authentication information is incorrect.
Without knowing more about the API its hard to say, but you should consult the docs again to ensure you are making the call correctly.
* EDIT*
Ok, tested with REST client and there are some things to correct in your code:
Change 'passsword' to 'password'
Change the line:
Original:
new StringEntity( "JSON: " + json.toString())
To:
new StringEntity(json.toString())
This should allow the request through, though I'm still not sure this is the correct endpoint, since I get back an HTML page. One last thing, its always good to remove your API credentials before posting your code to SO. I'm including a screenshot of the request below:
The default redirect strategy used by HttpClient 4.x honors restrictions on automatic redirection of entity enclosing methods such as POST and PUT imposed by the HTTP specification. Per requirements of the HTTP specification 302 Moved Temporarily, 301 Moved Permanently and 307 Temporary Redirect status codes may not be handled automatically for POST and PUT methods without an explicit confirmation by the user.
HttpClient 4.2 can be configured to use LaxRedirectStrategy that handles all types of redirects automatically regardless of the restrictions imposed by the specification. With earlier versions one can implement a custom redirect strategy as described here: Httpclient 4, error 302. How to redirect? (as suggested by Bob Kuhar).
At the same time I have to say that 'Location: /' header looks somewhat suspicious and even automatic redirect to that location may not necessarily produce the desired effect.
response HTTP/1.1 302 Moved Temporarily means, some redirection happened.
One of the example case is, Single sign on (or) Authorization required. Without authorization cookie when you try to access the resource using URL you may be redirected for Authorization with response as 302.
You could just configure your HTTPClient to follow redirects. Prior to 4.x, it was just a method on the HTTPMethod. Add...
HttpPost httpost = new HttpPost(input_text);
httpost.setFollowRedirect( true );
...but this wasn't pure enough or something and they changed it in 4.x. I haven't tried it since, so am reluctant to post code. But this question has come up and been answered here before. Maybe this helps you? Httpclient 4, error 302. How to redirect?

Categories

Resources