Re: Write stream proxy
Re: Write stream proxy
- Subject: Re: Write stream proxy
- From: Jack Brindle <email@hidden>
- Date: Fri, 19 Sep 2008 13:22:26 -0700
- Thread-topic: Write stream proxy
Thanks Mark;
Now just to be sure, in the authentication process:
> create an http message, create a stream, try, fail, get auth, get
> credentials for the auth, create a new stream from the same http
> message, apply auth / credentials, try again.
When creating a new stream from the same http message, do we need to
recreate the read and write streams that are combined into the
CFReadStreamCreateForStreamedHTTPRequest? In other words, when the output
stream from the CFReadStreamCreateForStreamedHTTPRequest is released during
the process, are the read and write streams I am using also released?
I suspect the answer is yes, and this one step is what is keeping my code
from working.
I now believe that when creating the new stream during the authentication
process I will need to also create the paired read and write streams, then
feed the new ones to the CFReadStreamCreateForStreamedHTTPRequest.
On 9/18/08 7:10 PM, "Mark Pauley" <email@hidden> wrote:
> Here's what I mean by that: HTTPReadStreams support HTTP Proxies for
> both the standard HTTP Proxy mechanism and the HTTPS Connect tunneling
> mechanism and host resolution, plus since they're built on top of
> SocketStreams, they'll support SOCKS proxies both for tunneling and
> for host lookup.
>
> CFSocketStreams only support SOCKS proxies, because that's the only
> relevant proxy type for raw socket streams.
>
>
> If you're using the CFReadStreamCreateForStreamedHTTPRequest API,
> you'll get HTTP Proxy support and SOCKS proxy support.
>
>
> To be a bit more clear on the API and your intended use, you only need
> to schedule and set the client on the ReadStream returned from
> CFReadStreamCreateForStreamedHTTPRequest and on the WriteStream which
> pumps data into the ReadStream you pass into the
> CFReadStreamCreateForStreamedHTTPRequest API. You need not set the
> client on the ReadStream you pass into the
> CFReadStreamCreateForStreamedHTTPRequest API, it won't matter anyway
> since we will re-schedule and re-set the client internally.
>
> You are correct in your findings about authentication, the current
> pattern for this is:
> create an http message, create a stream, try, fail, get auth, get
> credentials for the auth, create a new stream from the same http
> message, apply auth / credentials, try again.
>
> Contact me if you need to work with NTLM authenticated servers...
> they're a bit more tricky because they break the general model of
> HTTP, and require persistent connections.
>
>
> On Sep 18, 2008, at 3:26 PM, Jack Brindle wrote:
>
>>
>> On 9/16/08 10:23 AM, "Philip D. Wasson" <email@hidden> wrote:
>>
>>>
>>> On Sep 12, 2008, at 14:18, Jack Brindle wrote:
>>>
>>>> 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?
>>>
>>> You should schedule all of the streams that are being used. I was
>>> going to say "both", but it looks like there are more than that in
>>> your situation.
>>
>> Actually there are just two at present. One for the replyStream and
>> one for
>> the writeStream. This works just fine for the non-proxy instance.
>> For the
>> proxy instance the first transfer is rejected, but all after that
>> work just
>> fine.
>>
>>> I think I'm still a bit unclear about the sequence you use, but let
>>> me
>>> take a stab at it.
>>>
>>> You said you use a control server and a separate transfer server.
>>> Does
>>> a message exchange with the control server direct you to send a file
>>> to the transfer server?
>>
>> Yes. The control server provides the URL for the transfer server.
>>
>>>> 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.
>>>
>>>
>>> I may be misinterpreting what you've said, but it looks to me as if
>>> you're getting the read and write streams' purposes confused.
>>> (Anyone else please tell me if _I'm_ wrong here.)
>>> HTTP is a request/response sort of protocol, so every action on the
>>> client side involves both sending the request and then reading the
>>> response. In order to send the request, you always open a read stream
>>> that will be used to read the reply. When creating the request, you
>>> can either provide a full request message (with all its headers and
>>> body content) and call CFReadStreamCreateForHTTPRequest, or you can
>>> provide the headers of the request plus a read stream for the body by
>>> calling CFReadStreamCreateForStreamedHTTPRequest. In the case of a
>>> non-
>>> file-transfer request, you want to use the first of those, whereas
>>> for
>>> sending a file, you want to use the second, as sketched in my
>>> previous
>>> email. In no case do you receive reply data on a write stream.
>>
>> This tells me that I don't need to look for incoming data on the write
>> stream callback, but just for the stream being ready to accept data
>> or an
>> error. There are then three paths, read and write on the read
>> stream, and
>> write (only) on the write stream. In our case the control server is
>> on the
>> read stream, and the transfer server is on the write stream. The proxy
>> challenges for the transfer server come in on the read stream. It
>> appears
>> that applying the challenge response to the read stream also applies
>> it to
>> the write stream.
>>
>>> So, let's say you want to send a message to the control server. You
>>> create and fill in a CFHTTPMessage, then call
>>> CFReadStreamCreateForHTTPRequest, then schedule and open that read
>>> stream and eventually get the response. Then you want to send a file
>>> to the transfer server. You create another CFHTTPMessage and set any
>>> headers. Then you open a pair of streams, read and write, with which
>>> you can supply the file data, as discussed previously, and schedule
>>> and open both of them. Finally, you call
>>> CFReadStreamCreateForStreamedHTTPRequest, providing it with the
>>> CFHTTPMessage and the read stream half of the pair. If you need to
>>> specify a proxy, you can set the kCFStreamPropertyHTTPProxy property
>>> of the resulting read stream ref. You then schedule and open that
>>> stream, which begins the transfer. I don't have experience with proxy
>>> authentication, but I get the impression that if you need to provide
>>> some authentication, this reply stream will include the error, ending
>>> that whole exchange, and the write stream will get an error because
>>> nobody's reading it anymore. So then you repeat all that except you
>>> also supply whatever authentication credentials are required in the
>>> CHTTPMessage.
>>> Note that without having to repeat due to a proxy authentication
>>> challenge, this pair of requests uses three read streams and one
>>> write
>>> stream. The write stream is not really what you're sending the file
>>> transfer request with; it's just feeding data to the request-sending
>>> mechanism behind CFReadStreamCreateForStreamedHTTPRequest.
>>
>> That last sentence explains a lot about the double-socket process.
>> Now it
>> makes sense...
>>
>> What I am actually seeing is the challenge comes in on the read
>> stream, the
>> authentication response is applied and we retry the the
>> transmission. Except
>> that the actual file transmission is not being restarted, which is a
>> logic
>> flaw in my code. Interestingly if I then try another transfer it
>> works just
>> fine, using the authentication information that was just set up.
>>
>> The proxy setup and code is really very interesting, and anyone who is
>> setting up a client that could be behind a proxy really needs to
>> implement
>> it. It would be a lot easier, though, to use higher level calls that
>> handle
>> it automatically. Better docs would help also... ;-)
>>
>>> I hope I'm not too wrong about the proxy stuff...
>>>
>>>
>>> ----------------------------------------
>>> Philip D. Wasson
>>> email@hidden
>>>
>>>
>> Thanks a bunch for your help and that from Mark and Quinn. I hope (and
>> think) that I have this just about right at this time. The one thing
>> that
>> continues to bother me is Mark's comment that it might only work for
>> the
>> socks protocol and not HTTP proxy. I really hope it is more universal.
>>
>> Jack Brindle
>> YouSendIt, Inc.
>>
>> _______________________________________________
>> 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
>
> _Mark
> 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