Sunteți pe pagina 1din 20

Windows Internet Extensions (WINX) Library

Microsoft Windows Internet


Extensions (WINX)
Gopher Protocol API Specification

Richard Firth

18th October 1994

Version 0.3

Gopher Client API 0


Windows Internet Extensions (WINX) Library

Gopher API Specification


The Gopher protocol will be abstracted into a set of user-mode APIs, located
in a DLL and callable from any user-mode Win32 program which supports 32-bit
memory allocation. The Gopher protocol (Gopher in this specification means the
original Gopher protocol as described in RFC 1436 and the Gopher+ protocol which
so far has not been ratified as an RFC) is strictly a client-server protocol which is
used to perform searches at a server for directories, documents and to perform
content-index searches at special servers which support indexing.

The Gopher APIs are intended to achieve the following goals:

1. Decouple the protocol from the Gopher application


To avoid applications having to be intimately familiar with the Gopher
protocol - as they now are - the use of a well-defined API allows applications
to request functionality from the underlying protocol without having to deal
in the specifics of the protocol. This assures upward compatibility for
applications using the API and that replacing the DLLs containing the API
can accomodate existing applications with newer (or feature enhanced)
versions of the protocol.

2. Encapsulate the protocol


Encapsulating the protocol means wrapping it in abstract APIs at the client
side. This has the added benefits that i) the APIs can be closer in specifying
functionality to that required by applications, and ii) elements of the
protocol can be migrated to the server-side as the protocol matures in order
to increase efficiency of the protocol.

3. Provide information in a form easily digested by Windows applications


Since it is expected that clients of the Gopher API will typically be Win32,
graphical applications, the API should accept requests and provide
responses to its clients in a manner which is natural to the Win32
programmer, and in a way that requires the programmer to do as little work
as possible in order to use the returned information.

4. Make it easy to write a Gopher client application


Rather than all application programs that wish to use the Gopher protocol
having to understand the protocol and make the requisite Winsock calls, the
functional abstraction of the Gopher protocol allows applications to work at
a higher level, and therefore to reduce the effort required by application
writers to employ Gopher functionality.

5. Import Gopher functionality into systems using e.g. VBA


The benefits of putting a well-defined Gopher API in a DLL are manifold, not
least of which is that now the functionality is easily and quickly imported
into e.g. VBA (or any other language product that can handle run-time
dynamic linking) applications and therefore allows macros and other
functions in which hitherto it would have been difficult to provide such
functionality to easily use the Gopher protocol.

Initially, the Gopher API will need to handle most of the filtering locally, and
will be required to store data locally. This is because the Gopher protocol is very
simple - typically an application requests a piece of information, the server responds

Gopher Client API 1


Windows Internet Extensions (WINX) Library

with one or more lines of text, and the client must parse the desired information
from the text returned.

In order to achieve Goal 3 above, the protocol DLL will need to store data
returned from the server until requested or discarded by the application. Eventually,
the protocol can be expanded so as to implement the requirements of the API at the
server-side: for example specifying and returning only specific document types or
attributes. Currently, all documents will be returned by the server and parsed locally.
Similiarly, a particular required attribute must be locally filtered from the list of
attributes returned by the server.

As mentioned above, the Gopher protocol actually currently exists as two


versions - Gopher and Gopher+. At any time, both server types may be extant on
the Internet, and must be correctly identified by the Gopher DLL. Gopher+ is a
superset of Gopher, so it should not be difficult to accomodate the basic functions.
However, extended functionality such as attributes that can be requested on a per-
document or per-directory node basis can only be supplied by Gopher+, so it is
important to be able to differentiate the two in such a case.

As the Microsoft Gopher client API DLL and server service mature, it is
expected that situations where applications make requests in such a way that
enhancement of the protocol would improve throughput efficiency, and
consequently reduce required network bandwidth, both the client and server will be
modified to facilitate enhancements of the protocol, or if necessary, a completely
new protocol.

In this specification, I will refer to the original Gopher protocol as TGP for Tiny
Gopher Protocol, GPP for Gopher Plus Protocol and SGP for Super Gopher Protocol
which represents any enhancements made to the protocol by Microsoft over and
above changes to the extant protocols made by any (Internet) standards body. This
is only a notational convention - more than likely any improvements made to the
protocol will be a joint effort, or one in which Microsoft plays a leadership role, but
also where the changes are ratified by the relevant standards committee(s).

All APIs in this specification are synchronous.. We may decide that in the
future it is desirable to create asynchronous versions of the APIs, APIs which return
their results via Windows messages or via callback functions.

Gopher Client API 2


Windows Internet Extensions (WINX) Library

Open Issues
TGP and GPP are purely text-based protocols, except for binary files returned
by the server. It is a convention that new Gopher types, and hence servers, can be
added by simply specifying a single ASCII character denoting a file or hierarchy or
server type.

The APIs could allow these ASCII characters to be specified when searching
for particular types of information, or they could use bitmaps in which particular bit
positions correspond to the Gopher types. After initially favouring the use of the
ASCII characters, mainly because this would lead to new server types being instantly
allowed by the APIs, I decided to go with the bitmaps for the following reasons

1. Win32 APIs - especially the FindFirstFile etc. APIs which we copy - use
bitmaps to indentify attributes of searched criteria.

2. Adding new server or data types would more than likely mean that new
processing would be required - maybe even additional APIs

3. The Gopher protocol, and probably GPP also, is fairly static and seems to
have changed little in the 3 years it has been available.

4. Typically, Gopher clients which did not understand a particular type would
simply discard all information about the item in question. We will do the
same (actually irrespective of how the type is identified to the API).

5. Using bitmaps allows us an extra level of parameter checking, if we should


desire it.

6. Using bits over ASCII characters promotes language independance and


does not encumber either the API writer (me) or the application writer
(potentially you) with having to worry about international or UNICODE
characters (or versions of the API) in order to specify attribute information,
or discover what was returned.

Having made this decision for the above reasons, it is open to change if it felt
that allowing single ASCII characters as type specifiers is preferable to a more
rigidly-defined identifier scheme. For multiple Gopher types, this would require a
string of characters instead of a bitmap in which more than 1 bit is specified.

The APIs which return data expect the user to supply a buffer. Maybe we will
allocate buffers on behalf of the client and return these, since RPC will need to
allocate and copy buffers; it would be inefficient for RPC to allocate buffers and
perform the transfer, only to discover that the user doesn’t have enough buffer.
Even if the protocol is smart enough to support a size query request before
performing the transfer, this would still use up extra bandwidth.

Gopher Client API 3


Windows Internet Extensions (WINX) Library

External Data Structures


The following are the public data structures used by the Gopher API. The
following data types are defined:

GOPHER_FIND_DATA

GOPHER_FIND_DATA

This data type is returned by the GfrFindFirst and GfrFindNext APIs.

typedef struct {
LPTSTR DisplayString;
DWORD GopherType;
DWORD SizeLow;
DWORD SizeHigh;
FILETIME LastModificationTime;
LPTSTR Locator;
} GOPHER_FIND_DATA, *LPGOPHER_FIND_DATA;

DisplayString The text which the application should display. This is the first
part of the Gopher descriptor string,.

GopherType Describes the type of item returned:

GOPHER_TYPE_FILE
The item returned is a document/file of some type. See
below.

GOPHER_TYPE_DIRECTORY
The item returned is a directory/hierarchical item.

GOPHER_TYPE_CSO
The item returned identifies a CSO phone book server
(NOT EXPECTED).

GOPHER_TYPE_MAC_BINHEX
The item is a BinHex’d Macintosh file.

GOPHER_TYPE_DOS_ARCHIVE
The item is some sort of DOS archive file (e.g. .ZIP).

GOPHER_TYPE_UNIX_UUENCODED
The item is a uuencoded UNIX file.

GOPHER_TYPE_INDEX_SERVER
The item is an Index-Search server.

GOPHER_TYPE_TELNET
The item points to a text-based Telnet session (?).

GOPHER_TYPE_BINARY
The item is a binary file.

Gopher Client API 4


Windows Internet Extensions (WINX) Library

GOPHER_TYPE_REDUNDANT
This is a redundant server entry. It may be used if the
server for the immediately preceding entry is
unavailable.

GOPHER_TYPE_TN3270
This item points to a text-based TN3270 session (?).

GOPHER_TYPE_GIF
This item is a GIF format graphics file.

GOPHER_TYPE_IMAGE
This item is some sort of image file, not necessarily a
GIF.

SizeLow Low 32-bits of (estimated) file size, where available.

SizeHigh High 32-bits of (estimated) file size, where evailable.

LastModificationTime The last time the item was modified, where available.

Locator The full Gopher locator/descriptor string returned by the server.


This should be opaque to the calling application.
N.B. This field could live in a corresponding system-side
structure, identified by the GOPHER_FIND_DATA handle (but:
one handle per buffer, which may hold >1 GOPHER_FIND_DATA
structure. TBD)

N.B. Once again (for the reasons as described above in the Open Issues
section). we return the data types as bits in a bitmap, instead of the Gopher
identifier characters. It is simpler for the application to deal with multiple bits in a
bitmap rather than parsing a string of ASCII characters, and the Gopher protocol is
pretty much cast-in-stone (RFC 1436).

The GOPHER_FIND_DATA structure is returned in a user-supplied buffer. The


fixed-length structure is written at the start of the buffer, with the strings starting at
the end of the fixed structure.

Gopher Client API 5


Windows Internet Extensions (WINX) Library

APIs
Below is the initial cut at the Microsoft Internet Extensions Gopher APIs. The
following APIs are defined:

GfrCreateLocator
GfrIsFile
GfrIsDirectory
GfrIsGopherPlus
GfrFindFirst
GfrFindNext
GfrFindClose
GfrOpenFile
GfrCloseHandle
GfrReadFile
GfrGetAttribute
GfrGetLastErrorInfo

Gopher Client API 6


Windows Internet Extensions (WINX) Library

GfrCreateLocator

This API creates a gopher/gopher+ locator string from its component parts. It allows
the application to remain ignorant of the protocol details of gopher requests.

BOOL
GfrCreateLocator(
IN LPTSTR Host,
IN DWORD Port,
IN LPTSTR DisplayString OPTIONAL,
IN LPTSTR Selector OPTIONAL,
IN DWORD GopherType,
IN DWORD BufferLength,
OUT LPTSTR Buffer
);

Parameters

Host String idenfifying the name of the host (or dotted-decimal IP


address).

Port Port on which the Gopher server at Host lives, in host-byte


order. If 0 the default gopher port, 70, will be used.

DisplayString The string to be displayed. May be NULL.

Selector The selector string to be sent to the gopher server in order to


retrieve information. May be NULL.

GopherType Specifying whether Selector refers to a directory or document,


and whether the request is gopher+ or gopher. See
GOPHER_FIND_DATA Attributes.

BufferLength Length of Buffer.

Buffer Pointer to the buffer where the locator string will be returned.

Returns

TRUE if success, else FALSE, in which case more information will be available via
GetLastError() and GfrGetLastErrorInfo().

Comments

This API exists for when the user/client application wants to get information from a
server without first having received the associated locator from the server. Ideally,
we just want to specify the selector string to GfrFindFirst/GfrFindNext/GfrGetFile
APIs, but the locator contains additional information and can be treated as a token
by the app - it just inputs whatever it got from the server. A slight problem arises
when we want to retrieve information from a server without traversing the
information tree - for example if we know a priori where a desired piece of
information lives and how to get it, it should be possible for a gopher client

Gopher Client API 7


Windows Internet Extensions (WINX) Library

application to make that request on behalf of the user, with the minimum amount of
communication with the gopher server(s). In this case, if we didn’t use the locator, it
would be possible to e.g. return a directory as a file, and vice versa.

Gopher Client API 8


Windows Internet Extensions (WINX) Library

GfrIsFile

Returns TRUE if a locator describes a file.

BOOL
GfrIsFile(
IN LPTSTR Locator
);

Parameters

Locator Pointer to locator to check

Returns

TRUE if Locator describes a file, else FALSE.

Comments

Gopher Client API 9


Windows Internet Extensions (WINX) Library

GfrIsDirectory

Returns TRUE if a locator describes a directory.

BOOL
GfrIsDirectory(
IN LPTSTR Locator
);

Parameters

Locator Pointer to locator to check

Returns

TRUE if Locator describes a directory, else FALSE.

Comments

Gopher Client API 10


Windows Internet Extensions (WINX) Library

GfrIsGopherPlus

Returns TRUE if a locator describes an item at a gopher+ server.

BOOL
GfrIsGopherPlus(
IN LPTSTR Locator
);

Parameters

Locator Pointer to locator to check

Returns

TRUE if Locator describes a gopher+ entity, else FALSE

Comments

Gopher Client API 11


Windows Internet Extensions (WINX) Library

GfrFindFirst

Given a host (server) identifier and some search criteria, this API will attempt to
create a session with the server and locate the requested documents, binary files,
index servers or directory trees.

HANDLE
GfrFindFirst(
IN HANDLE InternetHandle,
IN LPTSTR Locator,
IN LPTSTR SearchString,
IN DWORD BufferLength,
OUT LPGOPHER_FIND_DATA Buffer
);

Parameters

InternetHandle Handle returned by OpenInternet().

Locator Name of the item to locate. This is the Locator string returned
from a previous call to this function or GfrFindNext(), a NULL
pointer or NUL string indicating that we are returning the top-
most information from a gopher server, or a locator created by
GfrCreateLocator().

SearchString If this request is to an index server, then the caller may specify
the strings to search for with this parameter. The parameter
should be NULL otherwise.

BufferLength On input, the size of Buffer in bytes.

Buffer Pointer to application-supplied buffer which will be filled with a


GOPHER_FIND_DATA structure.

Returns

If successful a valid search handle, else INVALID_HANDLE_VALUE, in which case more


information will be available via GetLastError() and GfrGetLastErrorInfo().

Comments

This API has been modified and simplified to more closely resemble the
Win32 FindFirstFile() API.

Gopher Client API 12


Windows Internet Extensions (WINX) Library

GfrFindNext

Given a handle indentifying a search session created with GfrFindFirst(), continues


the search for the next items.

BOOL
GfrFindNext(
IN HANDLE GfrFindHandle,
IN DWORD BufferLength,
OUT LPGOPHER_FIND_DATA Buffer
);

Parameters

GfrFindHandle Handle returned from GfrFindFirst().

BufferLength Size of Buffer in bytes.

Buffer Pointer to user-suppled buffer which receives results of search


criteria indentified by GfrFindHandle.

Returns

TRUE if data is returned, else FALSE. API can fail for following reasons:

¨ Invalid Handle
¨ Invalid Parameter(s)
¨ Buffer too small
¨ Server (or equivalent) no longer accessible
¨ Out of memory
¨ No more information

Comments

See GftFindFirst.

Gopher Client API 13


Windows Internet Extensions (WINX) Library

GfrFindClose

Given a handle describing a search session with a Gopher server, cancels all
outstanding requests, returns all allocated resources, and terminates the handle.

BOOL
GfrFindClose(
IN HANDLE GfrFindHandle
);

Parameters

GfrFindHandle Identifies search session created by GfrFindFirst.

Returns

TRUE if the handle is valid and identifies a Gopher search session

Comments

If there are any pending operations described by the handle, they are cancelled, or
marked close-pending. Any open sessions will be terminated, and any data waiting
to be indicated to the caller will be discarded. Any allocated buffers will be freed.

Gopher Client API 14


Windows Internet Extensions (WINX) Library

GfrOpenFile

“Opens” a file at a Gopher server. Since a file cannot be opened or locked at a


server, this call simply associates location information with a handle that can be
used for file-based operations, such as GfrReadFile or GfrGetAttribute.

HANDLE
GfrOpenFile(
IN HANDLE InternetHandle,
IN LPTSTR Locator,
IN LPTSTR View
);

Parameters

InternetHandle Handle returned by OpenInternet().

Locator String identifying the file to ‘open’.

View If several views of the file exist at the server, this parameter
describes which file view to open.

Returns

INVALID_HANDLE_VALUE if the file cannot be “opened”. Use GetLastError or


GfrGetLastErrorInfo to determine the cause of the error.

Comments

Gopher Client API 15


Windows Internet Extensions (WINX) Library

GfrCloseHandle

Closes a file handle opened by GfrOpenFile

BOOL
GfrCloseHandle(
IN HANDLE GfrFileHandle
);

Parameters

GfrFileHandle Handle value created by GfrOpenFile

Returns

TRUE if the handle was successfully closed, else FALSE.

Comments

Gopher Client API 16


Windows Internet Extensions (WINX) Library

GfrReadFile

This API allows an application to read a file from a gopher server as a stream.

BOOL
GfrReadFile(
IN HANDLE GfrFileHandle,
IN OUT LPDWORD BufferLength,
OUT LPBYTE Buffer,
OUT LPDWORD BytesReturned
);

Parameters

GfrFileHandle Valid handle created by GfrOpenFile().

BufferLength Size of Buffer, in bytes.

Buffer Pointer to user-supplied buffer to read data into. Assumed to be


at least as large as the input value of BufferLength..

BytesReturned Number of bytes read into Buffer.

Returns

TRUE if request is satisfied, else FALSE. Use GetLastError or GfrGetLastErrorInfo to


discover more information about the error.

Comments

Gopher Client API 17


Windows Internet Extensions (WINX) Library

GfrGetAttribute

This API allows an application to retrieve GPP (or SGP) specific attribute information
from the server.

BOOL
GfrGetAttribute(
IN HANDLE InternetHandle,
IN LPTSTR Locator,
IN LPTSTR Information,
IN OUT LPDWORD BufferLength,
OUT LPBYTE Buffer,
OUT LPDWORD BytesReturned
);

Parameters

IntenetHandle Handle returned by OpenInternet().

Locator String identifying item at gopher server about which to return


attribute information.

Information Pointer to space-delimited string specifying names of attributes


to return.

BufferLength Size of Buffer. in bytes.

Buffer Pointer to user-supplied buffer into which attribute information


is retrieved.

BytesReturned Number of bytes read into Buffer.

Returns

TRUE if some or all of requested attribute information returned

Comments

I expect that this call will be made following a GfrFindFirst/GfrFindNext call which will
therefore request non-cached information. Create a GfrGetAttributeHandle call if this
kind of call made multiple times for each file.

This is not sufficient. What we need are the following:

1. Get attribute types (list of + attributes, no data)


2. Individual attributes.
3. Combinations of attributes.
4. All attributes.

In all cases, we must be able to get structured buffer of attribute information


returned. The application should not have to spend time parsing buffers or strings of
attribute information.

Gopher Client API 18


Windows Internet Extensions (WINX) Library

GfrGetLastErrorInfo

Returns a string in a user-supplied buffer which is text associated with the last
Gopher library function which failed in the context of the current thread.

BOOL
GfrGetLastErrorInfo(
IN OUT LPDWORD BufferLength,
OUT LPBYTE Buffer
);

Parameters

BufferLength On input the length of the user-supplied buffer. On output, the


length of the returned string, without the terminating NUL (as if
strlen() had been called).

Buffer Pointer to application-supplied buffer into which Gopher


protocol error text will be placed.

Returns

FALSE and BufferLength == 0 if there was no error text. FALSE and BufferLength !=
0 if there is error text, but Buffer is not large enough; BufferLength will contain the
required buffer size. TRUE if error text was available and has been copied to Buffer.

Comments

Gopher Client API 19

S-ar putea să vă placă și