Extreme streaming #396

Closed
wants to merge 35 commits into
from

Conversation

Projects
None yet
5 participants
@lansing
Contributor

lansing commented Jun 30, 2012

Hey homeboy, check out this reimplementation of the HTTP multipart stuff. Rather than piling on one hack after another to get the temporary file stuff working, I created an nsinputstream subclass that aggregates your form datas and your file urls, handles building the headers, and doesn't use any temp files.

It's basically a drop-in replacement for the previous implementation, although I cut out a bunch of the public API for composing the request. I feel like there's no point in taking pains (and believe me, it was painful) to build a multipart request correctly via this method, only to let people bone it up themselves by appending data without the proper headers, etc. If they want to do that they should subclass. So really all you can do is attach a form data object or attach a file.

There are a bunch of stubbed out methods in the nsinputstream subclass which are simply required to avoid a runtime exception (not that Apple documented this fact). I also added the MobileCoreServices framework to the ios project, which is required to get the MIME type from the filename (although it's kinda not chill that this will break existing projects that don't have this framework added, with some bogus error).

pal and others added some commits Jun 1, 2012

Updated README to explain how to set the `-fno-objc-arc` for all file…
…s at once, saving a bunch of clicking for users.
Mattt Thompson
Merge pull request #359 from pal/master
README: Set `-fno-objc-arc` for all files at once
Adding additional note about not ever really having to manually incre…
…ment or decrement the activity count on AFNetworkActivityIndicatorManager
[Issue #368] Checking for non-zero data length before attempting to a…
…ppend to write to output stream in multipart form data builder
Merge pull request #376 from AFNetworking/experimental-default-http-p…
…ipelining

Automatically use HTTP pipelining for GET and HEAD requests in AFHTTPClient
Merge pull request #381 from ltbl/master
AFHTTPClient adds an unnecessary data when constructing a multipart request with nil parameters
reimplemented multipart form data to use a body streaming object that…
… aggregates file streams and in-memory data objects to compose the request body just in time. also trimmed the multipart form body public API and added CoreMobileServices framework to enable lookup of MIME type by file extension.
@hwaxxer

This comment has been minimized.

Show comment Hide comment
@hwaxxer

hwaxxer Jul 16, 2012

This is a great addition but I had issues getting it to work. The server receives the data correctly, but oddly enough the NSURLRequest never completes or fails, it just times out after the specified timeoutInterval. Something wrong with the headers?

hwaxxer commented Jul 16, 2012

This is a great addition but I had issues getting it to work. The server receives the data correctly, but oddly enough the NSURLRequest never completes or fails, it just times out after the specified timeoutInterval. Something wrong with the headers?

@lansing

This comment has been minimized.

Show comment Hide comment
@lansing

lansing Jul 16, 2012

Contributor

I ran into this in my own usage but thought I had fixed the bug. The client should hang up automatically when the nsinputstream subclass returns zero bytes from a read or hasBytesAvailable returns NO, so it's likely that your use case has exposed a bug related to that behavior. That is my working assumption, anyway. The official NSStream subclassing documentation is nothing but half truths and outright fabrications so I'm learning via trial and error.

It would be great if you could provide a code snippet of your multiple request composition block. I'll try and recreate the issue. What is your server stack?

Contributor

lansing commented Jul 16, 2012

I ran into this in my own usage but thought I had fixed the bug. The client should hang up automatically when the nsinputstream subclass returns zero bytes from a read or hasBytesAvailable returns NO, so it's likely that your use case has exposed a bug related to that behavior. That is my working assumption, anyway. The official NSStream subclassing documentation is nothing but half truths and outright fabrications so I'm learning via trial and error.

It would be great if you could provide a code snippet of your multiple request composition block. I'll try and recreate the issue. What is your server stack?

@hwaxxer

This comment has been minimized.

Show comment Hide comment
@hwaxxer

hwaxxer Jul 17, 2012

It's just a simple:

[formData appendPartWithFileURL:[NSURL fileURLWithPath:filePath] name:@"item[asset]" error:&error];

The file is already zipped.
It's a rails server. And I'm not sure if it's related, but I've had issues before because the server returns whitespace in the response body on 201.

hwaxxer commented Jul 17, 2012

It's just a simple:

[formData appendPartWithFileURL:[NSURL fileURLWithPath:filePath] name:@"item[asset]" error:&error];

The file is already zipped.
It's a rails server. And I'm not sure if it's related, but I've had issues before because the server returns whitespace in the response body on 201.

@lansing

This comment has been minimized.

Show comment Hide comment
@lansing

lansing Jul 17, 2012

Contributor

To clarify, is this an issue that popped up once you checked out my fork, or were there other changes on client or server (and conversely, it goes away if you switch back to master)?

I didn't change anything in the response handling. Does your client ever start receiving the response data, hitting the appropriate callbacks? Maybe set some breakpoints to find out.

If the server is completing the request on its end, it seems that the multipart form data is probably being written out properly and completely, but the client is still waiting on the inputstream to close.

What's your rails version and what http server(s) are you using? iOS 5 sdk?

Contributor

lansing commented Jul 17, 2012

To clarify, is this an issue that popped up once you checked out my fork, or were there other changes on client or server (and conversely, it goes away if you switch back to master)?

I didn't change anything in the response handling. Does your client ever start receiving the response data, hitting the appropriate callbacks? Maybe set some breakpoints to find out.

If the server is completing the request on its end, it seems that the multipart form data is probably being written out properly and completely, but the client is still waiting on the inputstream to close.

What's your rails version and what http server(s) are you using? iOS 5 sdk?

@hwaxxer

This comment has been minimized.

Show comment Hide comment
@hwaxxer

hwaxxer Jul 18, 2012

Only having this problem with your fork.
The client receives no callbacks after upload progress reaches 100%.
Using rails 3.1.1, iOS 5x.
I'm a bit swamped with other stuff right now, but I'll try to dig into the code to see if I can find something this week.

hwaxxer commented Jul 18, 2012

Only having this problem with your fork.
The client receives no callbacks after upload progress reaches 100%.
Using rails 3.1.1, iOS 5x.
I'm a bit swamped with other stuff right now, but I'll try to dig into the code to see if I can find something this week.

@lansing

This comment has been minimized.

Show comment Hide comment
@lansing

lansing Jul 18, 2012

Contributor

One more thing... do you mind pasting in your AFHTTPRequestOperation init -> completion/progress block setup -> start snippet? Probably boilerplate but i want to make sure I'm hitting the code the same way as you.

Contributor

lansing commented Jul 18, 2012

One more thing... do you mind pasting in your AFHTTPRequestOperation init -> completion/progress block setup -> start snippet? Probably boilerplate but i want to make sure I'm hitting the code the same way as you.

@lansing

This comment has been minimized.

Show comment Hide comment
@lansing

lansing Jul 20, 2012

Contributor

Closing this and making a new pull request with supposed fix.

Contributor

lansing commented Jul 20, 2012

Closing this and making a new pull request with supposed fix.

@lansing lansing closed this Jul 20, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment