Can I get the status text from an NSHTTPURLResponse? - iphone

If I use NSURLConnection to get data from a server and it sends back a response that begins with, say:
HTTP/1.1 406 Some string of text here
Is there any way I can retrieve the status text "Some string of text here"? I know how to get the status code, and I know about localizedStringForStatusCode:, but in this case I need access to the specific text sent back.

You can use ASIHTTPRequest, which provides this as -requestStatusMessage. Or you can use Core Foundation's CFHTTP, which provides CFHTTPMessageCopyResponseStatusLine. I don't believe there's a good way to get to the CFHTTPMessage from NSHTTPURLResponse unfortunately. Of course, ASIHTTPRequest is pretty awesome anyway.

Related

HTTP GET request with body for RESTful API [duplicate]

This question already has answers here:
HTTP GET with request body
(23 answers)
Closed 2 years ago.
I've been looking at how to implement the following:
I am developing a RESTful Web API (using .Net Core 2.2). I need to create an endpoint where the consuming client can send some text to the API, the API replaces some tokens in this text, and returns the text back to the consuming client.
I thought that the client should simply do a GET request, with the text in the body. The reply would then be the new text after the token replacements. However, from my research, it appears one should not stick anything with semantics in the body of a GET request. I'm not sure if arbitrary text with certain tokens that need to be replaced by the API qualifies as semantic? I've also seen it stated at "you should not be able to use the body of a GET request to alter the response". I guess I'm in trouble there, as depending what goes into he body, will affect the response.
So then, I've been struggling to figure out what is the correct way to do this. If anyone has an pointers I'd greatly appreciate it.
Thank you.
I thought that the client should simply do a GET request, with the text in the body. The reply would then be the new text after the token replacements. However, from my research, it appears one should not stick anything with semantics in the body of a GET request.
Right - RFC 7231
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
In basic HTTP, you've got choices. One is to include a representation of your document in the URI itself
/?your_document_as_a_query_string
/your/document/as/path/segments
For short documents, that approach can be fine; but implementations are not required to support infinitely long identifiers, so you may discover that intermediate components reject your request, or crop the URI in transit.
A safe mechanism for achieving your goal is to use POST, rather than GET. POST supports a message body, so you can send the blank form to the server, and receive back the edited version in the response.
POST is the wildcard method of HTTP, it can mean anything. In the spec, the body of the response includes "a representation of the status of, or results obtained from, the action".
You might also consider that the response duplicates a lot of the content of the body of the request, and consider instead the possibilities of fetching a map of your template values from the server, and then applying the template on the client.

Requesting RESTful GET with meaningful Body? Standards not clear

We found ourselves in a dead end when trying to follow standards as we need to build a request that should be a GET and should have a meaning Body.
The request just wants to retrieve some data, no modification inside the database, just getting some data. But at the same time we need to send an array of ids for the objects we want to retrieve, and no, these objects can't be indexed in any way so we really need to send the list of ids or alternatively make 100 requests to the server to get them one by one. That's not gonna happen.
We could also add the list to the URL, but we can't be sure the URL won't end up being too long if the list of ids were to be too big. So to ensure the system doesn't fail we want to use the Body.
I read that a GET can have a Body, but only if it isn't meaningful:
HTTP GET with request body
Yes. In other words, any HTTP request message is allowed to contain a message body, and thus must parse messages with that in
mind. Server semantics for GET, however, are restricted such that a
body, if any, has no semantic meaning to the request. The requirements
on parsing are separate from the requirements on method semantics.
So, yes, you can send a body with GET, and no, it is never useful to do so.
This is part of the layered design of HTTP/1.1 that will become clear again once the spec is partitioned (work in progress).
....Roy
But our Body IS meaningful, which takes us to have to decide between unfollowing HTTP standards or unfollowing REST standards.
Is there any alternative to that? (It's not that this blocks us but I would like to know the answer).
Thank you very much.
you should consider changing your request to POST method.
As I understand it, there are three potential issues with a GET with request body: (link to blog)
Not all servers will support this.
Not all tools will support this (Swagger, POSTMAN added support this year: https://github.com/postmanlabs/postman-app-support/issues/131)
There is not yet a consensus on GET with request body. (For example, is Dropbox still using a POST)
so you'll have problems process the body with GET

Sending data to a website and getting results of search iOS

I am very new to iOS and I've just begun reading about HTTP requests and POST and GET methods. Let's say, for example, I want to have the user input a string, and then send that data to a website, (for this example, say www.rhymezone.com), search with that string, and get the results of that search within my application. Is this done with an HTTP post method? Or what? Any help / examples would be greatly appreciated. Also, if there are tutorials for this stuff, that would be appreciated as well.
For sake of example, here is what I've tried:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.rhymezone.com/r/rhyme.cgi?Word=test&typeofrhyme=perfect&org1=syl&org2=l&org3=y"]];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString *dataAsString=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"data: %#",dataAsString);
}
This outputs the entire source of the website (searching for rhymes of the word test). While I can certainly write a method to go through the source of the website and extract the words it returns, I feel like this is not correct. My way of getting rhymes of different words is simply to change the URL here, so where it says 'test' I change it to whatever the user inputs.
Thanks
Look into AFNetworking and RestKit.
It's easiest if you're calling a public API that uses JSON/XML, and then use a built in parser or a parser library to extract the data you want.
Simply downloading the contents of a URL is an HTTP GET request, such as going to a website.
This link talks a bit more about the difference between GET and POST.
When do you use POST and when do you use GET?
If I understand correctly what you are trying to do, I fear that the only option for you is sending the HTTP request (GET or POST according to what the website expects, just like you are doing) and then parse the result to filter all the information that is not relevant.
An alternative approach would be possible if you were using a website offering a REST API, or a JSON API so that you send the query and you get back just the information you need (in a specific format).
So, it depends strongly on the website you are using, but for the generic case, the only option you have is parsing.
(Or, you could display the full content of the page through UIWebView. This would not require explicitly setting up a connection, but I am not sure it is what you are trying to do.)
You are looking for a way to communicate with your website from your iOS application. The common approach is to get the string entered by the user, encode and send it as http request to a sort of script (webservice). This script will do all the stuff you want (search with this string). Then re-send the result to the client (your iOS app) as a http response which will be parsed in your iOS app(with a JSON parser for instance).
There is good resources around that, as an example, you may read this: http://www.raywenderlich.com/2965/how-to-write-an-ios-app-that-uses-a-web-service

Fiddler2 - How do I URlDecode the Request body for Viewing?

I'm using Fiddler to debug some particularly painful AJAX code, and in the POST requests that are being sent across to the server the Request BODY is UrlEncoded. This leads to me having to cut and paste the text into an online app to UrlDecode the text into the JSON object for the request. There has to be a better way to do this.
Does anyone know how I can make fiddler automatically URLDecode the body of the POST Request?
Well, you can simply press CTRL+E to decode locally. But depending on the format, you may also be able to use the WebForms Inspector.
Fiddler can manipulate the HTTP request and response in any way you like:
https://stackoverflow.com/a/23615119/264181

Best way to return error messages on REST services?

I've been looking at examples of REST API's like Netflix http://developer.netflix.com/docs/REST_API_Reference#0_59705 and Twitter and they seem to place error messages in the statusText header response instead of the responseText. We're developing an internal RESTful api and I am arguing for sending custom statusText messages and ignoring the responseText.
For the scope of our app, we're returning error 400 when the user has tried doing something they aren't supposed to, and the only error messages that will be updated in the UI for the user will be delivered with 400. I am of the belief that the message should be sent as a modified statusText but one of the engineers (who knows a bit less about REST than me) is arguing for sending it in the responseText.
What's the best way to go?
HTTP defines that you should put a descriptive error message in the response entity body, aka responseText.
statusText is not rendered or processed by any client.
I'd use the status text for the error message type, aka 400 Client Error, and the body for a description of the problem that can be rendered to the user, in whatever the format the client may be able to process.
Edit: Note that since then, a new standardised format exists to communicate in a standard fashion error details back to the client, which you can find at https://www.rfc-editor.org/rfc/rfc7807 and which I would recommend.
I think you're right, the general approach is use the existing error mechanism built into HTTP.
In general, try to map your errors to existing HTTP errors, for example if they request something they don't have permission to, return a 403 error.
If they request something that doesn't exist, return a 404.
Alex
According to the HTTP specification (rfc2616): "HTTP status codes are extensible"
However I don't think that creating new statuses for every different error message is the correct approach:
I would say choose HTTP Status appropriately (HTTP Status Code Definitions) if you can't find any category which matches your requirement create a custom one (but I'm sure you will) and put error messages in the HTTP response body.
Picking appropriate status code for your responses is extremely important as it is a key enabler of self-descriptive messages.
The entity body should be a representation of the resource's state and ideally contain hyperlinks to available next states in your application
Http Status Codes are pretty self explanatory and should be used as such. Returning 200 OK with validation errors is pretty Soap-y and misleading. Any REST Client implementation 4xx and 5xx errors go into a error block and it really depends on case to case basis if you really want to use the response body for non 2xx responses.