src/inc/net.h 1.36

1.36 2009/11/13 06:35:45 angie
Added netUrlOpenSockets/netGetOpenFtpSockets, which can pass the FTP control socket back to the caller instead of forking for the sake of closing the control socket immediately. This prevents the accumulation of zombie (defunct) child processes forked from the udcFuse daemon, and saves a bit of overhead. netUrl byterange can now be open-ended (only the start offset is specified), which also supports persistent connections in udcFuse. Also did some refactoring (readability & error messages).
Index: src/inc/net.h
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/inc/net.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -b -B -U 1000000 -r1.35 -r1.36
--- src/inc/net.h	10 Nov 2009 23:23:58 -0000	1.35
+++ src/inc/net.h	13 Nov 2009 06:35:45 -0000	1.36
@@ -1,217 +1,223 @@
 /* Net.h some stuff to wrap around net communications. 
  *
  * This file is copyright 2002 Jim Kent, but license is hereby
  * granted for all use - public, private or commercial. */
 
 
 #ifndef NET_H
 #define NET_H
 
 #ifndef LINEFILE_H
 #include "linefile.h"
 #endif /* LINEFILE_H */
 
 #ifndef DYSTRING_H
 #include "dystring.h"
 #endif /* DYSTRING_H */
 
 int netConnect(char *hostName, int port);
 /* Start connection with a server having resolved port. */
 
 int netMustConnect(char *hostName, int port);
 /* Start connection with server or die. */
 
 int netMustConnectTo(char *hostName, char *portName);
 /* Start connection with a server and a port that needs to be converted to integer */
 
 int netAcceptingSocket(int port, int queueSize);
 /* Create a socket for to accept connections. */
 
 int netAcceptingSocketFrom(int port, int queueSize, char *host);
 /* Create a socket that can accept connections from a 
  * IP address on the current machine if the current machine
  * has multiple IP addresses. */
 
 int netAccept(int sd);
 /* Accept incoming connection from socket descriptor. */
 
 int netAcceptFrom(int sd, unsigned char subnet[4]);
 /* Wait for incoming connection from socket descriptor
  * from IP address in subnet.  Subnet is something
  * returned from netParseDottedQuad.  */
 
 FILE *netFileFromSocket(int socket);
 /* Wrap a FILE around socket.  This should be fclose'd
  * and separately the socket close'd. */
 
 void netBlockBrokenPipes();
 /* Make it so a broken pipe doesn't kill us. */
 
 size_t netReadAll(int sd, void *vBuf, size_t size);
 /* Read given number of bytes into buffer.
  * Don't give up on first read! */
 
 int netMustReadAll(int sd, void *vBuf, size_t size);
 /* Read given number of bytes into buffer or die.
  * Don't give up if first read is short! */
 
 boolean netSendString(int sd, char *s);
 /* Send a string down a socket - length byte first. */
 
 boolean netSendLongString(int sd, char *s);
 /* Send a string down a socket - up to 64k characters. */
 
 boolean netSendHugeString(int sd, char *s);
 /* Send a string down a socket - up to 4G characters. */
 
 char *netRecieveString(int sd, char buf[256]);
 /* Read string into buf and return it.  If buf is NULL
  * an internal buffer will be used. Abort if any problem. */
 
 char *netRecieveLongString(int sd);
 /* Read string up to 64k and return it.  freeMem
  * the result when done. Abort if any problem*/
 
 char *netRecieveHugeString(int sd);
 /* Read string up to 4G and return it.  freeMem
  * the result when done. Abort if any problem*/
 
 char *netGetString(int sd, char buf[256]);
 /* Read string into buf and return it.  If buf is NULL
  * an internal buffer will be used. Print warning message
  * and return NULL if any problem. */
 
 char *netGetLongString(int sd);
 /* Read string up to 64k and return it.  freeMem
  * the result when done.  Print warning message and
  * return NULL if any problem. */
 
 char *netGetHugeString(int sd);
 /* Read string up to 4 gig and return it.  freeMem
  * the result when done.  Print warning message and
  * return NULL if any problem. */
 
 void netCatchPipes();
 /* Set up to catch broken pipe signals. */
 
 boolean netPipeIsBroken();
 /* Return TRUE if pipe is broken */
 
 void  netClearPipeFlag();
 /* Clear broken pipe flag. */
 
 void netParseSubnet(char *in, unsigned char out[4]);
 /* Parse subnet, which is a prefix of a normal dotted quad form.
  * Out will contain 255's for the don't care bits. */
 
 struct netParsedUrl
 /* A parsed URL. */
    {
    char protocol[16];	/* Protocol - http or ftp, etc. */
    char user[128];	/* User name (optional)  */
    char password[128];	/* Password  (optional)  */
    char host[128];	/* Name of host computer - www.yahoo.com, etc. */
    char port[16];       /* Port, usually 80 or 8080. */
    char file[1024];	/* Remote file name/query string, starts with '/' */
    ssize_t byteRangeStart; /* Start of byte range, use -1 for none */
    ssize_t byteRangeEnd;   /* End of byte range use -1 for none */
    };
 
 void netParseUrl(char *url, struct netParsedUrl *parsed);
 /* Parse a URL into components.   A full URL is made up as so:
  *   http://user:password@hostName:port/file;byterange=0-499
  * User and password may be cgi-encoded.
  * This is set up so that the http:// and the port are optional. 
  */
 
 int netUrlOpen(char *url);
-/* Return unix low-level file handle for url. 
+/* Return socket descriptor (low-level file handle) for read()ing url data. 
  * Just close(result) when done. */
 
+int netUrlOpenSockets(char *url, int *retCtrlSocket);
+/* Return socket descriptor (low-level file handle) for read()ing url data. 
+ * If retCtrlSocket is non-NULL and url is FTP, set *retCtrlSocket
+ * to the FTP control socket which is left open for a persistent connection.
+ * close(result) (and close(*retCtrlSocket) if applicable) when done. */
+
 struct hash;
 
 int netUrlHead(char *url, struct hash *hash);
 /* Go get head and return status.  Return negative number if
  * can't get head. If hash is non-null, fill it with header
  * lines with upper cased keywords for case-insensitive lookup, 
  * including hopefully CONTENT-TYPE: . */
 
 struct lineFile *netLineFileOpen(char *url);
 /* Return a lineFile attached to url.  This one
  * will skip any headers.   Free this with
  * lineFileClose(). */
 
 struct lineFile *netLineFileMayOpen(char *url);
 /* Same as netLineFileOpen, but warns and returns
  * null rather than aborting on problems. */
 
 struct dyString *netSlurpFile(int sd);
 /* Slurp file into dynamic string and return. */
 
 struct dyString *netSlurpUrl(char *url);
 /* Go grab all of URL and return it as dynamic string. */
 
 struct lineFile *netHttpLineFileMayOpen(char *url, struct netParsedUrl **npu);
 /* Parse URL and open an HTTP socket for it but don't send a request yet. */
 
 void netHttpGet(struct lineFile *lf, struct netParsedUrl *npu,
 		boolean keepAlive);
 /* Send a GET request, possibly with Keep-Alive. */
 
 int netOpenHttpExt(char *url, char *method, char *optionalHeader);
 /* Return a file handle that will read the url.  optionalHeader
  * may by NULL or may contain cookies and other info. */
 
 int netHttpConnect(char *url, char *method, char *protocol, char *agent, char *optionalHeader);
 /* Parse URL, connect to associated server on port,
  * and send most of the request to the server.  If
  * specified in the url send user name and password
  * too.  Typically the "method" will be "GET" or "POST"
  * and the agent will be the name of your program or
  * library. optionalHeader may be NULL or contain
  * additional header lines such as cookie info. */
 
 int netHttpGetMultiple(char *url, struct slName *queries, void *userData,
 		       void (*responseCB)(void *userData, char *req,
 					  char *hdr, struct dyString *body));
 /* Given an URL which is the base of all requests to be made, and a 
  * linked list of queries to be appended to that base and sent in as 
  * requests, send the requests as a batch and read the HTTP response 
  * headers and bodies.  If not all the requests get responses (i.e. if 
  * the server is ignoring Keep-Alive or is imposing a limit), try again 
  * until we can't connect or until all requests have been served. 
  * For each HTTP response, do a callback. */
 
 
 boolean netSkipHttpHeaderLinesWithRedirect(int sd, char *url, char **redirectedUrl);
 /* Skip http header lines. Return FALSE if there's a problem.
  * The input is a standard sd or fd descriptor.
  * This is meant to be able work even with a re-passable stream handle,
  * e.g. can pass it to the pipes routines, which means we can't
  * attach a linefile since filling its buffer reads in more than just the http header.
  * Handles 300, 301, 302, 303, 307 http redirects by setting *redirectedUrl to
  * the new location. */
 
 boolean netSkipHttpHeaderLinesHandlingRedirect(int sd, char *url, int *redirectedSd, char **redirectedUrl);
 /* Skip http headers lines, returning FALSE if there is a problem.  Generally called as
  *    netSkipHttpHeaderLine(sd, url, &sd, &url);
  * where sd is a socket (file) opened with netUrlOpen(url), and url is in dynamic memory.
  * If the http header indicates that the file has moved, then it will update the *redirectedSd and
  * *redirectedUrl with the new socket and URL, first closing sd.
  * If for some reason you want to detect whether the forwarding has occurred you could
  * call this as:
  *    char *newUrl = NULL;
  *    int newSd = 0;
  *    netSkipHttpHeaderLine(sd, url, &newSd, &newUrl);
  *    if (newUrl != NULL)
  *          // Update sd with newSd, free url if appropriate and replace it with newUrl, etc.
  *          //  free newUrl when finished.
  * This routine handles up to 5 steps of redirection.
  * The logic to this routine is also complicated a little to make it work in a pipe, which means we
  * can't attach a lineFile since filling the lineFile buffer reads in more than just the http header. */
 
 boolean netGetFtpInfo(char *url, long long *retSize, time_t *retTime);
 /* Return date and size of ftp url file */
 
 #endif /* NET_H */