Re: Write stream proxy
Re: Write stream proxy
- Subject: Re: Write stream proxy
- From: Jack Brindle <email@hidden>
- Date: Fri, 12 Sep 2008 11:18:43 -0700
- Thread-topic: Write stream proxy
Philip;
Thanks. There are several things you said that helped my understanding. Now
I understand why I am getting the pipe failure. Obviously the read stream is
being closed, with the write stream open, and data comes in that can't be
handled.
In your example, you show the write stream being scheduled. Should the reply
stream also be scheduled, or maybe it be instead of the write stream? As I
see it, anything that gets send back from the server will show up on the
reply stream and must be handled there. I send data out on the write stream
and not the reply stream. Is this correct?
The next question is for the proxy folks. Do I apply the proxy on the reply
stream or the write stream? If the above is correct, then the challenge will
come in on the reply stream, but I'm not sure the right things is to apply
it there.
The light bulb is surely getting brighter...
Jack Brindle
On 9/11/08 3:35 PM, "Philip D. Wasson" <email@hidden> wrote:
>
> On Sep 11, 2008, at 16:45, Jack Brindle wrote:
>
>> Mark's suggestions were also very interesting. I have just a few
>> comments.
>> Our application must run on Tiger, so the CFStreamCreateBoundPair call
>> Is probably out. But this gets us back to the question as to whether
>> we
>> really need a socket pair and what is its purpose. I'm still chewing
>> on the
>> rest of his suggestions, they make a lot of sense, and are pretty
>> close to
>> what we are doing now. It does get me back to the question as to why
>> the
>> pipe breaks when we receive the proxy challenge on the write stream.
>
> We do something similar in one of our applications, although we don't
> have to deal with the proxy issues.
>
> You need to use CFReadStreamCreateForStreamedHTTPRequest because you
> can't simply give it a complete request since you're reading it or
> generating it from multiple location and it can be huge. The result of
> that call is a read stream from which you can read the reply. But you
> also need to give it a read stream from which the system can read the
> data you're sending. (It reads it from you, then writes it to the
> server.) Unfortunately, you can't create a custom read stream, but you
> can create read and write streams with sockets. If you have a pair of
> sockets that form a pipe, you can write into one end and the mechanism
> behind CFReadStreamCreateForStreamedHTTPRequest can read that data out
> and send it along.
>
> What we do is use the posix socketpair function to create two sockets
> that talk to each other. Then we call CFStreamCreatePairWithSocket,
> twice, to create a read stream bound to one of those sockets and a
> write stream bound to the other. Then we can give that read stream to
> CFReadStreamCreateForStreamedHTTPRequest and write into the other end.
> And it works on Tiger.
>
> Hastily condensed code sample:
> int mySockets[2] = { 0, 0 };
> CFReadStreamRef theFileReadStream; // CFHTTP reads our content from
> this end
> CFWriteStreamRef theFileWriteStream; // we write the encoded file
> data into this end
>
> socketpair(AF_UNIX, SOCK_STREAM, 0, mySockets);
> CFStreamCreatePairWithSocket(NULL, mySockets[0], &theFileReadStream,
> NULL);
> CFStreamCreatePairWithSocket(NULL, mySockets[1], NULL,
> &theFileWriteStream);
> CFReadStreamSetProperty(theFileReadStream,
> kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
> CFWriteStreamSetProperty(theFileWriteStream,
> kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
> CFStreamClientContext myClientContext = {0, this, NULL, NULL, NULL};
> CFWriteStreamSetClient(theFileWriteStream,
> kCFStreamEventOpenCompleted | kCFStreamEventCanAcceptBytes |
> kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
> (CFWriteStreamClientCallBack)MyWriteStreamClientCallBack,
> &myClientContext);
> CFWriteStreamScheduleWithRunLoop(theFileWriteStream,
> CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
> CFWriteStreamOpen(theFileWriteStream);
> CFReadStreamOpen(theFileReadStream);
> CFReadStreamRef theReplyStream =
> CFReadStreamCreateForStreamedHTTPRequest(
> kCFAllocatorDefault, myRequestCreatedElsewhere,
> theFileReadStream);
> // theReplyStream has Retained theFileReadStream so we can release and
> forget about it.
> CFRelease(theFileReadStream);
>
> I would expect that if there is some problem with the upload, you'll
> hear about it in the callback for the read stream created for the
> request (theReplyStream in my example above). If that happens, it
> probably closes early the read stream it's reading content from
> (theFileReadStream above), which could cause an error in the write
> stream that's attached to it (theFileWriteStream above). I would think
> that if you get any fatal errors in theFileWriteStream's callback, you
> can ignore them (after giving up trying to write) if your reply stream
> is dealing with something more interesting.
>
> I hope that helps some and didn't cause more confusion.
>
> ----------------------------------------
> Philip D. Wasson
> email@hidden
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden