Retrieve file size from web server - objective-c

Looking for a way to retrieve a file size from a web server using cocoa/foundation. I know one can use NSURLconnection which will return NSURLResponse that contains the file size. Is there any other way to get the size. I'm looking for a synchronous way of doing it so when i do [myClass getsize] the size is returned.
Thanks

You can use a NSMutableURLRequest to send a HTTP HEAD request (there’s a method called setHTTPMethod). You’ll get the same response headers as with GET, but you won’t have to download the whole resource body. And if you want to get the data synchronously, use the sendSynchronousRequest… method of NSURLConnection.

Related

NSURLConnection - Get HTTP status code on request failure

Is there any way I can get HTTP status code after NSURLConnection has failed to request? According to the documentation, I can get the HTTP status code from -connection:didReceiveResponse:. However, in case the request fails, only -connection:didFailedWithError: is called, and by far I haven't found any method to get status code inside this method.
p/s: I'm working on a VERY old, complicated project, and it's very error-prone, so I cannot use AFNetworking or NSURLSession.
As mentioned in the Apple docs for NSURLConnectionDataDelegate Protocol the connection:didReceiveResponse: is called only when sufficient data has been received to create the NSURLResponse object.
While the NSURLResponse object may not be available until later, it is possible for a connection to receive partial data by using the connection:didReceiveData: method. Note that this seems to exclude the HTTP headers and only contain the "data" component of the response. There may be a way to trigger the didReceiveResponse: early if the server knows ahead of time how much data will be transmitted although I am no familiar enough with this to confirm.
Be aware that the response data typically comes in blocks of approximately 1KiB of data each, depending on various network settings such as MTU and how often the server "flush" its output pipe.
Good luck!

Detect if NSURL is a URL to a file format supported by the UIImage class

I'm looking for a way to detect a if an NSURL is a URL to a file format supported by the UIImage class, and if yes, open it in something like MWPhotoBrowser (https://github.com/mwaterfall/MWPhotoBrowser) instead of a UIWebView. My first thought is to have an if condition with all the supported file extensions. I'm wondering if anyone knows of a better way?
You don't know what's at a URL until you at least begin to fetch it. Some URLs look like they end with a filename -- an image filename, even -- but actually point to HTML pages (say, for viewing said image). Some URLs don't appear to end in a filename but do point straight to an image file.
You can get a pretty good hint as to what kind of data is at a URL by making an HTTP HEAD request: see NSURLRequest and NSHTTPURLResponse and look for the Content-Type header. (Those just describe a request and response; you'll need NSURLSession to perform the request and get a response.)
Even a HEAD request doesn't always report correctly, though: the only way to really be sure if there's an image at a URL is to fetch it -- most image formats are identifiable within the first several bytes of the data, so you can begin a fetch, look at the first partial data you get, and abort the fetch if you don't want the rest.

ASIHTTPRequest seems to cache JSON data always

I'm using ASIHTTPRequest API to get some JSON data from a web side. I'm using an asynchronous request without changing default cache properties. Code is as follows:
__unsafe_unretained ASIHTTPRequest * request = [ASIHTTPRequest requestWithURL:url];
request.timeOutSeconds = 30;
[request setCompletionBlock:^(void)
{
NSString *str = [request responseString];
/*
*
*
*/
}];
[request setFailedBlock:^(void)
{
NSLog(#"status: %#",[request responseStatusMessage]);
NSLog(#"%# : %#",[request url],[[request error] debugDescription]);
}];
[request startAsynchronous];
However, obtained JSON data remains as the old one although content of JSON data in server changes.
I checked data using web browser, both on laptop and on iPhone safari. When i request url after a change in JSON, it first returns old data, but if i refresh the page, it returns updated data. But in the app, ASIHTTPRequest always returns the old data.
I also try to debug ASIHTTPRequest code in order to see whether any cached data used. But it seems like it never uses download cache because it has not been set. It never enters [useDataFromCache] method.
What could be the problem? How can i force ASIHTTPRequest to check whether there is an updated data on server, and make it get the true updated JSON?
EDIT
I used Cache-Control header, and now i get the correct updated JSON data. Code is as follows:
[request addRequestHeader:#"Cache-Control" value:#"no-cache"];
However, i think from now on request will always try to retrieve JSON even if it is not modified, which will decrease performance.
How can i make it first check the server whether data is modified, and retrieve if it is modified? Currently i get JSON data as a dynamic response from a php url, so there is no file which i can check up to dateness of the data.
What could be the solution?
Regards,
Given everything you've said, it seems unlikely that ASIHTTPRequest is cacheing the response.
So, something else must be - it seems like you have a cacheing proxy server inbetween you and the server, and that's why setting Cache-Control makes a difference.
It could be a proxy server on your local network, or it could be at your ISP, or it could be in front of the web server you're using.
According to ASIHTTPRequest's documentation, calling the method
[[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
will clear the cache. Call this method before you send the request and it should give you the updated JSON data.

Best way to write to file a large HTTP response

I'm looking for ways of writing to file the results of a web request. In languages based on the JVM or the CLR there are appropriate Stream-based techniques I'm familiar with, however I'm clueless on how could that be done in Objective-C.
What I need is essentially a way to send an HTTP request (with a custom header set) and write the HTTP response content as I receive it (due to memory constraints I can't afford to get the whole file or even a large portion of it before persisting the contents).
Ideas/suggestions/snippets?
Thanks in advance!
P.S.: I'm developing for Mac OS and I'm already using ASIHTTPRequest, if that can be of help.
Edit: I should specify that I don't want to write all of the contents returned by the server to disk unless I can write them directly at a certain offset of a file (which I'll then be able to manipulate), so anything that dumps straight to a new file or to the beginning of a file won't work for me.
There a few ways of doing it, depends on how you want to handle the responds
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:#"/Users/Test/Desktop/cool.html"];
with setDownloadDestinationPath: set, it'll save into temporary path, and when it finished, it'll move it to your downloadDestinationPath you set.
Or you can implement request:didReceiveData: delegate (see ASIHTTPRequestDelegate.h), and handle it yourself. This is similar to stream.
PS. I only ever use ASIHTTPRequest on iOS, not Mac OS, so I'm not entirely sure if it will work for you.

How to get a complete request from a NSURLRequest?

Is there any way to get the actual data that will be sent when a NSURLConnection sends a NSURLRequest? Right now I'm mainly interested in looking at HTTP and HTTPS requests, but since NSURLRequest works for many protocols, it seems like there ought to be a general way to see the corresponding data for any type of request.
Am I missing something, or do I need to construct the request myself by combining the headers, body, etc?
Just to be clear, I'd like to do this programmatically, not by watching what shows up at the server end.
Update: At this point I've written code that effectively constructs a request using the data in a NSURLRequest, so I'm not asking how to go about that. However, I'd still like to know if there's a way to access the request stream that the URL loading system would generate. In other words, can I get access to the exact bytes that would be sent if a NSURLConnection were to send my NSURLRequest?
According your last question:
Check cookiesCenter.
Check credentialsStorage.
Log all headers for example on the first urlConnection's delegate method didReceiveResponse:.
Make this connection with local webservice and try to catch all headers, params, etc.
Also, the most simple way, is making request yourself.
Am I missing something, or do I need to construct the request myself
by combining the headers, body, etc?
It turns out that this is exactly what I needed to do, and it makes sense. It's the protocol handler (NSURLProtocol subclass), not NSURLRequest, that knows how to format the request for its particular protocol. Luckily, it's very easy to render an instance of NSURLRequest into a valid HTTP request. You can get the method (GET, POST, etc.), requested resource, and host from the request, and you can also get all the HTTP headers using the -allHTTPHeaderFields method, which returns a dictionary. You can then loop over the keys in the dictionary and add lines to the request like:
for (NSString *h in headers) {
[renderedRequest appendFormat:#"%#: %#\r\n", h, [headers objectForKey:h]];
}