Documente Academic
Documente Profesional
Documente Cultură
Richard Firth
Version 0.3
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
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 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.
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).
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_FIND_DATA
GOPHER_FIND_DATA
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,.
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_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.
LastModificationTime The last time the item was modified, where available.
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).
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
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
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
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.
GfrIsFile
BOOL
GfrIsFile(
IN LPTSTR Locator
);
Parameters
Returns
Comments
GfrIsDirectory
BOOL
GfrIsDirectory(
IN LPTSTR Locator
);
Parameters
Returns
Comments
GfrIsGopherPlus
BOOL
GfrIsGopherPlus(
IN LPTSTR Locator
);
Parameters
Returns
Comments
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
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.
Returns
Comments
This API has been modified and simplified to more closely resemble the
Win32 FindFirstFile() API.
GfrFindNext
BOOL
GfrFindNext(
IN HANDLE GfrFindHandle,
IN DWORD BufferLength,
OUT LPGOPHER_FIND_DATA Buffer
);
Parameters
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.
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
Returns
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.
GfrOpenFile
HANDLE
GfrOpenFile(
IN HANDLE InternetHandle,
IN LPTSTR Locator,
IN LPTSTR View
);
Parameters
View If several views of the file exist at the server, this parameter
describes which file view to open.
Returns
Comments
GfrCloseHandle
BOOL
GfrCloseHandle(
IN HANDLE GfrFileHandle
);
Parameters
Returns
Comments
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
Returns
Comments
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
Returns
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.
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
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