WWDC2004 Session 406
Transcript
Kind: captions
Language: en
and with that would like to introduce
Becky well rich and chill
about modern networking using CF network
hi I'm Becky will return the technical
lead for CF network and i'll be talking
to you about how you can use CF network
into Mac os10 application what we're
going to cover today is we'll start out
with an introduction and overview we're
going to breeze through that pretty fast
because I figure that's review for most
everybody at this point we're going to
talk about what's new and tiger in
particular we're going to highlight two
new classes CF met diagnostics and CF
HTTP authentication then we're going to
look at a couple of common CF Network
tasks that we know from feedback from
you is something you want a little more
guidance with we're going to look at how
you manage proxies using CF network and
how you can use CF network to perform
asynchronous host look up and then
finally at the end we're going to wrap
up by comparing CF network with some of
the other URL loading api's on the
system and help you figure out which one
is most appropriate for the programming
task you have so I'm going to dive
straight into the introduction and
overview now what we're going to do is
start out by talking about what is CF
network and then we're going to look and
see how CF Network fits into the Mac
os10 stack as a whole and then finally
we're going to look at the feature set
in depth so CF network is chock-full of
network II goodness I have this on high
authority from a co-worker what TF
network is is a framework that provides
high level AP is for a number of
different Internet protocols and I
listed them here well what do I mean by
high level I mean higher level than BSD
sockets I do not mean high level like
you know just give me the URL and go do
some magic and give me the data it's not
that high level but it is better than
the sockets it's better than managing
selects yourself ins and parsing
yourself we also provide support for
dance features like proxies and
authentication so you don't have to
program those yourself one of our goals
is to provide web compatibility because
you know wonder of wonders not every
server out there is actually HTTP
compliant
we do our best to provide full access to
those servers anyway and it's worth
noting that the HTTP engine that
underlies Safari is in fact CF network
so every time you download a URL off the
web using Safari you're going through CF
network code CF networks api's are all
in the style of core foundation that has
two important consequences the first one
is that you're constantly using CF types
so you're going through the holes of CF
retain CF release reference counting
saying we use a couple types from the
core foundation pretty heavily CF read
stream and CF right stream we also add
new types in CF network those are all
CFCF types as well I listed three common
ones here CF host CF net services CF
HTTP message all introduced in CF
networks all also CF types the other
important consequence of having an API
based on core foundation is that we
produce all of our a synchronous using
CF run loop so the advantage of that is
that it fits in very easily with your
applications natural event model carbon
events and NS run loop are both built on
top of CF run loop so CF Network fits in
very naturally with that event model
however it also means that if you want
to use CF network to its best effect you
are going to need to understand CF run
loop to program it effectively it's not
going to be important for this talk but
just to warn you when you get into the
code itself you're going to want to have
a good understanding of CF run loop so I
said before I CF network is not this
convenient API where you give you hand
over the URL and you're like please just
download the data I don't want to know
the details there are api's on the
system that do that for you but CF
network is not it pardon me so for
example we do not automatically apply
any settings for you CF network is
intended to be a power API where
you go through and explicitly set each
bit and flag that you are interested to
customize the process the other part of
the goal is to expose the full power of
the protocols that it implements so you
can very explicitly turn on and off
every individual feature of the protocol
you're using now the upside is that you
do in fact have full control the
downside is that you really need to have
some understanding of the protocol
before you're going to be able to use CF
network to good effect so here's an
architecture diagram of Mac OS 10 you
guys have probably seen this a few
million times by now Darwin our UNIX
implementation is the core OS and then
we have various layers of libraries all
the way up to the applications at the
top CF networks fits into this core
services later so that's below the
graphics layer at the point where all of
the basic services that pretty much
every process on the system uses unless
it's a pure unix process and if you look
specifically at the networking pieces in
the stack here's how they line up CF
network is what's available at the core
services layer it's built on top of
Berkeley sockets tcp/ip rendezvous and
DNS implementations all available from
the core OS Darwin layer not much going
on in the networking world that the
application services layer which isn't
surprising that's where the graphics the
graphics and user event let pieces are
added but then above and the application
framework layers nsurl and WebKit become
available and then built on top of all
of this stack you'll see all of all of
the major networking apps on our system
like ichat sherlock safari males itunes
so specifically what feature set does CF
Network provide well first of all it
provides an abstraction for TCP socket
streams we went beyond supporting basic
TCP though to add in support for TLS and
SSL and socks proxies CF hosts gives you
access to DNS and in particular provides
asynchronous
host resolution then we have streams to
support both the HTTP and the FTP
protocol CF net services is your API
into rendezvous CF net diagnostics is
new and we'll talk about it some more in
a little bit and then of course we have
integrated proxy supported all these
layers so that if you need to use if you
need to apply a proxy setting you can do
that that's as much of an overview as I
want to give and from here I'm going to
dive into what's new in Tiger I've
already said that we have two new types
CF net diagnostics and CF HTTP
authentication we also have some new CF
net services api's and we have some new
settings on socket streams excuse me
specifically to allow you to customize
SSL and TLS sessions so what is CF net
diagnostics the basic scenario is this
you're in the middle of some networking
task and for some reason it's not
working you don't know why you just get
an error code back from a download for
instance or some kind of a POSIX error
that tells you that the network has gone
bad how do you report that back to the
user in some meaningful way and how do
you help the user move along to fix the
problem so that your program can work CF
Matt truck Diagnostics provides an easy
interface for you to lead the user
through these tasks so what kind of
problems to see if met in CF net
diagnostics prepared to diagnose
anything from a simple physical
connection failure someone's unplugged
the ethernet cables or a networking
failure like the router is not working
for some reason packets are just not
going through or a dns or dhcp server
has gone been to configuration failures
the user just did not enter the right
thing in the network and the network
system preferences panel CF net
diagnostics gives you away to prompt the
user about the problem and then move
through it and help the user to correct
the problem
looks like this so what would happen is
you would encounter this network failure
you'd lead the user to this panel
essentially and this panel would go
through the five steps you see on the on
the left to try and determine what's
gone wrong once it hits a problem in the
network pet in the network settings it
tells a user about it and tells them
what they can do to correct it once the
user is corrected it it goes further to
tell the user it that the situation has
been corrected so what's the advantage
of CF net diagnostics well the biggest
advantage well the biggest advantage is
you don't have to write the code but the
second biggest advantage is it provides
a uniform interface to the user it
allows you the programmer to easily
query what the network connectivity
status is you know is a network
functioning properly or not and if it's
not it gives you a localized string that
you can present directly to the user to
explain what's gone wrong having done
that it further leads the user to that
panel we just saw so that the user can
then go and try and correct a problem
themselves there a sample code available
showing how CF net diagnostics work
unfortunately due to a mastering error
it does not appear at this path on your
tiger CDs however it is included along
with every other sample code piece that
I'm going to talk about in the disc
image for this session so I encourage
you to download the discussions the disc
image for the session and grab the
sample code from there so how's it going
to look in your application it's
actually a very simple minimal API and
what I've got here are the three lines
of code that you're going to need to add
to your program to integrate CF net
diagnostics you can see at the top what
we've done is we've read bites from a
stream and we got a negative 1 return
which tells us that an error has
occurred so what where do we go from
there well it's pretty straightforward
we take the failed read stream the read
stream that we could not read from and
instantiate a net diagnostic object from
it
having done that we call met diagnostic
copy network status to retrieve an error
string that we can now display to the
user and we're going to display it in
some kind of an alert panel that says
that has an ok button to just dismiss it
and continue and a diagnosed a button to
draw to lead the user to further do
perform diagnosis if the user clicks the
diagnose button we're going to call this
line at the bottom diagnose problem
interactively that's going to return
immediately from your programs point of
view but from the users point of view
it's clean it's going to launch another
application and bring up a panel so that
the that will help the users start to
diagnose the problem so that's net
diagnostics and now I'm going to move on
to talk from about HTTP authentication
we've had authentication support for
HTTP in CF network for a long time now
at least a couple three years however
we've made some substantial changes in
tiger historically HTTP authentication
has supported basic and digest schemes
since since I last talked to you here
last year we've added support for ntlm
and span ago which are a couple schemes
that are common in the windows world and
the existing old API the one that's been
available for years was designed for
single shot transactions you'd send
issue a request and get back an
authentication challenge once you get
the challenge you call this as you call
the old API it corrects the request you
issue the request again and away you go
and it works fine the problem was that
you don't usually issue just one request
to a server you usually issue 10 or 20
and it seems a shame to have to go
through this process for each and every
request so that's why we added CF HTTP
authentication and tiger to allow you to
carry state forward from one request to
another going to the same authenticating
server so here's the old at the old API
CFH
GDP message add authentication every
request is processed individually each
time you receive a challenge you get the
credentials from the users you apply the
credentials to the request and then you
issue the entire request again and there
was no persistency across multiple
requests to the same servers the new API
uses an object of CF HTTP authentication
object to carry that state across from
request to request and that gives you
much better performance particularly
when you're talking to some some host
that has one of these very expensive
authentication schemes that requires for
instance multiple legs just to compute
keys and negotiate protocols so how's it
going to work in code in code you're
going to maintain a set of CF HTTP
authentication objects when you receive
an authentication challenge you're going
to look through the set of objects to
try and find one that applies if you
find one great if not you're going to
create one once you have that object you
apply it to the request along with
credentials from the users and CF
network will use the information stored
in that object to process the request as
efficiently as possible gives much
better performance this is the
authentication scheme used by Safari and
again we have sample code available
we've updated the get example inside
developed or examples networking to
include support for authentication so
here are the api's you're going to use
along the way from the store from the
store of authentication objects you'll
use CF HTTP authentication applies to
request to find out whether the auth
object applies to the request you're
trying to handle if you have to create
one from scratch you'll use create from
response once you have that off object
you need to check to see if the object
is valid reason why you need to do that
is because the authentication object may
go stale over time assuming it's valid
you get the credentials from the user or
from some shared store that you have in
mode you can use requires username and
password and requires account domain to
figure out what information you need to
collect from the user and then finally
you're going to apply all of the pieces
to the request to correct the request
and prepare it for an authenticated
transaction with the server and you're
going to you're going to do that using
apply credentials dictionary now there
are a couple tricks that you have to be
aware of when you're using HTTP
authentication the first one is that
some authentication schemes will only
work it's the subsequent request go out
over precisely the same socket as the
initial request went out over so that
means you have to turn on persistent
connections so when you're when you're
in a situation where you're trying to
handle authentication make sure you have
persistent connections turn on turned on
but further than that in order for the
persistent connections to Garrett to be
guaranteed to stay open you have to make
sure to keep open one stream to hold
open that socket inside CF network for
the subsequent requests so what I
recommend is that as you're going from
request to request don't close the
stream for the old request until you've
opened the stream to the new request
that'll guarantee that the socket
underlying the connection will be kept
open and reused the other thing to be
aware of is that some of the
authentication schemes require multiple
legs back and forth to the server just
to negotiate hash values protocols
whatever so that means that even though
you have you have applied authentication
once to a particular request that
doesn't mean that it will automatically
work from there you may have to keep
reapplying it over and over again until
finally the server negotiation gets to a
point where the server is ready to
return the data the simple rule is just
keep reapplying the authentication
object until or unless it goes invalid
the auth object knows how many legs are
required it knows when the credentials
are simply wrong or when the
server has decided to shut down the
transaction at that point you can fall
back and figure out how to handle a
failure case so with that I'm going to
switch over to the demo what I've got
here is a simple application which
downloads URLs so I can type in dub dub
dub apple com and click start and click
start there we go scared me for a moment
there and you can see that the URL was
downloaded down here so here we're
looking at all the text for dub dub dub
apple com and at the top we just the way
I've just displayed a summary of the
status line now there are a couple
things that are not working properly in
this demo the first one is that failures
are not handled in a particularly
interesting way so if I go to
www.hsn.com back with a little error
string right here which is in fact what
the code is set up to do just now that's
not very interesting feedback to the
user so what we're going to do is add
net diagnostics to this application also
even though we have a username and
password configured here earth you I set
up here this isn't hooked up in any way
so even if I go to an authenticating
site like jigsaw dubbed reorg this is a
little site set up by the doubletree
consortium to let you test
authentications authentication code so
we go there
there we go and it comes back with a 401
on unauthorized because we haven't
provided username and password well even
if I provide the correct username and
password it's still going to come back
with this 401 so what we're going to do
is we're first going to hook up net
diagnostic so we can give better
feedback to the user and then we're
going to add authentication to this
application I'm going to quit this app
and come and look at the code here so
this code is also on the disk image it's
a very simple cocoa application it has
just one class download controller which
is wired up to the UI and to integrate
net diagnostics what I'm going to do is
go to the handle error method and here's
the simple the simple error string that
you would have seen it does nothing but
pull the error out of the read stream
and formatted and display it in the text
view that's not very interesting so
we're going to get rid of it and we're
going to replace it with net diagnostics
code the CF met diagnostic ref dude
Diagnostics get if net diagnostics
create with strings null allocator
stream is the instance variable that's
that storing the failed read stream and
we don't have a right stream so that's
there now we need a string rest for the
error error string CF net diagnostics
copy network status passively diag at
air ok so what that calls going to do is
it's going to use a Diagnostics object
and ask for an error string describing
the failure that error string is going
to be put into air now if you're not a
cocoa programmer I'm going to ask you to
just take my word on this I'm about to
add a line that's going to run an alert
panel and its run alert panel first
argument is the title second argument is
a printf string for the contents of the
panel third argument buttons default
button third argument is the alternate
button so we're going to have an
alternate button of diagnose which if
the user clicks we're going to use to
head off in to see if net Diagnostics to
bring up that diagnostic panel don't
have a third button and finally the
argument for the printf okay so that's
going to run an alert panel and what
we're going to do is if the result from
that is NS alert alternate return then
what that means is the user clicked
diagnose and we're just going to call CF
net diagnostic diagnose problems
interactively I'm really a much better
typist when I'm not on stage and that's
it we're done oh except for a little
cleanup we should release the objects we
have created oh there we go oh good all
right so so now let's just see what
happens
oh yes thank you and is it yes yes and
there is no F here either try this again
okay that does not look good there we go
alright it's just taking a little time
alright so given that the DNS server
doesn't seem to be too happy with us
right now I'm going to create a much
simpler networking failure that's a very
simple networking failure now let's see
if we can go to dub dub dub apple com no
we can't and here's that alert panel it
comes up and it shows us a string chosen
by CF net diagnostics the systems
internet connection appears to be down
all right let's see what CF net
Diagnostics can tell us about that so
here's the Diagnostics panel and it was
going to go through these five different
types of networking errors but in fact
it failed immediately the first one the
built in ethernet is not working so are
we trying to connect to the internet for
the first time no we're not we're trying
to configure the ethernet and now it's
as well the ethernet ports not active
let's check the following things and
you'll notice in this list one of them
is into the ethernet cable plugged in
well look at that no it's not so let's
just plug it back in let's just plug it
back in there we go and now you can see
net Diagnostics discovered that we've
corrected the problem and is going
through and checking the remainder of
our configuration
and now if I go back here i can download
apple com now I have to have make a
little confession here what you're
looking up looking at up here is pure
demo where if you were to build this
program on the WWDC seed that you
received you would not see that series
of panels and said you'd see a
placeholder panel which would tell you
that yes met Diagnostics fired correctly
it would tell you what application had
brought it up and what the code entry
point was but it wouldn't actually lead
you through that series of panels the
series of panels will of course be there
for the final tiger release we didn't
have them quite ready to where we were
willing to include them in the seed so
for the seed you'll just see the
placeholder panel which is hopefully
enough to allow you to develop your code
so having done that now let's add
authentication authentications a little
more complex than just using CF net
diagnostics to do that I'm going to need
to add two new instance variables
authentication ref so this is the auth
object that I'm going to use to store
the current authentication state and I'm
going to add a CF mutable array to store
the set of all authentication pieces
that I've received so that's the change
to the header file now over here in the
source file we need a couple bookkeeping
things first of all we'd better release
the objects when we're when we're
deallocated so we don't leave
secondly in the stop download method
this is what happens when the user
clicks top or when the stream is finally
exhausted in the data has been
successfully loaded we need to throw out
the auth object if one exists so it's
not carried forward to future requests
okay so that's the bookkeeping now to
actually do the work we have a method
here evaluate headers this is going to
fire the first time we get a look at the
headers back from the server so what we
want to do is look for an authentication
failure which would be a status code of
401 or 407 and if we have such a
response we want to attempt
authentication so here if we gotta
respond if CF HTTP message get response
status code response we're just going to
deal with 401 for the demo 407 s would
be a proxy authentication failure it's
pretty it's pretty much straight forward
in the same code for that so if we got a
401 we're going to attempt
authentication and we'll pass the
response we received and if that
succeeds so if this method returns true
then we're going to return no telling
the surrounding code ignore the stream
you've been looking at there's a new
stream coming okay I'm at it for that
code now all we need to do is write this
attempt authentication method well I'm
not going to force you to sit here and
watch me introduce a million typos I
actually have that method already
written up here and what I'm going to do
is just uncomment it and walk you
through it the first thing we do is look
and see if we already have an
authentication object if not we're going
to try and find one and we'll do that by
walking through author a for each item
in auth array we ask it does it apply to
our request
if so that's still not good enough we
want to know if it's still valid if it
is valid all right great then we store
it in our instance variable and break
out of the loop otherwise where there's
no there's no need to hold on to invalid
authentication items so we dispose it
and up and do some updating for the loop
once you reach once we're outside of
that loop if we still don't have an
authentication object that means we
couldn't find one so now we're going to
create one so we call CF HTTP
authentication create some response now
it is actually possible for a newly
created authentication item to be
invalid off the bat what that usually
means is that the server has chosen to
send an unauthorized response without
any information about how you can
correct the error the server is not
going to let you authenticate period
there are some other possibilities there
could be some missing headers in the
response but the main one is that the
server is simply not going to let you in
so you do have to check to make sure
that the authentication object you just
created is in fact valid if it is
terrific we'll add it to the shared
store if not then we're then we give up
so now coming down here at this point if
we don't have an authentication object
we're simply not going to get one and
we'll see at the end here that we simply
punt in that case however assuming we
did get an authentication object we look
to see if it requires an account domain
and if it does again we're going to punt
because my you I wasn't clever enough to
prompt for a domain that mostly means
we're giving up on ntlm that's the one
authentication scheme that requires a
domain aside from a user in addition to
user names so in that case we release
off and just return know otherwise we
come down into this code if the
authentication requires a username and
password we go and haul it out of the UI
and then we call HTTP message apply
credentials to apply the authentication
we've got to the request assuming if
that fails return no and bail otherwise
we're going to ultimately return yes
say that the authentication has
succeeded now comes the part where we
have to deal with the with the problem
of persistency we cannot dispose of the
old stream until the new stream is well
established so right here we do all the
work of setting up the new stream this
is all standard CF network code create
the new stream set the client scheduled
it with the run loop set what other
whatever properties you need and then
open the stream once we've got that
stream setup we can now go and dispose
of the old stream close it set the
client to null on schedule and release
and ultimately set our instance variable
to point to the new stream at this point
we're done and we can return yes
authentication has succeeded so let's
see if it actually works ok so let's go
to jigsaw dub three org that same test
site so without a username and password
there we go comes back with a 401
unauthorized but this time when we
provide the username and password click
start we come back with the 200 ok and
if we were to look at this if we were to
look at the data we received yeah your
browser made it ok but if I give the
wrong username and password again we get
the 401 unauthorized so they are in
about 10 minutes we've added met
diagnostic capability and HTTP
authentication to a simple download
application
if I could get back to the slides if I
could have the slides back great okay
there are a couple other API new API is
I want to mention we redid the CF net
services ap is that's the api's would
give you access to rendezvous via the
run loop we redid it and Tiger not just
because we love making you change your
code we did it because we need to fix a
few problems that we uncovered with the
earlier api's and at the same time we
found that the earlier api's were
insufficient to pick up some new
features being exposed by a core OS we
are deprecating the old API that doesn't
mean that it will suddenly stopped
working it will still work as it always
did but one of the big things that
you'll pick up by going to the new API
is better network better network i/o
performance so we encourage you to
transition when you're ready to the
transition is as simple as we could make
it it's very nearly search and replace
and what I've done is I've listed here
what the old calls were and what the new
calls would be to help you with the
transition the release notes which are
on the tiger CD and also in the disk
image for this session give full
instructions for how to how to
transition to the new API we also
updated the echo & echoplex amples which
use CF net services to discover the
clients in the server to use the new API
so you can look there for more examples
there is one important difference that I
want to mention CF net service resolve
has been replaced with CF net service
resolved with timeout the reason well
one of the reasons why is that CF net
service resolve would leave open the
resolution until it was explicitly
canceled and what we found out is that
this was completely unexpected by most
people and so they would call Matt
service resolve they would get back the
resolution the
so they would get back the information
they were looking for and then they
would assume that the net service was
done well it wasn't it's still consuming
bandwidth it's still consuming network
time until it's explicitly cancelled so
CF net service resolved with timeout has
slightly different behavior it now will
exit when either a suitable address has
been found where the timeout has been
reached and as a result it consumes
considerably less network bandwidth now
there was one legitimate time when you
would want to leave a net service open
and running forever you would want to do
that if you were monitoring a single net
service and waiting for changes to occur
to address that problem we've added a
new type CF net service monitor new and
tiger and where you used to use a
long-running CF net service resolve call
together with get protocol specific
information so you could find out what
had changed about that net service
instead just use net service monitor it
has a much more efficient smaller
network footprint in terms of the
traffic the other new API is just a
couple new properties on CF socket
streamed they're both targeted to allow
you finer control and a better
understanding of what has happened in
the ssl/tls negotiations for secure
socket streams the first property is kc
f stream property ssl pier certificates
this is a retrievable property you can
retrieve any time after the ssl
handshake has completed and what it's
going to return is an array of the
certificates that the server has has
used to present itself for the pier
who's used to present itself so it's got
every certificate from the root
certificates to the certificate given by
the server you can look at them in depth
you can do any kind of evaluation with
it that you'd like the other property is
kc upstream property ssl settings this
is a settable property its value as a
dictionary the keys of the dictionaries
are a number of
configuration options which you can find
in CF socket streamed H and it allows
you to control how CF network will judge
the pier certificates by and large and
how CF network will work we'll handle
the head the TLS or SSL handshake I'm
not going to go through these in huge
details these are all the different
properties you can set SSL level lets
you choose TLS v1 or sslv3 or what kind
of fall back you want allows expired
certificates and allows expired routes
allows any route pretty much
self-explanatory validate validate some
certificate if Akane whether you want CF
network to even look at the certificate
chain or whether you want to do that
yourself or you want to leave yourself
wide open to whatever the server gives
you ssl pier name allows you to set the
expected name that you that you're
expecting to see on the certificate from
the remote side because you might
connect my IP address but the
certificate the certificate is going to
display a hostname and so you need to
set that separately ssl-certificates
allows you to set the certificates for
your side of the ssl transaction so
that's what you would use if you wanted
to do client-side certificate checking
or if you wanted to write a server
yourself speaking of servers you'd set
SSL is server if you were performing the
server side of the transaction as
opposed to the client side default
values are all documented in CF socket
stream th in general the defaults are
for the strongest security possible and
the maximum amount of checking so you
would need to set these to make the
requirements more lacs that's the new
API is that we have available in tiger
now I'm going to take a moment to talk
about the difference a couple different
CF Network tasks in particular we're
going to talk about how you use proxies
using CF network and how you would
perform an asynchronous DNS lookup
so one of CF networks strengths /
working with other networking stacks or
writing your own is that it's prepared
to handle complex combinations of
proxies so if you look at the system
settings the users turned on a socks
proxy and an HTTP proxy and an HTTPS
proxy and you don't know which one
you're going to use and you don't you're
not sure how the different
communications are handled well CF
network does CF network can figure out
which proxy should be applied and then
do the correct communication for that
type of proxy however CF networks not
intended in the convenience API so you
have to explicitly turn proxies on to
get proxy support from CF networks
you're always going to do that by
calling CF read stream set properties
and the key or the property you're going
to set is whatever proxy setting is
appropriate for the kind of stream
you're using well so one of the
questions we get as well as an HDTV
proxy and there's a socks proxy and I'm
work but I'm working with an HTTP stream
do i set the socks property a proxy
property or the HTTP proxy property
always set the highest level so in that
case you would be setting the HTTP proxy
if you were working with an FTP stream
you would set the ftp proxy property
even if the proxy you're applying is
socks for instance you should also
always apply the proxy settings before
opening the stream because we need that
information before we establish the
correct socket and what we found is that
our developers use proxies basically in
two different ways either they simply
want to apply the default system proxy
configuration or they know that their
case is special in some way and they
have a custom proxy server that they
wish to apply regardless of what other
settings may be present so here's
probably the more common one you just
want to use whatever the current system
proxy settings are well the good news is
that while you have to be explicit about
this its really fairly straightforward
just call FC dynamic store copy proxies
that will get you the default proxy
dictionary or the system proxy
dictionary out of system config
and apply it blindly to the stream don't
look at it don't tear it apart just pass
the whole schmear through CF read stream
setproperty streams property HTTP proxy
and the dictionary you got back from
system config that's it CF network will
pull the dictionary apart figure out
what the correct settings are and use
them if on the other hand you need to
use a custom proxy configuration you're
going to need to create the custom proxy
dictionary yourself look in the correct
stream header file to find out what the
keys are you're going to need a key for
the host and a key for the port and
those are the only two keys that you
need present in your dictionary some
proxies most notably thought have some
additional keys you could set if you
would like you can take a look at those
those aren't actually required once you
have constructed that dictionary you
apply it exactly the same way by calling
setproperty stream HTTP proxy dictionary
so here's what it looks like in code
create a mutable CF dictionary set value
proxy host whatever the host is set
value proxy port whatever the port is
then called CF read stream setproperty
exactly as you did before so another
task that's pretty common that we hear
about is the need to perform an
asynchronous host look up what do I mean
by that well you have a host name you
want the IP address so that
straightforward and the traditional UNIX
calls for this or get host by name or
the slightly newer get a tour info but
the problem with those calls is that
they're blocking they're going to tie up
a thread and they're not going to return
until they have the answer that makes it
very difficult to process multiple
multiple host names at once so the
solution to that is to use CF host
instead CF host is going to report its
results back to you hey synchronously
via the CF run loop
excuse me that way you can have as many
open queries as you'd like they're all
going to happen on the same thread and
they're all going to report the results
back asynchronously and incidentally CF
hosts will perform both ipv4 and ipv6
look look up for you incidentally CF
hosts supports a number of other things
too you can do reverse DNS lookup so you
have the address you want to know the
common host names you can use it to
determine whether a given host is
reachable just now if for some reason
you want to use a blocking API you can
use CF host in that fashion although we
always recommend that you use the
asynchronous non-blocking API instead
that's the power of the object and for
our purposes here today we're going to
focus on just basic host lookups so
using CF host is pretty much the same as
using every other CF network object you
start by setting it up you create it set
your callback all of that good stuff
then you wait for the call back to come
in when the callback comes in you filled
it and then finally you clean up every
CF Network object follows this basic
pattern set it up wait for the events
wait for the callbacks to come in and
then dispose of the object so here's the
setup here we're doing a DNS lookup
dub-dub-dub apple com CF hose create
with names wal com then we need to set
up the client call back we UCF host set
client that's just how you specify what
function CF host should call when it
when it receives the information that
you're looking for schedule it with a
run loop here we're scheduling it with
the current run loop in the default mode
that tells CF host where you want to
receive that call back you can schedule
it on another thread if you want and
then having done all that setup you
start CF hosted its work by calling CF
host start in full resolution and here
you pass the host object and then the
type of information you're looking for
looking for the addresses so that's KCF
host addresses and you're done then the
run loop runs and at some point later CF
host has its answer once that happens
it's going to call your call back on the
run move you specified so here we're
fielding the call back first argument is
going to be the host object whose
resolution it has completed second
argument tells you what resolution has
completed we only signed up for one so
we know what that's going to be third
argument is an error if an error has
occurred and then finally is a context
pointer which you could have provided to
pass information or state around inside
your own program to handle it first we
look at the error if an errors occurred
then we're going to need to field it in
some fashion assuming no error has
occurred we can now safely call CF host
get addressing knowing that the host
already has the address available so
that will return immediately providing
the addresses that it just received your
program will probably want to do
something more specific or more
sophisticated than this but just to show
you how we would get the information out
here we get the value of the first the
first item in the array that's going to
be CF data ref the CF data is
essentially a sockaddr so CF data get
byte pointer is going to give you a
pointer to a sock adder CF data get
length will give you the length of that
sockaddr and you can pass it into any
Berkeley or any units call so here I'm
just calling connect to connect a socket
finally we need to clean up any
asynchronous process is going to require
a little extra clean up compared to
simply releasing a reference basically
three phases first unschedule it from
the run loop that makes sure that the
run loop releases any reference it has
on the host and that any any data or
state that's being maintained by the
host object or by the run loop gets
freed up CS host set client null tells
the host that you're done you don't ever
want to receive a call back again and
then finally CF truly
this release releases your reference on
the host object and that's what I wanted
to say about those two basic CF
networking tasks and we're running a
little tight on time so I'm going to fly
through this next section where we're
going to talk about some of the other
URL loading api's on the system the two
other major URL loading api's on a mac
OS 10 system are the foundation URL
loading pieces and URL access manager
the foundation pieces are basically
represented by these three classes and
at URL request response in connection
URL access manager is the carbon API
that became available I think starting
in nine maybe a little before that and
is now deprecated has been for a couple
years now so way back when I was talking
about how CF network is intended as a
power API that explode exposes all of
the pieces that all of the the knobs and
buttons on its given protocols
foundation is the convenience API
foundation provides a nice smooth easy
API to allow you to download a URL just
like a browser would whatever it is that
a browser does in terms of cookies
authentication caching all of that magic
is just done automatically at the
foundation level so there are two
consequences of that first as you'd
expect at the foundation level we have a
support for a lot more features caching
cookie support better authentication
support in the sense that there will be
some automatic credential management the
callback for a little cleaner at the
foundation level than what we saw at the
fence at the CF network level but the
other consequences there are a lot more
constraints because the URL loading
system has made some choices for you you
must use an asynchronous delegation
model you must use the threading model
that foundation dictates and you must
use foundation scheduling policy so for
instance there's no way to say download
these URLs on one fund
thread and these others on another
there's no way to hold a download in
progress there's no way to give a
particular URL download a higher
priority than other ones and then just
as an added note the foundation always
uses the system proxies you cannot do
any custom proxy configuration at the
foundation layer so how do you decide
which one you're going to use well use
nsurl use the foundation api's if you
need the additional features but more
generally use nsurl if your task is
really to download something pretty much
exactly like a browser would so the
classic example for me of this is when
you're downloading HTML mail you're
going to display it just the way you
would expect a browser to display it you
want to download all the images exactly
the same way with the same cookies same
authentication model that a browser
would use on the other hand UCF network
if you don't want to link that high you
don't want the extra convenience and the
extra pieces you don't want to link
foundation or objective c you want
fine-tuned control of the threading
model or more generally you just you're
not doing a basic browser like download
so classic example of that is your
downloading a software update you're
only going to download it once you don't
want it cached you know there are no
cookies involved whatever authentication
needs to be performed you already know
all the details about it you can use
foundation to do that kind of a download
if you want but it's more work to go in
and turn off each and every one of those
things then to just start with CF
network can work and do it the download
from there so then the other API URL
access manager you should never use URL
access manager anymore really it's bad
we've been saying that for at least two
years now and then I was thinking well
okay is there any time I would recommend
that you use URL access manager well if
you still need compatibility with mac OS
9 then you're stuck yeah you're going to
have to use URL access manager
but to give you a little incentive to
kind of my great that old code off of
URL access manager I've listed here the
major shortcomings of URL access that
have been fixed with CF networking with
foundation but will never be fixed in
the URL access manager no authenticating
proxies no HTTPS proxies tied to a
couple obsolete AP is the thread manager
and FS specs and no support never will
be for ipv6 so if I want to migrate from
URL access manager to CF network or
foundation what do I need to do three
basic entry points to URL access manager
URL simple download and URL download and
then there's URL open which is the
asynchronous API for ul access manager
if you're doing a download to memory use
these nsurl methods instead if you're
doing a download the file use nsurl
download it's designed for that purpose
you can use CF network instead of nsurl
it takes a little more work I listed
nsurl is the first choice because that's
the one line replacement using CF
network is maybe 50 something like
depending on how sophisticated to
download you're doing and they're there
is some good sample code available at
developer.apple.com to show you how to
do a CF Network download URL open is
considerably more sophisticated and
provides a number of different flags so
what you're going to do if you're
calling URL open depends on why you're
using URL open if the only reason you're
using URL open is to get some asynchrony
support use nsurlconnection instead if
on the other hand you need high high
level of customization or detailed
threading and buffer control drop the CF
network that will give you the extra
knobs you need to control the download
that's all I want to say about those AP
is we are out of time so I'm just going
to point at point out so there are about
a million references a bunch of
documentation and sample code available
all of this information is available in
the disc image so just get the disc
image and you'll see all of this
information replicated there