pokeb / asi-http-request Goto Github PK
View Code? Open in Web Editor NEWEasy to use CFNetwork wrapper for HTTP requests, Objective-C, Mac OS X and iPhone
Home Page: http://allseeing-i.com/ASIHTTPRequest
License: Other
Easy to use CFNetwork wrapper for HTTP requests, Objective-C, Mac OS X and iPhone
Home Page: http://allseeing-i.com/ASIHTTPRequest
License: Other
I noticed strange thing with ASIHTTPRequest when it downloads ~50Kb image over slow cellular connection. In my code I configure ASIHTTPRequest to download ~50Kb image over cellular network. When user wants to cancel the download I send -[NSOperationQueue cancelAllOperations]
to cancel the request. ASIHTTPRequest's delegate receives requestDidFailed:
message with ASIRequestCancelledErrorType error. But afterwards delegate receives requestDidFinished:
message with properly downloaded image. To workaround this issue I send -[ASIHTTPRequest cancel]
in requestDidFailed:
if request failed with error ASIRequestCancelledErrorType.
I think it's a bug.
The paths that S3 requests take is not the key that amazon uses to store the data. The path needs a prefix of / , ie path == /key
This does not seem to be in the docs, and may even be a bug. At the least there should be an assertion added to requestWithBucket. It seems dumb to repair the 'path'. Perhaps renaming the call, (which breaks existing stuff) or making a new call, like requestWithBucket:(NSString_)bucket key:(NSString_)key would be better.
ASIS3Request *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com%@",bucket,path]]] autorelease];
[request setBucket:bucket];
[request setPath:path];
return request;
}
Both the sample projects use a build script to set the version number post build. This refers to stuff not installed by default on Mac OS X thus causing the build to error out. Deleting the build script phase allows the build to complete.
ASIHTTPRequest.m:1382
- (void)incrementDownloadSizeBy:(long long)length
{
[ASIHTTPRequest performSelector:@selector(request:incrementDownloadSizeBy:) onTarget:[self queue] withObject:self amount:&length];
- [ASIHTTPRequest performSelector:@selector(request:incrementDownloadSizeBy:) onTarget:[self uploadProgressDelegate] withObject:self amount:&length];
+ [ASIHTTPRequest performSelector:@selector(request:incrementDownloadSizeBy:) onTarget:[self downloadProgressDelegate] withObject:self amount:&length];
}
You need to call self here or ASIHTTPRequest subclasses can't configure defaults by overriding -init. I haven't checked other areas of the code, but generally super should never be called unless it's from the same method implementation in a subclass.
If I run 'build and analyze' on a garbage-collection-enabled project using ASIHTTPRequest, I get 10 warnings with the message "Potential leak (when using garbage collection) of an object..." (in ASIFormDataRequest.m and ASIHTTPRequest.m). Could you look into this? (It seems it's mostly related to objects allocated using CoreFoundation functions and deallocated using autorelease.)
We were discussing it in this post of the group:
http://groups.google.com/group/asihttprequest/browse_thread/thread/1aad7e268ed1444e
It would be interesting that we could set the character encoding of the form requests
Thank you
The following patch adds proper URL encoding of form data to ASIFormDataRequest. It also sets the charset to UTF-8, the charset that is used throughout ASIFormDataRequest to encode strings into data.
Without the former, URL injection is easily possible and people could just pass maliciously crafted data to an application to forge an incorrect request.
Without the latter many servers misinterprete the form data as ISO-8859-1 and certain characters get manhandled.
diff --git a/device/iphone/safe-online-iphone-client/Sources/ASIHttpRequest/Classes/ASIFormDataRequest.h b/device/iphone/safe-online-iphone-client/Sources/ASIHttpRequest/Classes/ASIFormDataRequest.h
index a0991ad..dbc73ed 100644
--- a/device/iphone/safe-online-iphone-client/Sources/ASIHttpRequest/Classes/ASIFormDataRequest.h
+++ b/device/iphone/safe-online-iphone-client/Sources/ASIHttpRequest/Classes/ASIFormDataRequest.h
@@ -26,6 +26,9 @@ typedef enum _ASIPostFormat {
ASIPostFormat postFormat;
}
+#pragma mark utilities
++ (NSString*) encodeURL:(CFStringRef) string;
+
#pragma mark setup request
// Add a POST variable to the request
diff --git a/device/iphone/safe-online-iphone-client/Sources/ASIHttpRequest/Classes/ASIFormDataRequest.m b/device/iphone/safe-online-iphone-client/Sources/ASIHttpRequest/Classes/ASIFormDataRequest.m
index 803cf33..29c7827 100644
--- a/device/iphone/safe-online-iphone-client/Sources/ASIHttpRequest/Classes/ASIFormDataRequest.m
+++ b/device/iphone/safe-online-iphone-client/Sources/ASIHttpRequest/Classes/ASIFormDataRequest.m
@@ -19,6 +19,17 @@
@implementation ASIFormDataRequest
+#pragma mark utilities
++ (NSString*) encodeURL:(CFStringRef)string
+{
+ CFStringRef result = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
+ string,
+ NULL,
+ CFSTR(":/?#[]@!$ &'()*+,;=\"<>%{}|\\^~`"),
+ kCFStringEncodingUTF8);
+ return [(NSString*) result autorelease];
+}
+
#pragma mark init / dealloc
+ (id)requestWithURL:(NSURL *)newURL
@@ -181,7 +192,7 @@
return;
}
- [self addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"];
+ [self addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded; charset=UTF-8"];
NSEnumerator *e = [[self postData] keyEnumerator];
@@ -189,7 +200,7 @@
int i=0;
int count = [[self postData] count]-1;
while (key = [e nextObject]) {
- NSString *data = [NSString stringWithFormat:@"%@=%@%@",[key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],[[[self postData] objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],(i<count ? @"&" : @"")];
+ NSString *data = [NSString stringWithFormat:@"%@=%@%@", [ASIFormDataRequest encodeURL:(CFStringRef)key], [ASIFormDataRequest encodeURL:(CFStringRef)[[self postData] objectForKey:key]],(i<count ? @"&" : @"")];
[self appendPostData:[data dataUsingEncoding:NSUTF8StringEncoding]];
i++;
}
Seems like asi-http-request is throwing away the POST request body on the second request.
apple has updated its reachability class to version 2.0 which currently breaks ASIHTTPRequest
When shouldCancelAllRequestsOnFailure is set to YES, the queueDidFinishSelector gets called once per each failed/cancelled request. I was expecting it to be called only once per queue.
I don't know if anyone else has experience this but I'm seeing a large performance hit when running the code on an Iphone 3G. (On WiFi.) I got about 30 kbit/s
The same code running on the simulator runs at 200 kbit/s (My maximum line speed.)
Some servers don't seem to like this, and it's irrelevant for binary data, and misleading for text.
I'm setting the credentials with using setUserName and setPassword in the delegate method authenticationNeededForRequest. If credentials are wrong the app crashes.
It looks like the authentication delegate method is being called 3 times before the crash occurs, and from what I understand from the code this shouldn't be happening, and the request should just fail if the authorisation attempt count is 2.
The crash occurs on the line "[self setRequestCredentials:nil];" in ASIHTTPRequest's "attemptToApplyCredentials".
I have an example app if necessary.
This might be on purpose but if I set a User-Agent then the request gets redirected it gets set back to the ASIDefaultUserAgent.
When fetching an URL that gets redirected, de progress is set to 100% when the redirecting request finished. Then the progress is set back again to 0% when the new request (to which the other URL pointed) is started.
Better would be not to set the progress, until the headers are processed and it is known that the request is not redirected.
To fix, we need to implement all the non-private NSStream methods as if we were subclassing:
In my test example, I'm requesting a URL, say:
Which redirects to:
This fails because an exception is thrown deep in the guts of ASIHTTPRequest. I tracked this down to line 2904 of ASIHTTPRequest.m in the method findSessionAuthenticationCredentials
, where it tries to compare the port of the new URL (80) to the port in the original URL (nil). The exception is thrown because it is calling NSNumber isEqualToNumber:
with a nil argument.
So, this line:
if ([[theURL host] isEqualToString:[requestURL host]] && ([theURL port] == [requestURL port] || [[theURL port] isEqualToNumber:[requestURL port]]) && [[theURL scheme] isEqualToString:[requestURL scheme]]) {
Should probably be something like (ugly, but works):
if ([[theURL host] isEqualToString:[requestURL host]] && ([theURL port] == [requestURL port] || ([requestURL port] && [[theURL port] isEqualToNumber:[requestURL port]])) && [[theURL scheme] isEqualToString:[requestURL scheme]]) {
In iOS 4, the authentication dialog does not seem to work, its shown as expected, but it isn't possible to write a username or password into it.
The keyboard appears, it is possible to select a textfield aswell, but the input doesn't seem to reach the textField.
When working with asynchronous requests in a single thread mode redirect requests get quietly dropped without completion
See this thread:
http://groups.google.com/group/asihttprequest/browse_thread/thread/11bf8a7f0afb4a9
Best thing to do would be to move saving into readResponseHeaders, since that's when we find out if creds are good or not.
+currentLocale
returns user's locale overlaid with other language settings on the iPhone. For some reason I'm getting en_US on my iPhone even when I've set up Russian in Settings application. [[NSLocale preferredLanguages] objectAtIndex:0]
seem solves this problem.
I guess it's nicer to set originalURL in initWithURL: instead of startRequest.
I'm experiencing an issue with an Amazon S3 file upload. The simulator works great. But the exact same code on the device doesn't seem to upload the entire 166 Kb .png picture file. It only seems to upload 159 Kb. When I try to open the image, I get an error. I've tried both 3G network and WiFi. Both with the same result. Anyone experienced this issue or know what the problem could be? I am on an iPhone 3Gs running OS 3.1.
This may not be a bug and it may be the intention that ASIHTTPRequest is targeting 10.6 only now but line 3458 of ASIHTTPRequest.m calls:
Which is a 10.6 API.
When using a redirected URL and a custom temp file, the output stream is being closed when the stream from the redirecting URL is completed, in line 2500:
if ([self temporaryFileDownloadPath]) {
[[self fileDownloadOutputStream] close];
After that, the final URL starts to download to a closed output stream (fileDownloadOutputStream).
Hi!
I've noticed a bug in the sample project.
When I build the sample project and run on the Simulator everything is in order, all URL request works. But when I try to run this project on an iPhone I noticed when try to run the Queue sample (2. tab) it never finish the downloading and never show any images!
I found a workaround, read below:
QueueViewController.m (iPhone.xcode)
In this section the download destination path points to the Application's root directory which is writeable on the Simulator but not on Device (the device throws a write deny message, but this message only shows in the device log only not in the debugger console). So I changed the download destination to CachedImages below the NSCachesDirectory which is writeable on the Device
Regards,
Hi again,
When using ASIHTTPRequest to download redirected URLs (e.g. 307, temporary redirect), the body of the redirecting URL gets saved to file (or memory). In my test case (http://download.omroep.nl/vpro/35551406.mp3), the redirecting URL's body contains html meta redirect code (as fallback for browsers ignoring the 307 HTTP status).
It seems to be solved when this condition is added at line 2478 in ASIHTTPRequest.m. Not sure if there are any malicious consequences though...
if ([self needsRedirect] == NO)
// Are we downloading to a file?
if ([self downloadDestinationPath])
M
Look at merging:
http://github.com/nanotech/asi-http-request/commits/new-auth-dialog
Should finally get around to integrating http://blog.ddg.com/?p=24 to replace the Apple Reachability classes.
Is good
It may be we need to set the stream properties differently when connecting to HTTPS urls.
Been using the File upload for quite some time and every since 3.1 came out on the iPhone I get the error "Domain=ASIHTTPRequestErrorDomain Code = 1 UserInfo == xxxx 'A connection failure occurred: SSL problem (possibly a bad/expired/self-signed certificate)'"
Our hosting provider assures us all is good on the cert/config areas.
This is totally random and when I am good 3G coverage. I can immediately retry and it may or may not work. Not sure if this is an issue in the ASI code just wanted to toss it out there in case anyone else is having this.
It would be nice if the request would store the original URL.
When using a queue and requestDidFinish delegate methods, I usually check the url property of a request to figure out which resource has been downloaded. But if the request has been redirected, this fails.
The issue is with the following url and any url after this (replace the 100 with 200, 300, 400, etc):
http://www.craigslist.org/about/best/all/index100.html
The first page of the 'best of' section (http://www.craigslist.org/about/best/all/) works fine. For all other pages responseString returns nil due to trying to convert the responseData (which is properly downloaded) with the wrong encoding. ASI tries to use UTF8 when the actual data is ASCII (or at least using NSASCIIStringEncoding will allow the data to be converted to string).
This may or may not be an ASI issue. I will see if I can get some more info and a fix or if it is just a craigslist.org issue with sending different encoding and actual data.
- (void)markAsFinished
{
[self willChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isFinished"];
[self setInProgress:NO];
CFRunLoopStop(CFRunLoopGetCurrent());
}
should be
- (void)markAsFinished
{
[self willChangeValueForKey:@"isFinished"];
[self setInProgress:NO];
[self didChangeValueForKey:@"isFinished"];
CFRunLoopStop(CFRunLoopGetCurrent());
}
I'm seeing a EXC_BAD_ACCESS when I run through this code. I'm not aware that this defect would cause that though.
I've setup multiple ASIS3Request's and added them to a ASINetworkQueue.
The S3 Requests have a download and temporary download path, resume download is allowed.
I've setup a UIProgressView as downloadProgressDelegate for the queue.
However it seems that the progress is not updated.
I've debugged the methods:
Any ideas how to solve this?
In the right circumstances, the same request is able to call both its success and failure delegate methods, this shouldn't be possible. Must have been broken as a result of recent changes.
Hi, I've got a singleton method that I use to manage downloading.
I'm downloading a lot of files so they are placed in a ASINetworkQueue and run.
All works well until after the user chooses to cancel download (I call a cancelAllOperations on the queue) and the queue is cancelled.
However if the user chooses to start the download again I see the queue fill up with requests, I then call "go" but nothing happens.
The ASINetworkQueue object is retained and still exists (hence the fact I can get a count). It just never runs the second time.
Any ideas?
Thanks, M
When I compile my application which uses ASIHTTPRequest, I get two warnings with such message:
incompatible Objective-C types assigning 'struct NSDictionary *', expected 'struct NSMutableDictionary *'
Both are reported in ASIHTTPRequest.m, one on @synthesize proxyCredentials and the other on @synthesize requestCredentials. It's not really a problem, but it is a bit annoying to see this every time I recompile the app ;)
Hi, I'm getting sporadic crashes when canceling requests.
It crashes in startRequest: http://skitch.com/steipetee/n2w5q/xcode
I am stopping all current operations via
[networkQueue cancelAllOperations];
Am I doing something wrong?
I receive the error "Internal compiler error: Segmentation fault" when attempting to build a project which includes asi-http-request. Pressing build again usually alleviates this error, but it is still quite annoying. This occurs on both my Macbook Pro, Macbook Air, and Mac Pro. Thanks for your help!
I don't have really good reproduce instructions for you on this one because it is so rare but it does happen. I use a standard NSOperationQueue to push all ASIHTTPRequests into and I push a lot of requests through it limited to 4 simulataneously.
Around line 717 of ASIHTTPRequest.m there are (rare) occasions when the readStream is NULL and
the following line crashes the app:
[self setTotalBytesSent:[[(NSNumber *)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPRequestBytesWrittenCount) autorelease] unsignedLongLongValue]];
In order to distinguish between multiple queues it would be great if ASINetworkQueue gets a "userInfo" NSDictionary.
I've already added it to this gist source here: http://gist.github.com/215015
Hi,
I noticed that it's possible to configure ASIHTTPRequest to automatically retry a set number of times. But it seems that to retry immediately after it has failed. I think an (exponentially growing) delay between the failed attempt and the next attempt would be better.
M
Little bug in line 1739 of ASIHTTPRequest.m:
NSLog(@"Request will redirect (code: %hi): %@", self, [self responseStatusCode]);
Should be:
NSLog(@"Request will redirect (code: %hi): %@", [self responseStatusCode], self);
Progress tracking code feels messy and contains lots of repetition.
lhunath's fork has moved the queue progress methods into a protocol, it would be worth looking at this too.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.