This question was asked many times before, but I wanted to ask about different aspect of it.
My testcase:
header("HTTP/1.0 404 Not Found"); // and
header("HTTP/1.0 404");
result in server returing header:
HTTP/1.1 404 Not Found
But it's also possible to do:
header("HTTP/1.0 404 Oh... sorry, did not find");
Where is this possibility coming from? Is it proper (does not make any complications?) to change Not Found string?
It's not that I want to change it as none will ever see it except for somone checking headers. But I'm courious.
Rather not. This header is standarized and should be always returned as is - in the common form:
HTTP/1.1 404 Not Found
If you need to pass any additional info to the client, pass it in the responses body and in standarized way as well, e.g.:
{
"status": 404,
"code": 509, //some internal code
"message": "Can not find resource for ID: XXX"
}
Related
How do you give any hints with a 400 status code?
For example, I know that I will throw a 400 if a certain cookie is missing or empty. Do I put a message in the body? In some "Error hint" header?
Thank you
Into the content. You may want to look at RFC 7807, "Problem Details for HTTP APIs".
I am trying out the HERE Maps REST API's - Custom Location Extension and run into a problem. It was mentioned that a POST request using the Corridor Search Using Coordinates for Custom Locationscan be used instead of a GET request if I want to submit a request with a large coordinate set, but the example POST request was not in the documentation.
I tried to figure out how to submit a POST request and this was how far I got:
Request:
POST /v1/search/corridor HTTP/1.1
Host: customlocation.cit.api.here.com
?app_id={YOUR_APP_ID}
&app_code={YOUR_APP_CODE}
&route=52.51978,13.388211,
52.5198326,13.3882084,
52.5198402,13.3883495,
52.5147705,13.3891602,
52.514758,13.389155
&radius=100
&layerId=30
Response:
{
"message": "Required parameters have not been provided",
"status": "400 Bad Request",
"error": "Required String parameter 'route' is not present",
"targetLayerId": null
}
Notes:
I wrote it here using the HTTP format
This request was the same GET request in the documentation and I just tried to convert it as a POST request by moving the query parameter into the body and sending the request using POST.
Body datatype is set as RAW TEXT
Edit:
(Further trial)
I also tried to move all the query params from the body to the url except route.
POST /v1/search/corridor ?app_id=Qk8YkRrHMbbbpkVipwIZ
&app_code=tYSXrAAHGEOcUB_cxbPQSA&radius=100&layerId=852 HTTP/1.1
route=52.51978,13.388211, 52.5198326,13.3882084,
52.5198402,13.3883495,
52.5147705,13.3891602,
52.514758,13.389155
Response:
{
"message": "Required parameters have not been provided",
"status": "400 Bad Request",
"error": "Required String parameter 'route' is not present",
"targetLayerId": null
}
I poked at this a bit and was able to get a response via POSTing by removing the route from the querystring and sending it as a form key/value pair. I used the demo credentials, and am testing using the Chrome plugin "Postman". My POST URL looks like this:
https://customlocation.cit.api.here.com/v1/search/corridor?layerId=30&radius=100&app_id=DemoAppId01082013GAL&app_code=AJKnXv84fjrb0KIHawS0Tg
and then I set either a form-data or x-www-form-urlencoded key of "route" and then the value was a string of coordinates. And then it came back with a successful response. I did get the same error you mentioned when trying to put any payload as raw text.
Things I don't know: is there some limit on the form data values?
Good luck. I do agree that the official document is pretty light on the POST examples, especially since they explicitly suggest that as a method for sending large payloads.
I am trying to make a POST request to the following url: http://xxx.xxx.xxx.xxx/api/signup
However I get this response:
http://xxx.xxx.xxx.xxx/api/signup?first_name=&last_name=&email_id=&password=&dob ...Please pass parameters...
So I tried making the request like this:
http://xxx.xxx.xxx.xxx/api/signup?first_name=Jay&last_name=Last&email_id=Jay#test.com&password=qqq&dob=1/1/15
But I get the same response.
I have no idea what the correct syntax is supposed to be...
Can someone please explain how I should rewrite the url?
Edit
After I make the request, if successful, I get a response saying "success new user" and a JSON with the key/vals
Does encoding your values make any difference?
for example:
http://xxx.xxx.xxx.xxx/api/signup?first_name=Jay&last_name=Last&email_id=Jay%40test.com&password=qqq&dob=1%2F1%2F15
Does anyone know how to manipulate the HTTP Status text in Scala Play 2.2?
I see that it's easy to specify the status code but not the accompanying text.
The reason I'm interested is that I'm trying to emulate exactly a web service I need to consume, and it puts specific information in the status text.
For example, when failing a login attempt I'll get the following snippet from this service (curl output):
< HTTP/1.1 401 username or password invalid
< ...
When I return an Unauthorized response from my Mock service I just get the following:
< HTTP/1.1 401 Unauthorized
< ...
I'm clearly missing the real way to do this if it's even possible in the first place.
Here's how I'm constructing the unauthorized response:
Unauthorized(views.html.invalidlogon(message)).withHeaders(
CONTENT_TYPE -> "text/plain"
)
Here's what I'd like to do in my fictional naive world:
Unauthorized(views.html.invalidlogon(message)).withHeaders(
CONTENT_TYPE -> "text/plain"
).setStatusText(message)
Thanks for the help!
Edit - Additional Info
So it turns out what I'm really looking for is the Reason Phrase.
According to the RFC they say the following:
The reason phrases listed here are only recommendations -- they MAY be replaced by local equivalents without affecting the protocol.
Of particular interest is the use of MAY with regard to the existing error codes.
However if in Play I return a custom 4XX error then the reason phrase is just Client Error following the classification of the 4XX status. It would be nice to have control over the reason phrase so that it accompanies the custom response status code.
De facto response status is a numeric value by HTTP specification and therefore it's hardcoded in Play.
If you really need this so as suggested in answer to other question it's better to add custom header, ie:
Unauthorized("You can't login now, sorry...").withHeaders(
CONTENT_TYPE -> "text/plain; charset=utf-8",
"X-Error-Message" -> "Login or password invalid"
)
TIP: For security reasons be careful with too descriptive error messages during login proccess.
After review of the Play code I don't think this is possible at the moment.
If you look here they do the following:
def createNettyResponse(header: ResponseHeader, closeConnection: Boolean, httpVersion: HttpVersion) = {
val nettyResponse = new DefaultHttpResponse(httpVersion, HttpResponseStatus.valueOf(header.status))
...
The call to HttpResponseStatus.valueOf(header.status) doesn't allow for Reason Phrase to be added.
In a purely fictional (and possibly dubious) world the following change might allow this:
def createNettyResponse(header: ResponseHeader, closeConnection: Boolean, httpVersion: HttpVersion) = {
val nettyResponse = header.reasonPhrase match {
case Some(reasonPhrase) => new DefaultHttpResponse(httpVersion, HttpResponseStatus(header.status, header.reasonPhrase))
case _ => new DefaultHttpResponse(httpVersion, HttpResponseStatus.valueOf(header.status))
}
...
However a change like that has a big ripple effect.
So If I'm correct, this is just not possible and I will see what the Play folks think.
thanks
With the following code:
//fpCode and fpParams are strings
ingestionBody := strings.NewReader(fpCode+fpParams)
resp, err := http.Post("http://192.168.1.151:8080/ingest?", "text/plain", ingestionBody)
I'm getting the error message:
"HTTP/1.1 POST /ingest" - 400 Bad Request
I don't know if I'm not using the Post method right (even when in this answer, they seem to use it in a similar way. Is the only example that I was able to find, unfortunatelly Go documentation lacks of examples), the problem is with the second parameter, which should be something different (but I also tried "text/*") or there is something important that I'm missing.
Perhpas you can try http.PostForm:
form := url.Values{}
form.Add("field1", a)
form.Add("field2", b)
http.PostForm("http://192.168.1.151:8080/ingest", form)
If you're doing a POST you should probably be using a content-type of application/x-www-form-urlencoded or multipart/form-data.
Ultimately you need to look at the server logs to determine why the request is failing.
You might try http.PostForm() instead.