Sinatra: concerning filters, halt and body on 404 error - json

I'm using Sinatra to develop this JSON API. The way I designed it, the error messages are also delivered in JSON in a specific format. The only difference is that they response will have a 4xx status code instead of a 2xx or 3xx. Now, the problems I encountered:
I defined a general filter where I set the response content type. Like this:
before { content_type :json }
problem is, everytime I call halt, this setting is not taken into account. I have to set it myself on the halt call in a very ugly, more verbose and error-prone way:
halt [404, {"Content-Type" => "application/json;charset=utf-8"}]
is there another way to do this?
The problem that phases me the most is: when I halt with code 404 after I catch the 404 error (see below), JSON content type and json body, strangely, I don't get any body, neither browser nor curl gets it. How come?
error 404 do
halt [404...{"bang" => "bong"....}]
end
UPDATE
Concerning the last issue, here is what it happens using curl and triggering a call which will fall in the 404 error block:
curl http://faulty_url
# curl log:
curl: (52) Empty reply from server
# sinatra log:
!! Unexpected error while processing request: Content-Length header was 221, but should be 227
127.0.0.1 - - [28/Mar/2013 11:28:47] "GET / HTTP/1.1" 404 221 0.0664
maybe this helps.

I may not understand exactly what's the output, but if you are looking to override 404 you will have to do something like below instead of error 404 do
not_found do
# Set content
{"bang" => "bong"}
end

Which version of Sinatra were you using? Looking at the recent change logs for Sinatra I see two entries in the 1.4.x releases that seem like they could be relevant:
Status, headers and body will be set correctly in an after filter when using halt in a before filter or route. (Konstantin Haase)
Setting status code to 404 in error handler no longer triggers not_found handler. (Konstantin Haase)

Related

API POST response returning 400 response code in Jmeter

I am trying to create a test plan using jmeter.its for an API Post request, I have a header manager, bodydata, checked for spellings and the syntax seems to be correct. However, Im getting 400 response code with the following error shown in the attached image. Anyone with an idea how I can resolve this? Thank you. the error
Here is the request the request
The user doesn't have to be logged in, i have added a header manager, I have also noticed there header has a cookie value thats hard coded but it appears to be the same in every request. In the UI the API request returns 200 and thats what im expecting with the Jmeter script.
In its current form the question cannot be answered comprehensively.
HTTP Status Code 400 means that
The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).
Check that your ${site} and ${csVersion} variables have their respective values using Debug Sampler and View Results Tree listener combination
Cross check headers sent by JMeter and by the "UI", the most important is Content-Type
Use a sniffer tool like Wireshark of Fiddler and capture the requests which are being sent by JMeter and the "UI", the requests must be exactly the same apart from dynamic parameters which need to be correlated
The issues was being caused by an anti-forgery cookie which was hard coded in the request.I used a regex to extract the value from a previous request and used a variable value from the regex to make sure the same value is being passed on to the request that was failing.

How to add exception for this scenario in Anypoint studio?

I want to add exception when a user enters an invalid URL to call the endpoint in Anypoint studio.
Like my default path for calling the API is http://localhost:1234/api/flights, so I want a custom message "Something went wrong!" with a status code of 500 to be shown in an exception when a user enters bad path like http://localhost:1234/24api/flights. I have used APIKit router in this case. Please help me.
Because that is an invalid URI the HTTP Listener and APIKit should be returning a 404 (Not found) status code by default, which is the correct one for this scenario. Returning a 500 status code would be misleading.

How to configure Nginx not to cache error returned

We have a nginx to cache the json return (such as {"returnVal":10}) of an API call. We have to set the refresh interval as 1 hour due to some business consideration. We run into the case that sometimes the api call return json response {"returnVal":null} due to some intermittent error and nginx cached this "null" and serve to all the API calls before the next refresh comes. Can I configure nginx to do not cache the return when it is an error/null value?
HTTP error code (4xx, 5xx) is the best option to setup and control caching, so you can do something like that:
proxy_cache_valid 200 1m;
proxy_cache_valid 403 1h;
In case of problems with setting specific header up you can set cache key as a body (works only if error response body is the same but none errors are always different):
proxy_cache_key "$request_uri|$request_body";

Error when attempting a PUT against /users/USERID endpoint in 2.0 API

I've seen others with the same issue ... I get the following json error message back whenever I attempt to disable a user or update their title. Has anyone had luck with this?
I have no problems with the POST method to add an email_alias, or with the PUT method to move a users folder from one owner to another. I've tried it in perl and in curl (see below example session) So I'm relatively confident that :
I have a valid, OAuth2 bearer token
I have properly formed content and URLs
So, I'm trying to post to:
PUT /2.0/users/XXXXXXXXXX HTTP/1.1
Authorization: Bearer TOKEN
Response:
HTTP/1.1 400 Bad Request
{"type":"error","status":400,"code":"invalid_request_parameters","help_url":"http:\/\/developers.box.com\/docs\/#errors","message":"Invalid input parameters in request","request_id":"1682580609514902d69b5fd"}
Update: below is a trace from curl showing the request body:
0000: PUT /2.0/users/USERID HTTP/1.1
00a2: Authorization: Bearer TOKEN
011f:
=> Send data, 23 bytes (0x17)
0000: {"status" : "inactive"}
<= Recv header, 26 bytes (0x1a)
0000: HTTP/1.1 400 Bad Request
<= Recv data, 207 bytes (0xcf)
0000: {"type":"error","status":400,"code":"invalid_request_parameters"
0040: ,"help_url":"http:\/\/developers.box.com\/docs\/#errors","messag
0080: e":"Invalid input parameters in request","request_id":"718513715
00c0: 514916f1109c2"}
Found the answer to the 4xx errors on PUTs : the OAuth2 settings for the application in box needed to have "Manage Enterprise" checked ... my app has been around since the pre-OAuth2 days, wasnt aware of this flag.
After checking it, i get 200 response ... some PUT operations still dont effectively change the attribute, but they return a 2xx response, so, one hurdle cleared.

Server Internal Error : Premature end of script headers in file.cgi

I am running Apache server. When I send the request from HTML using ajax call to cgi, I am not getting any response.
I found the following error statement in the httpd/error_log file:
Premature end of script headers: file.cgi
When I gave alert to the status code, it returned 500 Internal Server Error.
How to resolve this?
You're not returning a full set of headers. The output for a CGI must be of the format:
[header]
[blankline]
[body]
If you're getting the "Premature end..." error, the most likely reason is that you're not supplying any header. At an absolute bare minimum, you should return the content-type and then any other optional fields, for example, a simple "Hello world" response would be:
Content-type: text/plain
Hello world!
Or a simple HTML example:
Content-type: text/html
<html>
<body>Hello world!</body>
</html>
Other headers you may want to return with Content-type include those that control the cache, cookies, redirects, etc.