The second part of the assignment, however, will require the following
IDL specification:
The
// IDL schema definition for Web server interface.
module Web_Server
{
typedef sequence<octet> Chunk_Type;
interface Callback
{
// This operation is called back by the server to pass
// the next <chunk> of the file starting at <offset>.
// If there are no more chunks, <last_chunk> is true.
void next_chunk (in Chunk_Type chunk,
in unsigned long offset,
in boolean last_chunk);
};
exception Error_Result {
// Status of the <register_callback> operation. These
// values should map onto the normal HTTP
// status values, e.g., 200 means success, 404
// means "file not found," etc.
short status;
};
struct Metadata_Type
{
// Modification date.
string modification_date;
// Type of content.
string content_type;
};
interface Iterator_Factory
{
// This registration method passes a <Callback> that
// the Web server uses to ``push'' data associated with
// <pathname> one ``chunk'' at a time. The <metadata>
// reports information about the <pathname>.
Metadata_Type register_callback (in string pathname,
in Callback client_callback)
raises (Error_Result);
};
};
register_callback allows a client to pass a
Callback that the Web server will use to ``push'' to the
client the contents of the file associated with pathname.
The register_callback operation returns a
struct containing metadata that describes certain
information, such as the MIME type and return status, about the
pathname. If an error occurs, the
Error_Result exception will be raised, its
status_ field will contain a non-success value.
As the Web server reads the file, it will call the
next_chunk operation to pass the file one chunk at a time
to the client. I recommend passing the file in BUFSIZ chunks,
i.e., the first call to next_chunk will contain
offset 0 of the file, the next with offset 0 + BUFSIZ, etc.
Naturally, the client will need to check the length of the sequence it
gets back to know how much it got. It must also use the
offset parameter to know where to write the chunk in the
file. This parameter is necessary since there's no guarantee that the
next_chunk callback operations will be called in a
particular order on the client.
You will use a CORBA IDL compiler to translate this specification into client-side stubs and server-side skeletons. The client application (which you must write) will use the stubs as a proxy to request the server to download the content. In addition, you must also write the server, which implements the operation that downloads content to the client.
-GI option
of TAO's IDL compiler to generate the skeletons for you.
To implement the register_callback and next_chunk
operations you'll need to use OS filesystem APIs, such as
open(2), close(2), and read(2).
I recommend that you check the UNIX manual pages for more details on
using these functions.
In addition, you'll need to implement a main function
that defines an instance of Web_Server_i, obtains and
activates the RootPOA and then calls the ORB's run method
to start its event loop.
To make your solution more scalable, the server should
bind its IOR to an instance of the CORBA Naming Service
that you have running. Too keep from interfering with each other's
Naming Services, I recommend you add an entry to your
.cshrc file that assigns your login uid
number to an environment variable called NameServicePort.
Here's how you can do this with csh or tcsh:
setenv NameServicePort 19850
or the following in your .profile file for Bourne shell compatible
shells, e.g., sh, ksh,
Bash:
NameServicePort 19850
export NameServicePort
Note that I got my uid via the id UNIX
command. Remember that valid unprivileged ports on UNIX are greater
than or equal to 1024 (@@ or is 1025) and less than or equal to
65535.
resolve_initial_references to obtain a reference to your
Naming Service (which must be running). This object reference will
then be downcast via _narrow() to an object reference for
a CosNaming::NamingContext interface, which you can then
use to resolve the object reference that the Web server
bound earlier. After you narrow this to the Web_Server
interface, you can do the following actions, depending on whether
you're implementing the AMI or Callback client:
sendc_next_chunk method on the iterator, passing in the
offset and the object reference to the client's reply handler. Note
that you can only have one pending call at a time per-server
because otherwise we'd need to add some type of offset
parameter to the next_chunk callback.
register_callback operation via the naming context's
object reference to pass the object reference to your client's
Callback, which the server uses to download the file.
next_chunk returns a chunk of the file, write
the contents into a temporary file created in your WWW cache (e.g.,
/tmp/yourloginname) on the local host
[creat,read/write].
/tmp/ so that it doesn't fill up!
Back to ECE 255 home page.
Last modified 10:35:50 CST 08 January 2003