typedef struct Client Client;
typedef struct Ctl Ctl;
typedef struct Ibuf Ibuf;
typedef struct Url Url;

/* simple buffered i/o for network connections; shared by http, ftp */
struct Ibuf
{
	int fd;
	Ioproc *io;
	char buf[4096];
	char *rp, *wp;
};

struct Ctl
{
	int	acceptcookies;
	int	sendcookies;
	int	redirectlimit;
	char	*useragent;
};

struct Client
{
	Url	*url;
	Url	*baseurl;
	Ctl ctl;
	Channel *creq;	/* chan(Req*) */
	int num;
	int plumbed;
	char *contenttype;
	char *postbody;
	char *redirect;
	char *authenticate;
	char *ext;
	int npostbody;
	int havepostbody;
	int iobusy;
	int bodyopened;
	Ioproc *io;
	int ref;
	void *aux;
};

/*
 * If ischeme is USunknown, then the given URL is a relative
 * URL which references the "current document" in the context of the base.
 * If this is the case, only the "fragment" and "url" members will have
 * meaning, and the given URL structure may not be used as a base URL itself.
 */
enum
{
	USunknown,
	UShttp,
	UShttps,
	USftp,
	USfile,
	UScurrent,
};

struct Url
{
	int		ischeme;
	char*	url;
	char*	scheme;
	int		(*open)(Client*, Url*);
	int		(*read)(Client*, Req*);
	void		(*close)(Client*);
	char*	schemedata;
	char*	authority;
	char*	user;
	char*	passwd;
	char*	host;
	char*	port;
	char*	path;
	char*	query;
	char*	fragment;
	union {
		struct {
			char *page_spec;
		} http;
		struct {
			char *path_spec;
			char *type;
		} ftp;
	};
};

enum
{
	STACK = 32*1024,  /* was 16*1024; there are big arrays on the stack */
};

extern	Client**	client;
extern	int		cookiedebug;
extern	Srv		fs;
extern	int		fsdebug;
extern	Ctl		globalctl;
extern	int		nclient;
extern	int		urldebug;
extern	int		httpdebug;
extern	char*	status[];

