xref: /inferno-os/appl/charon/chutils.m (revision e45fa0eb0763b57d6fb0649c064bc3b95ccdea6c)
1CharonUtils: module
2{
3	PATH: con "/dis/charon/chutils.dis";
4
5	# Modules for everyone to share
6	C: Ctype;
7	E: Events;
8	G: Gui;
9	L: Layout;
10	I: Img;
11	B: Build;
12	LX: Lex;
13	J: Script;
14	CH: Charon;
15	CK: Cookiesrv;
16	DI: Dial;
17
18	# HTTP methods
19	HGet, HPost : con iota;
20	hmeth: array of string;
21
22	# Media types (must track mnames in chutils.b)
23	ApplMsword, ApplOctets, ApplPdf, ApplPostscript, ApplRtf,
24	ApplFramemaker, ApplMsexcel, ApplMspowerpoint, UnknownType,
25
26	Audio32kadpcm, AudioBasic,
27
28	ImageCgm, ImageG3fax, ImageGif, ImageIef, ImageJpeg, ImagePng, ImageTiff,
29	ImageXBit, ImageXBit2, ImageXBitmulti, ImageXInfernoBit, ImageXXBitmap,
30
31	ModelVrml,
32
33	MultiDigest, MultiMixed,
34
35	TextCss, TextEnriched, TextHtml, TextJavascript, TextPlain, TextRichtext,
36	TextSgml, TextTabSeparatedValues, TextXml,
37
38	VideoMpeg, VideoQuicktime : con iota;
39
40	mnames: array of string;
41
42	# Netconn states
43	NCfree, NCidle, NCconnect, NCgethdr, NCgetdata,
44	NCdone, NCerr : con iota;
45
46	ncstatenames: array of string;
47
48	# Netcomm synch protocol values
49	NGstartreq, NGwaitreq, NGstatechg, NGfreebs : con iota;
50
51	# Colors
52	White: con 16rFFFFFF;
53	Black: con 16r000000;
54	Grey: con 16rdddddd;
55	DarkGrey: con 16r9d9d9d;
56	LightGrey: con 16rededed;
57	Blue: con 16r0000CC;
58	Navy: con 16r000080;
59	Red: con 16rFF0000;
60	Green: con 16r00FF00;
61	DarkRed: con 16r9d0000;
62
63	# Header major status values (code/100)
64	HSNone, HSInformation, HSOk, HSRedirect, HSError, HSServererr : con iota;
65	hsnames: array of string;
66
67	# Individual status code values (HTTP, but use for other transports too)
68	HCContinue:		con 100;
69	HCSwitchProto:		con 101;
70	HCOk:			con 200;
71	HCCreated:		con 201;
72	HCAccepted:		con 202;
73	HCOkNonAuthoritative:	con 203;
74	HCNoContent:		con 204;
75	HCResetContent:		con 205;
76	HCPartialContent:	con 206;
77	HCMultipleChoices:	con 300;
78	HCMovedPerm:		con 301;
79	HCMovedTemp:		con 302;
80	HCSeeOther:		con 303;
81	HCNotModified:		con 304;
82	HCUseProxy:		con 305;
83	HCBadRequest:		con 400;
84	HCUnauthorized:		con 401;
85	HCPaymentRequired:	con 402;
86	HCForbidden:		con 403;
87	HCNotFound:		con 404;
88	HCMethodNotAllowed:	con 405;
89	HCNotAcceptable:	con 406;
90	HCProxyAuthRequired:	con 407;
91	HCRequestTimeout:	con 408;
92	HCConflict:		con 409;
93	HCGone:			con 410;
94	HCLengthRequired:	con 411;
95	HCPreconditionFailed:	con 412;
96	HCRequestTooLarge:	con 413;
97	HCRequestURITooLarge:	con 414;
98	HCUnsupportedMedia:	con 415;
99	HCRangeInvalid:		con 416;
100	HCExpectFailed:		con 419;
101	HCServerError:		con 500;
102	HCNotImplemented:	con 501;
103	HCBadGateway:		con 502;
104	HCServiceUnavailable:	con 503;
105	HCGatewayTimeout:	con 504;
106	HCVersionUnsupported:	con 505;
107	HCRedirectionFailed:	con 506;
108
109	# Max number of redirections tolerated
110	Maxredir : con 10;
111
112	# Image Level config options
113	ImgNone, ImgNoAnim, ImgProgressive, ImgFull: con iota;
114
115 	# SSL connection version
116 	NOSSL, SSLV2, SSLV3, SSLV23: con iota;
117
118	# User Configuration Information (Options)
119	# Debug option letters:
120	# 'd' -> Basic operation info (navigation, etc.)
121	# 'e' -> Events (timing of progress through get/layout/image conversion)
122	# 'h' -> Build layout items from lex tokens
123	# 'i' -> Image conversion
124	# 'l' -> Layout
125	# 'n' -> transport (Network access)
126	# 'o' -> always use old http (http/1.0)
127	# 'p' -> synch Protocol between ByteSource/Netconn
128	# 'r' -> Resource usage
129	# 's' -> Scripts
130	# 't' -> Table layout
131	# 'u' -> use Uninstalled dis modules
132	# 'w' -> Warn about recoverable problems in retrieved pages
133	# 'x -> lex Html tokens
134	Config: adt
135	{
136		userdir:	string;		# where to find bookmarks, cache, etc.
137		srcdir:		string;		# where to find charon src (for debugging)
138		starturl:	string;# never nil (could be last of command args)
139		change_homeurl:	int;
140		homeurl:	string;# never nil
141		helpurl:	string;
142 		usessl:		int; # use ssl version 2, 3 or both
143 		devssl:		int; # use devssl
144		custbkurl:	string; # where are customized bookmarks-never nil
145		dualbkurl:	string; # where is the dual bookmark page-never nil
146		httpproxy:	ref Url->Parsedurl;# nil, if no proxy
147		noproxydoms:	list of string; # domains that don't require proxy
148		buttons:	string;		# customized buttons
149		framework: string;		# customized gui framework
150		defaultwidth:	int;		# of entire browser
151		defaultheight:	int;		# of entire browser
152		x:			int;		# initial x position for browser
153		y:			int;		# initial y position for browser
154		nocache:	int;		# true if shouldn't retrieve from or store to
155		maxstale:	int;		# allow cache hit even if exceed expiration by maxstale
156		imagelvl:	int;		# ImgNone, etc.
157		imagecachenum: int;	# imcache.nlimit
158		imagecachemem: int;	# imcache.memlimit
159		docookies:	int;		# allow cookie storage/sending?
160		doscripts:		int;		# allow scripts to execute?
161		httpminor:	int;		# use HTTP 1.httpminor
162		agentname:	string;	# what to send in HTTP header
163		nthreads:		int;		# number of simultaneous gets allowed
164		offersave:	int;		# offer to save a file of a type that can't be handled
165		charset: string;			# default character set
166		plumbport: string;		# from/to plumbing port name (default = "web")
167		wintitle: string;
168		dbgfile:		string;	# file to write debug messages to
169		dbg:		array of byte;	# ascii letters for different debugging kinds
170	};
171
172	# Information for fulfilling HTTP request
173	ReqInfo : adt
174	{
175		url:	ref Url->Parsedurl;	# should be absolute
176		method:	int;			# HGet or HPost
177		body:	array of byte;		# used for HPost
178		auth:	string;			# optional auth info
179		target:	string;			# target frame name
180	};
181
182	MaskedImage: adt {
183		im:		ref Draw->Image;		# the image
184		mask:	ref Draw->Image;		# if non-nil, a mask for the image
185		delay:	int;			# if animated, delay in millisec before next frame
186		more:	int;			# true if more frames follow
187		bgcolor:	int;			# if not -1, restore to this (RGB) color before next frame
188		origin:	Draw->Point;		# origin of im relative to first frame of an animation
189
190		free: fn(mim: self ref MaskedImage);
191	};
192
193	# Charon Image info.
194	# If this is an animated image then len mims > 1
195	CImage: adt
196	{
197		src:	ref Url->Parsedurl;	# source of image
198		lowsrc:	ref Url->Parsedurl;	# for low-resolution devices
199		actual: ref Url->Parsedurl;	# what came back as actual source of image
200		imhash:	int;			# hash of src, for fast comparison
201		width:	int;
202		height:	int;
203		next:	cyclic ref CImage;	# next (newer) image in cache
204		mims: array of ref MaskedImage;
205		complete: int;			# JavaScript Image.complete
206
207		new: fn(src: ref Url->Parsedurl, lowsrc: ref Url->Parsedurl, width, height: int) : ref CImage;
208		match: fn(a: self ref CImage, b: ref CImage) : int;
209		bytes: fn(ci: self ref CImage) : int;
210	};
211
212	# In-memory cache of CImages
213	ImageCache: adt
214	{
215		imhd:	ref CImage;	# head (LRU) of cache chain (linked through CImage.next)
216		imtl:		ref CImage;	# tail MRU) of cache chain
217		n:	int;			# size of chain
218		memused: int;		# current total of image mem used by cached images
219		memlimit: int;		# keep memused less than this
220		nlimit: int;			# keep n less than this
221
222		init: fn(ic: self ref ImageCache);
223		resetlimits: fn(ic: self ref ImageCache);
224		look: fn(ic: self ref ImageCache, ci: ref CImage) : ref CImage;
225		add: fn(ic: self ref ImageCache, ci: ref CImage);
226		deletelru: fn(ic: self ref ImageCache);
227		clear: fn(ic: self ref ImageCache);
228		need: fn(ic: self ref ImageCache, nbytes: int) : int;
229	};
230
231	# An connection to some host
232	Netconn: adt
233	{
234		id:		 int;			# for debugging
235		host:	string;			# host name
236		port:	int;			# port number
237		scheme: string;		# Url scheme ("http", "file", etc.)
238		conn:	ref Dial->Connection;	# fds, etc.
239 		sslx:	ref SSL3->Context;	# ssl connection
240 		vers:	int;			# ssl version
241		state:	int;			# NCfree, etc.
242		queue:	cyclic array of ref ByteSource;
243						# following are indexes into queue
244		qlen:		int;		# queue[0:qlen] is queue of requests
245		gocur:	int;		# go thread currently processing
246		ngcur:	int;		# ng threads currently processing
247		reqsent:	int;		# next to send request for
248		pipeline:	int;		# are requests being pipelined?
249		connected:	int;	# are we connected to host?
250		tstate:	int;		# for use by transport
251		tbuf: 	array of byte;	# for use by transport
252		idlestart:	int;		# timestamp when went Idle
253
254		new: fn(id: int) : ref Netconn;
255		makefree: fn(nc: self ref Netconn);
256	};
257
258	# Info from an HTTP response header
259	Header: adt
260	{
261		code:	int;			# HC... (detailed response code)
262		actual:	ref Url->Parsedurl;	# actual request url (may be result of redir)
263		base:	ref Url->Parsedurl;	# Content-Base or request url
264		location:	ref Url->Parsedurl;	# Content-Location
265		length:	int;			# -1 if unknown
266		mtype:	int;			# TextHtml, etc.
267		chset:	string;		# charset encoding
268		msg:	string;			# possible message explaining status
269		refresh:string;			# used for server push
270		chal:	string;			# used if code is HSneedauth
271		warn:	string;			# should show this to user
272		lastModified:	string;		# last-modified field
273
274		new: fn() : ref Header;
275		setmediatype: fn(h: self ref Header, name: string, first: array of byte);
276		print: fn(h: self ref Header);
277	};
278
279	# A source of raw bytes (with HTTP info)
280	ByteSource: adt
281	{
282		id: int;				# for debugging
283		req:	ref ReqInfo;
284		hdr:	ref Header;		# filled in from headers
285		data:	array of byte;		# all the data, maybe partially filled
286		edata: int;				# data[0:edata] is valid
287		err: string;			# there was an error
288		net:	cyclic ref Netconn;	# servicing fd, etc.
289		refgo: int;				# go proc is still using
290		refnc: int;				# netconn proc is still using
291
292		# producer sets eof upon finalising data & edata
293		eof: int;
294
295		# consumer changes only these fields:
296		lim: int;				# consumer has seen data[0:lim]
297		seenhdr: int;			# consumer has seen hdr
298
299		free: fn(bs: self ref ByteSource);
300		stringsource: fn(s: string) : ref ByteSource;
301	};
302
303	# Snapshot of current system resources
304	ResourceState: adt
305	{
306		ms: int;		# a millisecond time stamp
307		main: int;		# main memory
308		mainlim: int;		# max main memory
309		heap: int;		# heap memory
310		heaplim: int;		# max heap memory
311		image: int;		# used image memory
312		imagelim: int;		# max image memory
313
314		cur: fn() : ResourceState;
315		since: fn(rnew: self ResourceState, rold: ResourceState) : ResourceState;
316		print: fn(r: self ResourceState, msg: string);
317	};
318
319
320	Nameval: adt {
321		key: string;
322		val: string;
323
324		namevals: fn(s: string, sep: int) : list of Nameval;
325		find: fn(l: list of Nameval, key: string) : (int, string);
326	};
327
328
329	# Globals
330	config: Config;
331	startres: ResourceState;
332	imcache: ref ImageCache;
333	progresschan: chan of (int, int, int, string);
334	gen: int;	# go generation number
335	ckclient: ref Cookiesrv->Client;
336
337	init: fn(ch: Charon, me: CharonUtils, argl: list of string, evch: chan of ref E->Event, cksrv: Cookiesrv, ckclient: ref Cookiesrv->Client) : string;
338
339	# Dispatcher functions
340	stringreq: fn(s : string) : ref ByteSource;
341	startreq: fn(req: ref ReqInfo) : ref ByteSource;
342	waitreq: fn(bsl : list of ref ByteSource) : ref ByteSource;
343	freebs: fn(bs: ref ByteSource);
344	abortgo: fn(gopgrp: int);
345	netget: fn();
346
347	# Miscellaneous utility functions
348	kill: fn(pid: int, dogroup: int);
349	getline: fn(fd: ref Sys->FD, buf: array of byte, bstart, bend: int) :
350		(array of byte, int, int, int);
351	saveconfig: fn() : int;
352	strlookup: fn(a: array of string, s: string) : int;
353	realloc: fn(a: array of byte, incr: int) : array of byte;
354	hcphrase: fn(code: int) : string;
355	hdraction: fn(bs: ref ByteSource, ismain: int, nredirs: int) : (int, string, string, ref Url->Parsedurl);
356	makestrinttab: fn(a: array of string) : array of StringIntTab->StringInt;
357	urlequal: fn(a, b: ref Url->Parsedurl) : int;
358	makeabsurl: fn(s: string) : ref Url->Parsedurl;
359	loadpath: fn(s: string) : string;
360	event: fn(s: string, data: int);
361	color: fn(s: string, dflt: int) : int;
362	max: fn(a, b : int) : int;
363	min: fn(a, b : int) : int;
364	assert: fn(i: int);
365	stripscript: fn(s: string) : string;	# strip HTML comments from Script
366	getconv: fn(chset : string) : Btos;
367	setcookie: fn(host, path, cookie: string);
368	getcookies: fn(host, path: string, secure: int): string;
369	schemeok: fn(scheme: string): int;	# is URL scheme supported?
370	X: fn(s, note : string) : string;
371};
372