[0001]
[0002]
[0003]
[0004]
[0005]
[0006]
[0007]
[0008]
[0009]
[0010]
[0011]
[0012]
[0013]
[0014]
[0015]
[0016]
[0017]
[0018]
[0019]
[0020]
[0021]
[0022]
[0023]
[0024]
[0025]
[0026]
[0027]
[0028]
[0029]
[0030]
[0031]
[0032]
[0033]
[0034]
[0035]
[0036]
[0037]
[0038]
[0039]
[0040]
[0041]
[0042]
[0043]
[0044]
[0045]
[0046]
[0047]
[0048]
[0049]
[0050]
[0051]
[0052]
[0053]
[0054]
[0055]
[0056]
[0057]
[0058]
[0059]
[0060]
[0061]
[0062]
[0063]
[0064]
[0065]
[0066]
[0067]
[0068]
[0069]
[0070]
[0071]
[0072]
[0073]
[0074]
[0075]
[0076]
[0077]
[0078]
[0079]
[0080]
[0081]
[0082]
[0083]
[0084]
[0085]
[0086]
[0087]
[0088]
[0089]
[0090]
[0091]
[0092]
[0093]
[0094]
[0095]
[0096]
[0097]
[0098]
[0099]
[0100]
[0101]
[0102]
[0103]
[0104]
[0105]
[0106]
[0107]
[0108]
[0109]
[0110]
[0111]
[0112]
[0113]
[0114]
[0115]
[0116]
[0117]
[0118]
[0119]
[0120]
[0121]
[0122]
[0123]
[0124]
[0125]
[0126]
[0127]
[0128]
[0129]
[0130]
[0131]
[0132]
[0133]
[0134]
[0135]
[0136]
[0137]
[0138]
[0139]
[0140]
[0141]
[0142]
[0143]
[0144]
[0145]
[0146]
[0147]
[0148]
[0149]
[0150]
[0151]
[0152]
[0153]
[0154]
[0155]
[0156]
[0157]
[0158]
[0159]
[0160]
[0161]
[0162]
[0163]
[0164]
[0165]
[0166]
[0167]
[0168]
[0169]
[0170]
[0171]
[0172]
[0173]
[0174]
[0175]
[0176]
[0177]
[0178]
[0179]
[0180]
[0181]
[0182]
[0183]
[0184]
[0185]
[0186]
[0187]
[0188]
[0189]
[0190]
[0191]
[0192]
[0193]
[0194]
[0195]
[0196]
[0197]
[0198]
[0199]
[0200]
[0201]
[0202]
[0203]
[0204]
[0205]
[0206]
[0207]
[0208]
[0209]
[0210]
[0211]
[0212]
[0213]
[0214]
[0215]
[0216]
[0217]
[0218]
[0219]
[0220]
[0221]
[0222]
[0223]
[0224]
[0225]
[0226]
[0227]
[0228]
[0229]
[0230]
[0231]
[0232]
[0233]
[0234]
[0235]
[0236]
[0237]
[0238]
[0239]
[0240]
[0241]
[0242]
[0243]
[0244]
[0245]
[0246]
[0247]
[0248]
[0249]
[0250]
[0251]
[0252]
[0253]
[0254]
[0255]
[0256]
[0257]
[0258]
[0259]
[0260]
[0261]
[0262]
[0263]
[0264]
[0265]
[0266]
[0267]
[0268]
[0269]
[0270]
[0271]
[0272]
[0273]
[0274]
[0275]
[0276]
[0277]
[0278]
[0279]
[0280]
[0281]
[0282]
[0283]
[0284]
[0285]
[0286]
[0287]
[0288]
[0289]
[0290]
[0291]
[0292]
[0293]
[0294]
[0295]
[0296]
[0297]
[0298]
[0299]
[0300]
[0301]
[0302]
[0303]
[0304]
[0305]
[0306]
[0307]
[0308]
[0309]
[0310]
[0311]
[0312]
[0313]
[0314]
[0315]
[0316]
[0317]
[0318]
[0319]
[0320]
[0321]
[0322]
[0323]
[0324]
[0325]
[0326]
[0327]
[0328]
[0329]
[0330]
[0331]
[0332]
[0333]
[0334]
[0335]
[0336]
[0337]
[0338]
[0339]
[0340]
[0341]
[0342]
[0343]
[0344]
[0345]
[0346]
[0347]
[0348]
[0349]
[0350]
[0351]
[0352]
[0353]
[0354]
[0355]
[0356]
[0357]
[0358]
[0359]
[0360]
[0361]
[0362]
[0363]
[0364]
[0365]
[0366]
[0367]
[0368]
[0369]
[0370]
[0371]
[0372]
[0373]
[0374]
[0375]
[0376]
[0377]
[0378]
[0379]
[0380]
[0381]
[0382]
[0383]
[0384]
[0385]
[0386]
[0387]
[0388]
[0389]
[0390]
[0391]
[0392]
[0393]
[0394]
[0395]
[0396]
[0397]
[0398]
[0399]
[0400]
[0401]
[0402]
[0403]
[0404]
[0405]
[0406]
[0407]
[0408]
[0409]
[0410]
[0411]
[0412]
[0413]
[0414]
[0415]
[0416]
[0417]
[0418]
[0419]
[0420]
[0421]
[0422]
[0423]
[0424]
[0425]
[0426]
[0427]
[0428]
[0429]
[0430]
[0431]
[0432]
[0433]
[0434]
[0435]
[0436]
[0437]
[0438]
[0439]
[0440]
[0441]
[0442]
[0443]
[0444]
[0445]
[0446]
[0447]
[0448]
[0449]
[0450]
[0451]
[0452]
[0453]
[0454]
[0455]
[0456]
[0457]
[0458]
[0459]
[0460]
[0461]
[0462]
[0463]
[0464]
[0465]
[0466]
[0467]
[0468]
[0469]
[0470]
[0471]
[0472]
[0473]
[0474]
[0475]
[0476]
[0477]
[0478]
[0479]
[0480]
[0481]
[0482]
[0483]
[0484]
[0485]
[0486]
[0487]
[0488]
[0489]
[0490]
[0491]
[0492]
[0493]
[0494]
[0495]
[0496]
[0497]
[0498]
[0499]
[0500]
[0501]
[0502]
[0503]
[0504]
[0505]
[0506]
[0507]
[0508]
[0509]
[0510]
[0511]
[0512]
[0513]
[0514]
[0515]
[0516]
[0517]
[0518]
[0519]
[0520]
[0521]
[0522]
[0523]
[0524]
[0525]
[0526]
[0527]
[0528]
[0529]
[0530]
[0531]
[0532]
[0533]
[0534]
[0535]
[0536]
[0537]
[0538]
[0539]
[0540]
[0541]
[0542]
[0543]
[0544]
[0545]
[0546]
[0547]
[0548]
[0549]
[0550]
[0551]
[0552]
[0553]
[0554]
[0555]
[0556]
[0557]
[0558]
[0559]
[0560]
[0561]
[0562]
[0563]
[0564]
[0565]
[0566]
[0567]
[0568]
[0569]
[0570]
[0571]
[0572]
[0573]
[0574]
[0575]
[0576]
[0577]
[0578]
[0579]
[0580]
[0581]
[0582]
[0583]
[0584]
[0585]
[0586]
[0587]
[0588]
[0589]
[0590]
[0591]
[0592]
[0593]
[0594]
[0595]
[0596]
[0597]
[0598]
[0599]
[0600]
[0601]
[0602]
[0603]
[0604]
[0605]
[0606]
[0607]
[0608]
[0609]
[0610]
[0611]
[0612]
[0613]
[0614]
[0615]
[0616]
[0617]
[0618]
[0619]
[0620]
[0621]
[0622]
[0623]
[0624]
[0625]
[0626]
[0627]
[0628]
[0629]
[0630]
[0631]
[0632]
[0633]
[0634]
[0635]
[0636]
[0637]
[0638]
[0639]
[0640]
[0641]
[0642]
[0643]
[0644]
[0645]
[0646]
[0647]
[0648]
[0649]
[0650]
[0651]
[0652]
[0653]
[0654]
[0655]
[0656]
[0657]
[0658]
[0659]
[0660]
[0661]
[0662]
[0663]
[0664]
[0665]
[0666]
[0667]
[0668]
[0669]
[0670]
[0671]
[0672]
[0673]
[0674]
[0675]
[0676]
[0677]
[0678]
[0679]
[0680]
[0681]
[0682]
[0683]
[0684]
[0685]
[0686]
[0687]
[0688]
[0689]
[0690]
[0691]
[0692]
[0693]
[0694]
[0695]
[0696]
[0697]
[0698]
[0699]
[0700]
[0701]
[0702]
[0703]
[0704]
[0705]
[0706]
[0707]
[0708]
[0709]
[0710]
[0711]
[0712]
[0713]
[0714]
[0715]
[0716]
[0717]
[0718]
[0719]
[0720]
[0721]
[0722]
[0723]
[0724]
[0725]
[0726]
[0727]
[0728]
[0729]
[0730]
[0731]
[0732]
[0733]
[0734]
[0735]
[0736]
[0737]
[0738]
[0739]
[0740]
[0741]
[0742]
[0743]
[0744]
[0745]
[0746]
[0747]
[0748]
[0749]
[0750]
[0751]
[0752]
[0753]
[0754]
[0755]
[0756]
[0757]
[0758]
[0759]
[0760]
[0761]
[0762]
[0763]
[0764]
[0765]
[0766]
[0767]
[0768]
[0769]
[0770]
[0771]
[0772]
[0773]
[0774]
[0775]
[0776]
[0777]
[0778]
[0779]
[0780]
[0781]
[0782]
[0783]
[0784]
[0785]
[0786]
[0787]
[0788]
[0789]
[0790]
[0791]
[0792]
[0793]
[0794]
[0795]
[0796]
[0797]
[0798]
[0799]
[0800]
[0801]
[0802]
[0803]
[0804]
[0805]
[0806]
[0807]
[0808]
[0809]
[0810]
[0811]
[0812]
[0813]
[0814]
[0815]
[0816]
[0817]
[0818]
[0819]
[0820]
[0821]
[0822]
[0823]
[0824]
[0825]
[0826]
[0827]
[0828]
[0829]
[0830]
[0831]
[0832]
[0833]
[0834]
[0835]
[0836]
[0837]
[0838]
[0839]
[0840]
[0841]
[0842]
[0843]
[0844]
[0845]
[0846]
[0847]
[0848]
[0849]
[0850]
[0851]
[0852]
[0853]
[0854]
[0855]
[0856]
[0857]
[0858]
[0859]
[0860]
[0861]
[0862]
[0863]
[0864]
[0865]
[0866]
[0867]
[0868]
[0869]
[0870]
[0871]
[0872]
[0873]
[0874]
[0875]
[0876]
[0877]
[0878]
[0879]
[0880]
[0881]
[0882]
[0883]
[0884]
[0885]
[0886]
[0887]
[0888]
[0889]
[0890]
[0891]
[0892]
[0893]
[0894]
[0895]
[0896]
[0897]
[0898]
[0899]
[0900]
[0901]
[0902]
[0903]
[0904]
[0905]
[0906]
[0907]
[0908]
[0909]
[0910]
[0911]
[0912]
[0913]
[0914]
[0915]
[0916]
[0917]
[0918]
[0919]
[0920]
[0921]
[0922]
[0923]
[0924]
[0925]
[0926]
[0927]
[0928]
[0929]
[0930]
[0931]
[0932]
[0933]
[0934]
[0935]
[0936]
[0937]
[0938]
[0939]
[0940]
[0941]
[0942]
[0943]
[0944]
[0945]
[0946]
[0947]
[0948]
[0949]
[0950]
[0951]
[0952]
[0953]
[0954]
[0955]
[0956]
[0957]
[0958]
[0959]
[0960]
[0961]
[0962]
[0963]
[0964]
[0965]
[0966]
[0967]
[0968]
[0969]
[0970]
[0971]
[0972]
[0973]
[0974]
[0975]
[0976]
[0977]
[0978]
[0979]
[0980]
[0981]
[0982]
[0983]
[0984]
[0985]
[0986]
[0987]
[0988]
[0989]
[0990]
[0991]
[0992]
[0993]
[0994]
[0995]
[0996]
[0997]
[0998]
[0999]
[1000]
[1001]
[1002]
[1003]
[1004]
[1005]
[1006]
[1007]
[1008]
[1009]
[1010]
[1011]
[1012]
[1013]
[1014]
[1015]
[1016]
[1017]
[1018]
[1019]
[1020]
[1021]
[1022]
[1023]
[1024]
[1025]
[1026]
[1027]
[1028]
[1029]
[1030]
[1031]
[1032]
[1033]
[1034]
[1035]
[1036]
[1037]
[1038]
[1039]
[1040]
[1041]
[1042]
[1043]
[1044]
[1045]
[1046]
[1047]
[1048]
[1049]
[1050]
[1051]
[1052]
[1053]
[1054]
[1055]
[1056]
[1057]
[1058]
[1059]
[1060]
[1061]
[1062]
[1063]
[1064]
[1065]
[1066]
[1067]
[1068]
[1069]
[1070]
[1071]
[1072]
[1073]
[1074]
[1075]
[1076]
[1077]
[1078]
[1079]
[1080]
[1081]
[1082]
[1083]
[1084]
[1085]
[1086]
[1087]
[1088]
[1089]
[1090]
[1091]
[1092]
[1093]
[1094]
[1095]
[1096]
[1097]
[1098]
[1099]
[1100]
[1101]
[1102]
[1103]
[1104]
[1105]
[1106]
[1107]
[1108]
[1109]
[1110]
[1111]
[1112]
[1113]
[1114]
[1115]
[1116]
[1117]
[1118]
[1119]
[1120]
[1121]
[1122]
[1123]
[1124]
[1125]
[1126]
[1127]
[1128]
[1129]
[1130]
[1131]
[1132]
[1133]
[1134]
[1135]
[1136]
[1137]
[1138]
[1139]
[1140]
[1141]
[1142]
[1143]
[1144]
[1145]
[1146]
[1147]
[1148]
[1149]
[1150]
[1151]
[1152]
[1153]
[1154]
[1155]
[1156]
[1157]
[1158]
[1159]
[1160]
[1161]
[1162]
[1163]
[1164]
[1165]
[1166]
[1167]
[1168]
[1169]
[1170]
[1171]
[1172]
[1173]
[1174]
[1175]
[1176]
[1177]
[1178]
[1179]
[1180]
[1181]
[1182]
[1183]
[1184]
[1185]
[1186]
[1187]
[1188]
[1189]
[1190]
[1191]
[1192]
[1193]
[1194]
[1195]
[1196]
[1197]
[1198]
[1199]
[1200]
[1201]
[1202]
[1203]
[1204]
[1205]
[1206]
[1207]
[1208]
[1209]
[1210]
[1211]
[1212]
[1213]
[1214]
[1215]
[1216]
[1217]
[1218]
[1219]
[1220]
[1221]
[1222]
[1223]
[1224]
[1225]
[1226]
[1227]
[1228]
[1229]
[1230]
[1231]
[1232]
[1233]
[1234]
[1235]
[1236]
[1237]
[1238]
[1239]
[1240]
[1241]
[1242]
[1243]
[1244]
[1245]
[1246]
[1247]
[1248]
[1249]
[1250]
[1251]
[1252]
[1253]
[1254]
[1255]
[1256]
[1257]
[1258]
[1259]
[1260]
[1261]
[1262]
[1263]
[1264]
[1265]
[1266]
[1267]
[1268]
[1269]
[1270]
[1271]
[1272]
[1273]
[1274]
[1275]
[1276]
[1277]
[1278]
[1279]
[1280]
[1281]
[1282]
[1283]
[1284]
[1285]
[1286]
[1287]
[1288]
[1289]
[1290]
[1291]
[1292]
[1293]
[1294]
[1295]
[1296]
[1297]
[1298]
[1299]
[1300]
[1301]
[1302]
[1303]
[1304]
[1305]
[1306]
[1307]
[1308]
[1309]
[1310]
[1311]
[1312]
[1313]
[1314]
[1315]
[1316]
[1317]
[1318]
[1319]
[1320]
[1321]
[1322]
[1323]
[1324]
[1325]
[1326]
[1327]
[1328]
[1329]
[1330]
[1331]
[1332]
[1333]
[1334]
[1335]
[1336]
[1337]
[1338]
[1339]
[1340]
[1341]
[1342]
[1343]
[1344]
[1345]
[1346]
[1347]
[1348]
[1349]
[1350]
[1351]
[1352]
[1353]
[1354]
[1355]
[1356]
[1357]
[1358]
[1359]
[1360]
[1361]
[1362]
[1363]
[1364]
[1365]
[1366]
[1367]
[1368]
[1369]
[1370]
[1371]
[1372]
[1373]
[1374]
[1375]
[1376]
[1377]
[1378]
[1379]
[1380]
[1381]
[1382]
[1383]
[1384]
[1385]
[1386]
[1387]
[1388]
[1389]
[1390]
[1391]
[1392]
[1393]
[1394]
[1395]
[1396]
[1397]
[1398]
[1399]
[1400]
[1401]
[1402]
[1403]
[1404]
[1405]
[1406]
[1407]
[1408]
[1409]
[1410]
[1411]
[1412]
[1413]
[1414]
[1415]
[1416]
[1417]
[1418]
[1419]
[1420]
[1421]
[1422]
[1423]
[1424]
[1425]
[1426]
[1427]
[1428]
[1429]
[1430]
[1431]
[1432]
[1433]
[1434]
[1435]
[1436]
[1437]
[1438]
[1439]
[1440]
[1441]
[1442]
[1443]
[1444]
[1445]
[1446]
[1447]
[1448]
[1449]
[1450]
[1451]
[1452]
[1453]
[1454]
[1455]
[1456]
[1457]
[1458]
[1459]
[1460]
[1461]
[1462]
[1463]
[1464]
[1465]
[1466]
[1467]
[1468]
[1469]
[1470]
[1471]
[1472]
[1473]
[1474]
[1475]
[1476]
[1477]
[1478]
[1479]
[1480]
[1481]
[1482]
[1483]
[1484]
[1485]
[1486]
[1487]
[1488]
[1489]
[1490]
[1491]
[1492]
[1493]
[1494]
[1495]
[1496]
[1497]
[1498]
[1499]
[1500]
[1501]
[1502]
[1503]
[1504]
[1505]
[1506]
[1507]
[1508]
[1509]
[1510]
[1511]
[1512]
[1513]
[1514]
[1515]
[1516]
[1517]
[1518]
[1519]
[1520]
[1521]
[1522]
[1523]
[1524]
[1525]
[1526]
[1527]
[1528]
[1529]
[1530]
[1531]
[1532]
[1533]
[1534]
[1535]
[1536]
[1537]
[1538]
[1539]
[1540]
[1541]
[1542]
[1543]
[1544]
[1545]
[1546]
[1547]
[1548]
[1549]
[1550]
[1551]
[1552]
[1553]
[1554]
[1555]
[1556]
[1557]
[1558]
[1559]
[1560]
[1561]
[1562]
[1563]
[1564]
[1565]
[1566]
[1567]
[1568]
[1569]
[1570]
[1571]
[1572]
[1573]
[1574]
[1575]
[1576]
[1577]
[1578]
[1579]
[1580]
[1581]
[1582]
[1583]
[1584]
[1585]
[1586]
[1587]
[1588]
[1589]
[1590]
[1591]
[1592]
[1593]
[1594]
[1595]
[1596]
[1597]
[1598]
[1599]
[1600]
[1601]
[1602]
[1603]
[1604]
[1605]
[1606]
[1607]
[1608]
[1609]
[1610]
[1611]
[1612]
[1613]
[1614]
[1615]
[1616]
[1617]
[1618]
[1619]
[1620]
[1621]
[1622]
[1623]
[1624]
[1625]
[1626]
[1627]
[1628]
[1629]
[1630]
[1631]
[1632]
[1633]
[1634]
[1635]
[1636]
[1637]
[1638]
[1639]
[1640]
[1641]
[1642]
[1643]
[1644]
[1645]
[1646]
[1647]
[1648]
[1649]
[1650]
[1651]
[1652]
[1653]
[1654]
[1655]
[1656]
[1657]
[1658]
[1659]
[1660]
[1661]
[1662]
[1663]
[1664]
[1665]
[1666]
[1667]
[1668]
[1669]
[1670]
[1671]
[1672]
[1673]
[1674]
[1675]
[1676]
[1677]
[1678]
[1679]
[1680]
[1681]
[1682]
[1683]
[1684]
[1685]
[1686]
[1687]
[1688]
[1689]
[1690]
[1691]
[1692]
[1693]
[1694]
[1695]
[1696]
[1697]
[1698]
[1699]
[1700]
[1701]
[1702]
[1703]
[1704]
[1705]
[1706]
[1707]
[1708]
[1709]
[1710]
[1711]
[1712]
[1713]
[1714]
[1715]
[1716]
[1717]
[1718]
[1719]
[1720]
[1721]
[1722]
[1723]
[1724]
[1725]
[1726]
[1727]
[1728]
[1729]
[1730]
[1731]
[1732]
[1733]
[1734]
[1735]
[1736]
[1737]
[1738]
[1739]
[1740]
[1741]
[1742]
[1743]
[1744]
[1745]
[1746]
[1747]
[1748]
[1749]
[1750]
[1751]
[1752]
[1753]
[1754]
[1755]
[1756]
[1757]
[1758]
[1759]
[1760]
[1761]
[1762]
[1763]
[1764]
[1765]
[1766]
[1767]
[1768]
[1769]
[1770]
[1771]
[1772]
[1773]
[1774]
[1775]
[1776]
[1777]
[1778]
[1779]
[1780]
[1781]
[1782]
[1783]
[1784]
[1785]
[1786]
[1787]
[1788]
[1789]
[1790]
[1791]
[1792]
[1793]
[1794]
[1795]
[1796]
[1797]
[1798]
[1799]
[1800]
[1801]
[1802]
[1803]
[1804]
[1805]
[1806]
[1807]
[1808]
[1809]
[1810]
[1811]
[1812]
[1813]
[1814]
[1815]
[1816]
[1817]
[1818]
[1819]
[1820]
[1821]
[1822]
[1823]
[1824]
[1825]
[1826]
[1827]
[1828]
[1829]
[1830]
[1831]
[1832]
[1833]
[1834]
[1835]
[1836]
[1837]
[1838]
[1839]
[1840]
[1841]
[1842]
[1843]
[1844]
[1845]
[1846]
[1847]
[1848]
[1849]
[1850]
[1851]
[1852]
[1853]
[1854]
[1855]
[1856]
[1857]
[1858]
[1859]
[1860]
[1861]
[1862]
[1863]
[1864]
[1865]
[1866]
[1867]
[1868]
[1869]
[1870]
[1871]
[1872]
[1873]
[1874]
[1875]
[1876]
[1877]
[1878]
[1879]
[1880]
[1881]
[1882]
[1883]
[1884]
[1885]
[1886]
[1887]
[1888]
[1889]
[1890]
[1891]
[1892]
[1893]
[1894]
[1895]
[1896]
[1897]
[1898]
[1899]
[1900]
[1901]
[1902]
[1903]
[1904]
[1905]
[1906]
[1907]
[1908]
[1909]
[1910]
[1911]
[1912]
[1913]
[1914]
[1915]
[1916]
[1917]
[1918]
[1919]
[1920]
[1921]
[1922]
[1923]
[1924]
[1925]
[1926]
[1927]
[1928]
[1929]
[1930]
[1931]
[1932]
[1933]
[1934]
[1935]
[1936]
[1937]
[1938]
[1939]
[1940]
[1941]
[1942]
[1943]
[1944]
[1945]
[1946]
[1947]
[1948]
[1949]
[1950]
[1951]
[1952]
[1953]
[1954]
[1955]
[1956]
[1957]
[1958]
[1959]
[1960]
[1961]
[1962]
[1963]
[1964]
[1965]
[1966]
[1967]
[1968]
[1969]
[1970]
[1971]
[1972]
[1973]
[1974]
[1975]
[1976]
[1977]
[1978]
[1979]
[1980]
[1981]
[1982]
[1983]
[1984]
[1985]
[1986]
[1987]
[1988]
[1989]
[1990]
[1991]
[1992]
[1993]
[1994]
[1995]
[1996]
[1997]
[1998]
[1999]
[2000]
[2001]
[2002]
[2003]
[2004]
[2005]
[2006]
[2007]
[2008]
[2009]
[2010]
[2011]
[2012]
[2013]
[2014]
[2015]
[2016]
[2017]
[2018]
[2019]
[2020]
[2021]
[2022]
[2023]
[2024]
[2025]
[2026]
[2027]
[2028]
[2029]
[2030]
[2031]
[2032]
[2033]
[2034]
[2035]
[2036]
[2037]
[2038]
[2039]
[2040]
[2041]
[2042]
[2043]
[2044]
[2045]
[2046]
[2047]
[2048]
[2049]
[2050]
[2051]
[2052]
[2053]
[2054]
[2055]
[2056]
[2057]
[2058]
[2059]
[2060]
[2061]
[2062]
[2063]
[2064]
[2065]
[2066]
[2067]
[2068]
[2069]
[2070]
[2071]
[2072]
[2073]
[2074]
[2075]
[2076]
[2077]
[2078]
[2079]
[2080]
[2081]
[2082]
[2083]
[2084]
[2085]
[2086]
[2087]
[2088]
[2089]
[2090]
[2091]
[2092]
[2093]
[2094]
[2095]
[2096]
[2097]
[2098]
[2099]
[2100]
[2101]
[2102]
[2103]
[2104]
[2105]
[2106]
[2107]
[2108]
[2109]
[2110]
[2111]
[2112]
[2113]
[2114]
[2115]
[2116]
[2117]
[2118]
[2119]
[2120]
[2121]
[2122]
[2123]
[2124]
[2125]
[2126]
[2127]
[2128]
[2129]
[2130]
[2131]
[2132]
[2133]
[2134]
[2135]
[2136]
[2137]
[2138]
[2139]
[2140]
[2141]
[2142]
[2143]
[2144]
[2145]
[2146]
[2147]
[2148]
[2149]
[2150]
[2151]
[2152]
[2153]
[2154]
[2155]
[2156]
[2157]
[2158]
[2159]
[2160]
[2161]
[2162]
[2163]
[2164]
[2165]
[2166]
[2167]
[2168]
[2169]
[2170]
[2171]
[2172]
[2173]
[2174]
[2175]
[2176]
[2177]
[2178]
[2179]
[2180]
[2181]
[2182]
[2183]
[2184]
[2185]
[2186]
[2187]
[2188]
[2189]
[2190]
[2191]
[2192]
[2193]
[2194]
[2195]
[2196]
[2197]
[2198]
[2199]
[2200]
[2201]
[2202]
[2203]
[2204]
[2205]
[2206]
[2207]
[2208]
[2209]
[2210]
[2211]
[2212]
[2213]
[2214]
[2215]
[2216]
[2217]
[2218]
[2219]
[2220]
[2221]
[2222]
[2223]
[2224]
[2225]
[2226]
[2227]
[2228]
[2229]
[2230]
[2231]
[2232]
[2233]
[2234]
[2235]
[2236]
[2237]
[2238]
[2239]
[2240]
[2241]
[2242]
[2243]
[2244]
[2245]
[2246]
[2247]
[2248]
[2249]
[2250]
[2251]
[2252]
[2253]
[2254]
[2255]
[2256]
[2257]
[2258]
[2259]
[2260]
[2261]
[2262]
[2263]
[2264]
[2265]
[2266]
[2267]
[2268]
[2269]
[2270]
[2271]
[2272]
[2273]
[2274]
[2275]
[2276]
[2277]
[2278]
[2279]
[2280]
[2281]
[2282]
[2283]
[2284]
[2285]
[2286]
[2287]
[2288]
[2289]
[2290]
[2291]
[2292]
[2293]
[2294]
[2295]
[2296]
[2297]
[2298]
[2299]
[2300]
[2301]
[2302]
[2303]
[2304]
[2305]
[2306]
[2307]
[2308]
[2309]
[2310]
[2311]
[2312]
[2313]
[2314]
[2315]
[2316]
[2317]
[2318]
[2319]
[2320]
[2321]
[2322]
[2323]
[2324]
[2325]
[2326]
[2327]
[2328]
[2329]
[2330]
[2331]
[2332]
[2333]
[2334]
[2335]
[2336]
[2337]
[2338]
[2339]
[2340]
[2341]
[2342]
[2343]
[2344]
[2345]
[2346]
[2347]
[2348]
[2349]
[2350]
[2351]
[2352]
[2353]
[2354]
[2355]
[2356]
[2357]
[2358]
[2359]
[2360]
[2361]
[2362]
[2363]
[2364]
[2365]
[2366]
[2367]
[2368]
[2369]
[2370]
[2371]
[2372]
[2373]
[2374]
[2375]
[2376]
[2377]
[2378]
[2379]
[2380]
[2381]
[2382]
[2383]
[2384]
[2385]
[2386]
[2387]
[2388]
[2389]
[2390]
[2391]
[2392]
[2393]
[2394]
[2395]
[2396]
[2397]
[2398]
[2399]
[2400]
[2401]
[2402]
[2403]
[2404]
[2405]
[2406]
[2407]
[2408]
[2409]
[2410]
[2411]
[2412]
[2413]
[2414]
[2415]
[2416]
[2417]
[2418]
[2419]
[2420]
[2421]
[2422]
[2423]
[2424]
[2425]
[2426]
[2427]
[2428]
[2429]
[2430]
[2431]
[2432]
[2433]
[2434]
[2435]
[2436]
[2437]
[2438]
[2439]
[2440]
[2441]
[2442]
[2443]
[2444]
[2445]
[2446]
[2447]
[2448]
[2449]
[2450]
[2451]
[2452]
[2453]
[2454]
[2455]
[2456]
[2457]
[2458]
[2459]
[2460]
[2461]
[2462]
[2463]
[2464]
[2465]
[2466]
[2467]
[2468]
[2469]
[2470]
[2471]
[2472]
[2473]
[2474]
[2475]
[2476]
[2477]
[2478]
[2479]
[2480]
[2481]
[2482]
[2483]
[2484]
[2485]
[2486]
[2487]
[2488]
[2489]
[2490]
[2491]
[2492]
[2493]
[2494]
[2495]
[2496]
[2497]
[2498]
[2499]
[2500]
[2501]
[2502]
[2503]
[2504]
[2505]
[2506]
[2507]
[2508]
[2509]
[2510]
[2511]
[2512]
[2513]
[2514]
[2515]
[2516]
[2517]
[2518]
[2519]
[2520]
[2521]
[2522]
[2523]
[2524]
[2525]
[2526]
[2527]
[2528]
[2529]
[2530]
[2531]
[2532]
[2533]
[2534]
[2535]
[2536]
[2537]
[2538]
[2539]
[2540]
[2541]
[2542]
[2543]
[2544]
[2545]
[2546]
[2547]
[2548]
[2549]
[2550]
[2551]
[2552]
[2553]
[2554]
[2555]
[2556]
[2557]
[2558]
[2559]
[2560]
[2561]
[2562]
[2563]
[2564]
[2565]
[2566]
[2567]
[2568]
[2569]
[2570]
[2571]
[2572]
[2573]
[2574]
[2575]
[2576]
[2577]
[2578]
[2579]
[2580]
[2581]
[2582]
[2583]
[2584]
[2585]
[2586]
[2587]
[2588]
[2589]
[2590]
[2591]
[2592]
[2593]
[2594]
[2595]
[2596]
[2597]
[2598]
[2599]
[2600]
[2601]
[2602]
[2603]
[2604]
[2605]
[2606]
[2607]
[2608]
[2609]
[2610]
[2611]
[2612]
[2613]
[2614]
[2615]
[2616]
[2617]
[2618]
[2619]
[2620]
[2621]
[2622]
[2623]
[2624]
[2625]
[2626]
[2627]
[2628]
[2629]
[2630]
[2631]
[2632]
[2633]
[2634]
[2635]
[2636]
[2637]
[2638]
[2639]
[2640]
[2641]
[2642]
[2643]
[2644]
[2645]
[2646]
[2647]
[2648]
[2649]
[2650]
[2651]
[2652]
[2653]
[2654]
[2655]
[2656]
[2657]
[2658]
[2659]
[2660]
[2661]
[2662]
[2663]
[2664]
[2665]
[2666]
[2667]
[2668]
[2669]
[2670]
[2671]
[2672]
[2673]
[2674]
[2675]
[2676]
[2677]
[2678]
[2679]
[2680]
[2681]
[2682]
[2683]
[2684]
[2685]
[2686]
[2687]
[2688]
[2689]
[2690]
[2691]
[2692]
[2693]
[2694]
[2695]
[2696]
[2697]
[2698]
[2699]
[2700]
[2701]
[2702]
[2703]
[2704]
[2705]
[2706]
[2707]
[2708]
[2709]
[2710]
[2711]
[2712]
[2713]
[2714]
[2715]
[2716]
[2717]
[2718]
[2719]
[2720]
[2721]
[2722]
[2723]
[2724]
[2725]
[2726]
[2727]
[2728]
[2729]
[2730]
[2731]
[2732]
[2733]
[2734]
[2735]
[2736]
[2737]
[2738]
[2739]
[2740]
[2741]
[2742]
[2743]
[2744]
[2745]
[2746]
[2747]
[2748]
[2749]
[2750]
[2751]
[2752]
[2753]
[2754]
[2755]
[2756]
[2757]
[2758]
[2759]
[2760]
[2761]
[2762]
[2763]
[2764]
[2765]
[2766]
[2767]
[2768]
[2769]
[2770]
[2771]
[2772]
[2773]
[2774]
[2775]
[2776]
[2777]
[2778]
[2779]
[2780]
[2781]
[2782]
[2783]
[2784]
[2785]
[2786]
[2787]
[2788]
[2789]
[2790]
[2791]
[2792]
[2793]
[2794]
[2795]
[2796]
[2797]
[2798]
[2799]
[2800]
[2801]
[2802]
[2803]
[2804]
[2805]
[2806]
[2807]
[2808]
[2809]
[2810]
[2811]
[2812]
[2813]
[2814]
[2815]
[2816]
[2817]
[2818]
[2819]
[2820]
[2821]
[2822]
[2823]
[2824]
[2825]
[2826]
[2827]
[2828]
[2829]
[2830]
[2831]
[2832]
[2833]
[2834]
[2835]
[2836]
[2837]
[2838]
[2839]
[2840]
[2841]
[2842]
[2843]
[2844]
[2845]
[2846]
[2847]
[2848]
[2849]
[2850]
[2851]
[2852]
[2853]
[2854]
[2855]
[2856]
[2857]
[2858]
[2859]
[2860]
[2861]
[2862]
[2863]
[2864]
[2865]
[2866]
[2867]
[2868]
[2869]
[2870]
[2871]
[2872]
[2873]
[2874]
[2875]
[2876]
[2877]
[2878]
[2879]
[2880]
[2881]
[2882]
[2883]
[2884]
[2885]
[2886]
[2887]
[2888]
[2889]
[2890]
[2891]
[2892]
[2893]
[2894]
[2895]
[2896]
[2897]
[2898]
[2899]
[2900]
[2901]
[2902]
[2903]
[2904]
[2905]
[2906]
[2907]
[2908]
[2909]
[2910]
[2911]
[2912]
[2913]
[2914]
[2915]
[2916]
[2917]
[2918]
[2919]
[2920]
[2921]
[2922]
[2923]
[2924]
[2925]
[2926]
[2927]
[2928]
[2929]
[2930]
[2931]
[2932]
[2933]
[2934]
[2935]
[2936]
[2937]
[2938]
[2939]
[2940]
[2941]
[2942]
[2943]
[2944]
[2945]
[2946]
[2947]
[2948]
[2949]
[2950]
[2951]
[2952]
[2953]
[2954]
[2955]
[2956]
[2957]
[2958]
[2959]
[2960]
[2961]
[2962]
[2963]
[2964]
[2965]
[2966]
[2967]
[2968]
[2969]
[2970]
[2971]
[2972]
[2973]
[2974]
[2975]
[2976]
[2977]
[2978]
[2979]
[2980]
[2981]
[2982]
[2983]
[2984]
[2985]
[2986]
[2987]
[2988]
[2989]
[2990]
[2991]
[2992]
[2993]
[2994]
[2995]
[2996]
[2997]
[2998]
[2999]
[3000]
[3001]
[3002]
[3003]
[3004]
[3005]
[3006]
[3007]
[3008]
[3009]
[3010]
[3011]
[3012]
[3013]
[3014]
[3015]
[3016]
[3017]
[3018]
[3019]
[3020]
[3021]
[3022]
[3023]
[3024]
[3025]
[3026]
[3027]
[3028]
[3029]
[3030]
[3031]
[3032]
[3033]
[3034]
[3035]
[3036]
[3037]
[3038]
[3039]
[3040]
[3041]
[3042]
[3043]
[3044]
[3045]
[3046]
[3047]
[3048]
[3049]
[3050]
[3051]
[3052]
[3053]
[3054]
[3055]
[3056]
[3057]
[3058]
[3059]
[3060]
[3061]
[3062]
[3063]
[3064]
[3065]
[3066]
[3067]
[3068]
[3069]
[3070]
[3071]
[3072]
[3073]
[3074]
[3075]
[3076]
[3077]
[3078]
[3079]
[3080]
[3081]
[3082]
[3083]
[3084]
[3085]
[3086]
[3087]
[3088]
[3089]
[3090]
[3091]
[3092]
[3093]
[3094]
[3095]
[3096]
[3097]
[3098]
[3099]
[3100]
[3101]
[3102]
[3103]
[3104]
[3105]
[3106]
[3107]
[3108]
[3109]
[3110]
[3111]
[3112]
[3113]
[3114]
[3115]
[3116]
[3117]
[3118]
[3119]
[3120]
[3121]
[3122]
[3123]
[3124]
[3125]
[3126]
[3127]
[3128]
[3129]
[3130]
[3131]
[3132]
[3133]
[3134]
[3135]
[3136]
[3137]
[3138]
[3139]
[3140]
[3141]
[3142]
[3143]
[3144]
[3145]
[3146]
[3147]
[3148]
[3149]
[3150]
[3151]
[3152]
[3153]
[3154]
[3155]
[3156]
[3157]
[3158]
[3159]
[3160]
[3161]
[3162]
[3163]
[3164]
[3165]
[3166]
[3167]
[3168]
[3169]
[3170]
[3171]
[3172]
[3173]
[3174]
[3175]
[3176]
[3177]
[3178]
[3179]
[3180]
[3181]
[3182]
[3183]
[3184]
[3185]
[3186]
[3187]
[3188]
[3189]
[3190]
[3191]
[3192]
[3193]
[3194]
[3195]
[3196]
[3197]
[3198]
[3199]
[3200]
[3201]
[3202]
[3203]
[3204]
[3205]
[3206]
[3207]
[3208]
[3209]
[3210]
[3211]
[3212]
[3213]
[3214]
[3215]
[3216]
[3217]
[3218]
[3219]
[3220]
[3221]
[3222]
[3223]
[3224]
[3225]
[3226]
[3227]
[3228]
[3229]
[3230]
[3231]
[3232]
[3233]
[3234]
[3235]
[3236]
[3237]
[3238]
[3239]
[3240]
[3241]
[3242]
[3243]
[3244]
[3245]
[3246]
[3247]
[3248]
[3249]
[3250]
[3251]
[3252]
[3253]
[3254]
[3255]
[3256]
[3257]
[3258]
[3259]
[3260]
[3261]
[3262]
[3263]
[3264]
[3265]
[3266]
[3267]
[3268]
[3269]
[3270]
[3271]
[3272]
[3273]
[3274]
[3275]
[3276]
[3277]
[3278]
[3279]
[3280]
[3281]
[3282]
[3283]
[3284]
[3285]
[3286]
[3287]
[3288]
[3289]
[3290]
[3291]
[3292]
[3293]
[3294]
[3295]
[3296]
[3297]
[3298]
[3299]
[3300]
[3301]
[3302]
[3303]
[3304]
[3305]
[3306]
[3307]
[3308]
[3309]
[3310]
[3311]
[3312]
[3313]
[3314]
[3315]
[3316]
[3317]
[3318]
[3319]
[3320]
[3321]
[3322]
[3323]
[3324]
[3325]
[3326]
[3327]
[3328]
[3329]
[3330]
[3331]
[3332]
[3333]
[3334]
[3335]
[3336]
[3337]
[3338]
[3339]
[3340]
[3341]
[3342]
[3343]
[3344]
[3345]
[3346]
[3347]
[3348]
[3349]
[3350]
[3351]
[3352]
[3353]
[3354]
[3355]
[3356]
[3357]
[3358]
[3359]
[3360]
[3361]
[3362]
[3363]
[3364]
[3365]
[3366]
[3367]
[3368]
[3369]
[3370]
[3371]
[3372]
[3373]
[3374]
[3375]
[3376]
[3377]
[3378]
[3379]
[3380]
[3381]
[3382]
[3383]
[3384]
[3385]
[3386]
[3387]
[3388]
[3389]
[3390]
[3391]
[3392]
[3393]
[3394]
[3395]
[3396]
[3397]
[3398]
[3399]
[3400]
[3401]
[3402]
[3403]
[3404]
[3405]
[3406]
[3407]
[3408]
[3409]
[3410]
[3411]
[3412]
[3413]
[3414]
[3415]
[3416]
[3417]
[3418]
[3419]
[3420]
[3421]
[3422]
[3423]
[3424]
[3425]
[3426]
[3427]
[3428]
[3429]
[3430]
[3431]
[3432]
[3433]
[3434]
[3435]
[3436]
[3437]
[3438]
[3439]
[3440]
[3441]
[3442]
[3443]
[3444]
[3445]
[3446]
[3447]
[3448]
[3449]
[3450]
[3451]
[3452]
[3453]
[3454]
[3455]
[3456]
[3457]
[3458]
[3459]
[3460]
[3461]
[3462]
[3463]
[3464]
[3465]
[3466]
[3467]
[3468]
[3469]
[3470]
[3471]
[3472]
[3473]
[3474]
[3475]
[3476]
[3477]
[3478]
[3479]
[3480]
[3481]
[3482]
[3483]
[3484]
[3485]
[3486]
[3487]
[3488]
[3489]
[3490]
[3491]
[3492]
[3493]
[3494]
[3495]
[3496]
[3497]
[3498]
[3499]
[3500]
[3501]
[3502]
[3503]
[3504]
[3505]
[3506]
[3507]
[3508]
[3509]
[3510]
[3511]
[3512]
[3513]
[3514]
[3515]
[3516]
[3517]
[3518]
[3519]
[3520]
[3521]
[3522]
[3523]
[3524]
[3525]
[3526]
[3527]
[3528]
[3529]
[3530]
[3531]
[3532]
[3533]
[3534]
[3535]
[3536]
[3537]
[3538]
[3539]
[3540]
[3541]
[3542]
[3543]
[3544]
[3545]
[3546]
[3547]
[3548]
[3549]
[3550]
[3551]
[3552]
[3553]
[3554]
[3555]
[3556]
[3557]
[3558]
[3559]
[3560]
[3561]
[3562]
[3563]
[3564]
[3565]
[3566]
[3567]
[3568]
[3569]
[3570]
[3571]
[3572]
[3573]
[3574]
[3575]
[3576]
[3577]
[3578]
[3579]
[3580]
[3581]
[3582]
[3583]
[3584]
[3585]
[3586]
[3587]
[3588]
[3589]
[3590]
[3591]
[3592]
[3593]
[3594]
[3595]
[3596]
[3597]
[3598]
[3599]
[3600]
[3601]
[3602]
[3603]
[3604]
[3605]
[3606]
[3607]
[3608]
[3609]
[3610]
[3611]
[3612]
[3613]
[3614]
[3615]
[3616]
[3617]
[3618]
[3619]
[3620]
[3621]
[3622]
[3623]
[3624]
[3625]
[3626]
[3627]
[3628]
[3629]
[3630]
[3631]
[3632]
[3633]
[3634]
[3635]
[3636]
[3637]
[3638]
[3639]
[3640]
[3641]
[3642]
[3643]
[3644]
[3645]
[3646]
[3647]
[3648]
[3649]
[3650]
[3651]
[3652]
[3653]
[3654]
[3655]
[3656]
[3657]
[3658]
[3659]
[3660]
[3661]
[3662]
[3663]
[3664]
[3665]
[3666]
[3667]
[3668]
[3669]
[3670]
[3671]
[3672]
[3673]
[3674]
[3675]
[3676]
[3677]
[3678]
[3679]
[3680]
[3681]
[3682]
[3683]
[3684]
[3685]
[3686]
[3687]
[3688]
[3689]
[3690]
[3691]
[3692]
[3693]
[3694]
[3695]
[3696]
[3697]
[3698]
[3699]
[3700]
[3701]
[3702]
[3703]
[3704]
[3705]
[3706]
[3707]
[3708]
[3709]
[3710]
[3711]
[3712]
[3713]
[3714]
[3715]
[3716]
[3717]
[3718]
[3719]
[3720]
[3721]
[3722]
[3723]
[3724]
[3725]
[3726]
[3727]
[3728]
[3729]
[3730]
[3731]
[3732]
[3733]
[3734]
[3735]
[3736]
[3737]
[3738]
[3739]
[3740]
[3741]
[3742]
[3743]
[3744]
[3745]
[3746]
[3747]
[3748]
[3749]
[3750]
[3751]
[3752]
[3753]
[3754]
[3755]
[3756]
[3757]
[3758]
[3759]
[3760]
[3761]
[3762]
[3763]
[3764]
[3765]
[3766]
[3767]
[3768]
[3769]
[3770]
[3771]
[3772]
[3773]
[3774]
[3775]
[3776]
[3777]
[3778]
[3779]
[3780]
[3781]
[3782]
[3783]
[3784]
[3785]
[3786]
[3787]
[3788]
[3789]
[3790]
[3791]
[3792]
[3793]
[3794]
[3795]
[3796]
[3797]
[3798]
[3799]
[3800]
[3801]
[3802]
[3803]
[3804]
[3805]
[3806]
[3807]
[3808]
[3809]
[3810]
[3811]
[3812]
[3813]
[3814]
[3815]
[3816]
[3817]
[3818]
[3819]
[3820]
[3821]
[3822]
[3823]
[3824]
[3825]
[3826]
[3827]
[3828]
[3829]
[3830]
[3831]
[3832]
[3833]
[3834]
[3835]
[3836]
[3837]
[3838]
[3839]
[3840]
[3841]
[3842]
[3843]
[3844]
[3845]
[3846]
[3847]
[3848]
[3849]
[3850]
[3851]
[3852]
[3853]
[3854]
[3855]
[3856]
[3857]
[3858]
[3859]
[3860]
[3861]
[3862]
[3863]
[3864]
[3865]
[3866]
[3867]
[3868]
[3869]
[3870]
[3871]
[3872]
[3873]
[3874]
[3875]
[3876]
[3877]
[3878]
[3879]
[3880]
[3881]
[3882]
[3883]
[3884]
[3885]
[3886]
[3887]
[3888]
[3889]
[3890]
[3891]
[3892]
[3893]
[3894]
[3895]
[3896]
[3897]
[3898]
[3899]
[3900]
[3901]
[3902]
[3903]
[3904]
[3905]
[3906]
[3907]
[3908]
[3909]
[3910]
[3911]
[3912]
[3913]
[3914]
[3915]
[3916]
[3917]
[3918]
[3919]
[3920]
[3921]
[3922]
[3923]
[3924]
[3925]
[3926]
[3927]
[3928]
[3929]
[3930]
[3931]
[3932]
[3933]
[3934]
[3935]
[3936]
[3937]
[3938]
[3939]
[3940]
[3941]
[3942]
[3943]
[3944]
[3945]
[3946]
[3947]
[3948]
[3949]
[3950]
[3951]
[3952]
[3953]
[3954]
[3955]
[3956]
[3957]
[3958]
[3959]
[3960]
[3961]
[3962]
[3963]
[3964]
[3965]
[3966]
[3967]
[3968]
[3969]
[3970]
[3971]
[3972]
[3973]
[3974]
[3975]
[3976]
[3977]
[3978]
[3979]
[3980]
[3981]
[3982]
[3983]
[3984]
[3985]
[3986]
[3987]
[3988]
[3989]
[3990]
[3991]
[3992]
[3993]
[3994]
[3995]
[3996]
[3997]
[3998]
[3999]
[4000]
[4001]
[4002]
[4003]
[4004]
[4005]
[4006]
[4007]
[4008]
[4009]
[4010]
[4011]
[4012]
[4013]
[4014]
[4015]
[4016]
[4017]
[4018]
[4019]
[4020]
[4021]
[4022]
[4023]
[4024]
[4025]
[4026]
[4027]
[4028]
[4029]
[4030]
[4031]
[4032]
[4033]
[4034]
[4035]
[4036]
[4037]
[4038]
[4039]
[4040]
[4041]
[4042]
[4043]
[4044]
[4045]
[4046]
[4047]
[4048]
[4049]
[4050]
[4051]
[4052]
[4053]
[4054]
[4055]
[4056]
[4057]
[4058]
[4059]
[4060]
[4061]
[4062]
[4063]
[4064]
[4065]
[4066]
[4067]
[4068]
[4069]
[4070]
[4071]
[4072]
[4073]
[4074]
[4075]
[4076]
[4077]
[4078]
[4079]
[4080]
[4081]
[4082]
[4083]
[4084]
[4085]
[4086]
[4087]
[4088]
[4089]
[4090]
[4091]
[4092]
[4093]
[4094]
[4095]
[4096]
[4097]
[4098]
[4099]
[4100]
[4101]
[4102]
[4103]
[4104]
[4105]
[4106]
[4107]
[4108]
[4109]
[4110]
[4111]
[4112]
[4113]
[4114]
[4115]
[4116]
[4117]
[4118]
[4119]
[4120]
[4121]
[4122]
[4123]
[4124]
[4125]
[4126]
[4127]
[4128]
[4129]
[4130]
[4131]
[4132]
[4133]
[4134]
[4135]
[4136]
[4137]
[4138]
[4139]
[4140]
[4141]
[4142]
[4143]
[4144]
[4145]
[4146]
[4147]
[4148]
[4149]
[4150]
[4151]
[4152]
[4153]
[4154]
[4155]
[4156]
[4157]
[4158]
[4159]
[4160]
[4161]
[4162]
[4163]
[4164]
[4165]
[4166]
[4167]
[4168]
[4169]
[4170]
[4171]
[4172]
[4173]
[4174]
[4175]
[4176]
[4177]
[4178]
[4179]
[4180]
[4181]
[4182]
[4183]
[4184]
[4185]
[4186]
[4187]
[4188]
[4189]
[4190]
[4191]
[4192]
[4193]
[4194]
[4195]
[4196]
[4197]
[4198]
[4199]
[4200]
[4201]
[4202]
[4203]
[4204]
[4205]
[4206]
[4207]
[4208]
[4209]
[4210]
[4211]
[4212]
[4213]
[4214]
[4215]
[4216]
[4217]
[4218]
[4219]
[4220]
[4221]
[4222]
[4223]
[4224]
[4225]
[4226]
[4227]
[4228]
[4229]
[4230]
[4231]
[4232]
[4233]
[4234]
[4235]
[4236]
[4237]
[4238]
[4239]
[4240]
[4241]
[4242]
[4243]
[4244]
[4245]
[4246]
[4247]
[4248]
[4249]
[4250]
[4251]
[4252]
[4253]
[4254]
[4255]
[4256]
[4257]
[4258]
[4259]
[4260]
[4261]
[4262]
[4263]
[4264]
[4265]
[4266]
[4267]
[4268]
[4269]
[4270]
[4271]
[4272]
[4273]
[4274]
[4275]
[4276]
[4277]
[4278]
[4279]
[4280]
[4281]
[4282]
[4283]
[4284]
[4285]
[4286]
[4287]
[4288]
[4289]
[4290]
[4291]
[4292]
[4293]
[4294]
[4295]
[4296]
[4297]
[4298]
[4299]
[4300]
[4301]
[4302]
[4303]
[4304]
[4305]
[4306]
[4307]
[4308]
[4309]
[4310]
[4311]
[4312]
[4313]
[4314]
[4315]
[4316]
[4317]
[4318]
[4319]
[4320]
[4321]
[4322]
[4323]
[4324]
[4325]
[4326]
[4327]
[4328]
[4329]
[4330]
[4331]
[4332]
[4333]
[4334]
[4335]
[4336]
[4337]
[4338]
[4339]
[4340]
[4341]
[4342]
[4343]
[4344]
[4345]
[4346]
[4347]
[4348]
[4349]
[4350]
[4351]
[4352]
[4353]
[4354]
[4355]
[4356]
[4357]
[4358]
[4359]
[4360]
[4361]
[4362]
[4363]
[4364]
[4365]
[4366]
[4367]
[4368]
[4369]
[4370]
[4371]
[4372]
[4373]
[4374]
[4375]
[4376]
[4377]
[4378]
[4379]
[4380]
[4381]
[4382]
[4383]
[4384]
[4385]
[4386]
[4387]
[4388]
[4389]
[4390]
[4391]
[4392]
[4393]
[4394]
[4395]
[4396]
[4397]
[4398]
[4399]
[4400]
[4401]
[4402]
[4403]
[4404]
[4405]
[4406]
[4407]
[4408]
[4409]
[4410]
[4411]
[4412]
[4413]
[4414]
[4415]
[4416]
[4417]
[4418]
[4419]
[4420]
[4421]
[4422]
[4423]
[4424]
[4425]
[4426]
[4427]
[4428]
[4429]
[4430]
[4431]
[4432]
[4433]
[4434]
[4435]
[4436]
[4437]
[4438]
[4439]
[4440]
[4441]
[4442]
[4443]
[4444]
[4445]
[4446]
[4447]
[4448]
[4449]
[4450]
[4451]
[4452]
[4453]
[4454]
[4455]
[4456]
[4457]
[4458]
[4459]
[4460]
[4461]
[4462]
[4463]
[4464]
[4465]
[4466]
[4467]
[4468]
[4469]
[4470]
[4471]
[4472]
[4473]
[4474]
[4475]
[4476]
[4477]
[4478]
[4479]
[4480]
[4481]
[4482]
[4483]
[4484]
[4485]
[4486]
[4487]
[4488]
[4489]
[4490]
[4491]
[4492]
[4493]
[4494]
[4495]
[4496]
[4497]
[4498]
[4499]
[4500]
[4501]
[4502]
[4503]
[4504]
[4505]
[4506]
[4507]
[4508]
[4509]
[4510]
[4511]
[4512]
[4513]
[4514]
[4515]
[4516]
[4517]
[4518]
[4519]
[4520]
[4521]
[4522]
[4523]
[4524]
[4525]
[4526]
[4527]
[4528]
[4529]
[4530]
[4531]
[4532]
[4533]
[4534]
[4535]
[4536]
[4537]
[4538]
[4539]
[4540]
[4541]
[4542]
[4543]
[4544]
[4545]
[4546]
[4547]
[4548]
[4549]
[4550]
[4551]
[4552]
[4553]
[4554]
[4555]
[4556]
[4557]
[4558]
[4559]
[4560]
[4561]
[4562]
[4563]
[4564]
[4565]
[4566]
[4567]
[4568]
[4569]
[4570]
[4571]
[4572]
[4573]
[4574]
[4575]
[4576]
[4577]
[4578]
[4579]
[4580]
[4581]
[4582]
[4583]
[4584]
[4585]
[4586]
[4587]
[4588]
[4589]
[4590]
[4591]
[4592]
[4593]
[4594]
[4595]
[4596]
[4597]
[4598]
[4599]
[4600]
[4601]
[4602]
[4603]
[4604]
[4605]
[4606]
[4607]
[4608]
[4609]
[4610]
[4611]
[4612]
[4613]
[4614]
[4615]
[4616]
[4617]
[4618]
[4619]
[4620]
[4621]
[4622]
[4623]
[4624]
[4625]
[4626]
[4627]
[4628]
[4629]
[4630]
[4631]
[4632]
[4633]
[4634]
[4635]
[4636]
[4637]
[4638]
[4639]
[4640]
[4641]
[4642]
[4643]
[4644]
[4645]
[4646]
[4647]
[4648]
[4649]
[4650]
[4651]
[4652]
[4653]
[4654]
[4655]
[4656]
[4657]
[4658]
[4659]
[4660]
[4661]
[4662]
[4663]
[4664]
[4665]
[4666]
[4667]
[4668]
[4669]
[4670]
[4671]
[4672]
[4673]
[4674]
[4675]
[4676]
[4677]
[4678]
[4679]
[4680]
[4681]
[4682]
[4683]
[4684]
[4685]
[4686]
[4687]
[4688]
[4689]
[4690]
[4691]
[4692]
[4693]
[4694]
[4695]
[4696]
[4697]
[4698]
[4699]
[4700]
[4701]
[4702]
[4703]
[4704]
[4705]
[4706]
[4707]
[4708]
[4709]
[4710]
[4711]
[4712]
[4713]
[4714]
[4715]
[4716]
[4717]
[4718]
[4719]
[4720]
[4721]
[4722]
[4723]
[4724]
[4725]
[4726]
[4727]
[4728]
[4729]
[4730]
[4731]
[4732]
[4733]
[4734]
[4735]
[4736]
[4737]
[4738]
[4739]
[4740]
[4741]
[4742]
[4743]
[4744]
[4745]
[4746]
[4747]
[4748]
[4749]
[4750]
[4751]
[4752]
[4753]
[4754]
[4755]
[4756]
[4757]
[4758]
[4759]
[4760]
[4761]
[4762]
[4763]
[4764]
[4765]
[4766]
[4767]
[4768]
[4769]
[4770]
[4771]
[4772]
[4773]
[4774]
[4775]
[4776]
[4777]
[4778]
[4779]
[4780]
[4781]
[4782]
[4783]
[4784]
[4785]
[4786]
[4787]
[4788]
[4789]
[4790]
[4791]
[4792]
[4793]
[4794]
[4795]
[4796]
[4797]
[4798]
[4799]
[4800]
[4801]
[4802]
[4803]
[4804]
[4805]
[4806]
[4807]
[4808]
[4809]
[4810]
[4811]
[4812]
[4813]
[4814]
[4815]
[4816]
[4817]
[4818]
[4819]
[4820]
[4821]
[4822]
[4823]
[4824]
[4825]
[4826]
[4827]
[4828]
[4829]
[4830]
[4831]
[4832]
[4833]
[4834]
[4835]
[4836]
[4837]
[4838]
[4839]
[4840]
[4841]
[4842]
[4843]
[4844]
[4845]
[4846]
[4847]
[4848]
[4849]
[4850]
[4851]
[4852]
[4853]
[4854]
[4855]
[4856]
[4857]
[4858]
[4859]
[4860]
[4861]
[4862]
[4863]
[4864]
[4865]
[4866]
[4867]
[4868]
[4869]
[4870]
[4871]
[4872]
[4873]
[4874]
[4875]
[4876]
[4877]
[4878]
[4879]
[4880]
[4881]
[4882]
[4883]
[4884]
[4885]
[4886]
[4887]
[4888]
[4889]
[4890]
[4891]
[4892]
[4893]
[4894]
[4895]
[4896]
[4897]
[4898]
[4899]
[4900]
[4901]
[4902]
[4903]
[4904]
[4905]
[4906]
[4907]
[4908]
[4909]
[4910]
[4911]
[4912]
[4913]
[4914]
[4915]
[4916]
[4917]
[4918]
[4919]
[4920]
[4921]
[4922]
[4923]
[4924]
[4925]
[4926]
[4927]
[4928]
[4929]
[4930]
[4931]
[4932]
[4933]
[4934]
[4935]
[4936]
[4937]
[4938]
[4939]
[4940]
[4941]
[4942]
[4943]
[4944]
[4945]
[4946]
[4947]
[4948]
[4949]
[4950]
[4951]
[4952]
[4953]
[4954]
[4955]
[4956]
[4957]
[4958]
[4959]
[4960]
[4961]
[4962]
[4963]
[4964]
[4965]
[4966]
[4967]
[4968]
[4969]
[4970]
[4971]
[4972]
[4973]
[4974]
[4975]
[4976]
[4977]
[4978]
[4979]
[4980]
[4981]
[4982]
[4983]
[4984]
[4985]
[4986]
[4987]
[4988]
[4989]
[4990]
[4991]
[4992]
[4993]
[4994]
[4995]
[4996]
[4997]
[4998]
[4999]
[5000]
[5001]
[5002]
[5003]
[5004]
[5005]
[5006]
[5007]
[5008]
[5009]
[5010]
[5011]
[5012]
[5013]
[5014]
[5015]
[5016]
[5017]
[5018]
[5019]
[5020]
[5021]
[5022]
[5023]
[5024]
[5025]
[5026]
[5027]
[5028]
[5029]
[5030]
[5031]
[5032]
[5033]
[5034]
[5035]
[5036]
[5037]
[5038]
[5039]
[5040]
[5041]
[5042]
[5043]
[5044]
[5045]
[5046]
[5047]
[5048]
[5049]
[5050]
[5051]
[5052]
[5053]
[5054]
[5055]
[5056]
[5057]
[5058]
[5059]
[5060]
[5061]
[5062]
[5063]
[5064]
[5065]
[5066]
[5067]
[5068]
[5069]
[5070]
[5071]
[5072]
[5073]
[5074]
[5075]
[5076]
[5077]
[5078]
[5079]
[5080]
[5081]
[5082]
[5083]
[5084]
[5085]
[5086]
[5087]
[5088]
[5089]
[5090]
[5091]
[5092]
[5093]
[5094]
[5095]
[5096]
[5097]
[5098]
[5099]
[5100]
[5101]
[5102]
[5103]
[5104]
[5105]
[5106]
[5107]
[5108]
[5109]
[5110]
[5111]
[5112]
[5113]
[5114]
[5115]
[5116]
[5117]
[5118]
[5119]
[5120]
[5121]
[5122]
[5123]
[5124]
[5125]
[5126]
[5127]
[5128]
[5129]
[5130]
[5131]
[5132]
[5133]
[5134]
[5135]
[5136]
[5137]
[5138]
[5139]
[5140]
[5141]
[5142]
[5143]
[5144]
[5145]
[5146]
[5147]
[5148]
[5149]
[5150]
[5151]
[5152]
[5153]
[5154]
[5155]
[5156]
[5157]
[5158]
[5159]
[5160]
[5161]
[5162]
[5163]
[5164]
[5165]
[5166]
[5167]
[5168]
[5169]
[5170]
[5171]
[5172]
[5173]
[5174]
[5175]
[5176]
[5177]
[5178]
[5179]
[5180]
[5181]
[5182]
[5183]
[5184]
[5185]
[5186]
[5187]
[5188]
[5189]
[5190]
[5191]
[5192]
[5193]
[5194]
[5195]
[5196]
[5197]
[5198]
[5199]
[5200]
[5201]
[5202]
[5203]
[5204]
[5205]
[5206]
[5207]
[5208]
[5209]
[5210]
[5211]
[5212]
[5213]
[5214]
[5215]
[5216]
[5217]
[5218]
[5219]
[5220]
[5221]
[5222]
[5223]
[5224]
[5225]
[5226]
[5227]
[5228]
[5229]
[5230]
[5231]
[5232]
[5233]
[5234]
[5235]
[5236]
[5237]
[5238]
[5239]
[5240]
[5241]
[5242]
[5243]
[5244]
[5245]
[5246]
[5247]
[5248]
[5249]
[5250]
[5251]
[5252]
[5253]
[5254]
[5255]
[5256]
[5257]
[5258]
[5259]
[5260]
[5261]
[5262]
[5263]
[5264]
[5265]
[5266]
[5267]
[5268]
[5269]
[5270]
[5271]
[5272]
[5273]
[5274]
[5275]
[5276]
[5277]
[5278]
[5279]
[5280]
[5281]
[5282]
[5283]
[5284]
[5285]
[5286]
[5287]
[5288]
[5289]
[5290]
[5291]
[5292]
[5293]
[5294]
[5295]
[5296]
[5297]
[5298]
[5299]
[5300]
[5301]
[5302]
[5303]
[5304]
[5305]
[5306]
[5307]
[5308]
[5309]
[5310]
[5311]
[5312]
[5313]
[5314]
[5315]
[5316]
[5317]
[5318]
[5319]
[5320]
[5321]
[5322]
[5323]
[5324]
[5325]
[5326]
[5327]
[5328]
[5329]
[5330]
[5331]
[5332]
[5333]
[5334]
[5335]
[5336]
[5337]
[5338]
[5339]
[5340]
[5341]
[5342]
[5343]
[5344]
[5345]
[5346]
[5347]
[5348]
[5349]
[5350]
[5351]
[5352]
[5353]
[5354]
[5355]
[5356]
[5357]
[5358]
[5359]
[5360]
[5361]
[5362]
[5363]
[5364]
[5365]
[5366]
[5367]
[5368]
[5369]
[5370]
[5371]
[5372]
[5373]
[5374]
[5375]
[5376]
[5377]
[5378]
[5379]
[5380]
[5381]
[5382]
[5383]
[5384]
[5385]
[5386]
[5387]
[5388]
[5389]
[5390]
[5391]
[5392]
[5393]
[5394]
[5395]
[5396]
[5397]
[5398]
[5399]
[5400]
[5401]
[5402]
[5403]
[5404]
[5405]
[5406]
[5407]
[5408]
[5409]
[5410]
[5411]
[5412]
[5413]
[5414]
[5415]
[5416]
[5417]
[5418]
[5419]
[5420]
[5421]
[5422]
[5423]
[5424]
[5425]
[5426]
[5427]
[5428]
[5429]
[5430]
[5431]
[5432]
[5433]
[5434]
[5435]
[5436]
[5437]
[5438]
[5439]
[5440]
[5441]
[5442]
[5443]
[5444]
[5445]
[5446]
[5447]
[5448]
[5449]
[5450]
[5451]
[5452]
[5453]
[5454]
[5455]
[5456]
[5457]
[5458]
[5459]
[5460]
[5461]
[5462]
[5463]
[5464]
[5465]
[5466]
[5467]
[5468]
[5469]
[5470]
[5471]
[5472]
[5473]
[5474]
[5475]
[5476]
[5477]
[5478]
[5479]
[5480]
[5481]
[5482]
[5483]
[5484]
[5485]
[5486]
[5487]
[5488]
[5489]
[5490]
[5491]
[5492]
[5493]
[5494]
[5495]
[5496]
[5497]
[5498]
[5499]
[5500]
[5501]
[5502]
[5503]
[5504]
[5505]
[5506]
[5507]
[5508]
[5509]
[5510]
[5511]
[5512]
[5513]
[5514]
[5515]
[5516]
[5517]
[5518]
[5519]
[5520]
[5521]
[5522]
[5523]
[5524]
[5525]
[5526]
[5527]
[5528]
[5529]
[5530]
[5531]
[5532]
[5533]
[5534]
[5535]
[5536]
[5537]
[5538]
[5539]
[5540]
[5541]
[5542]
[5543]
[5544]
[5545]
[5546]
[5547]
[5548]
[5549]
[5550]
[5551]
[5552]
[5553]
[5554]
[5555]
[5556]
[5557]
[5558]
[5559]
[5560]
[5561]
[5562]
[5563]
[5564]
[5565]
[5566]
[5567]
[5568]
[5569]
[5570]
[5571]
[5572]
[5573]
[5574]
[5575]
[5576]
[5577]
[5578]
[5579]
[5580]
[5581]
[5582]
[5583]
[5584]
[5585]
[5586]
[5587]
[5588]
[5589]
[5590]
[5591]
[5592]
[5593]
[5594]
[5595]
[5596]
[5597]
[5598]
[5599]
[5600]
[5601]
[5602]
[5603]
[5604]
[5605]
[5606]
[5607]
[5608]
[5609]
[5610]
[5611]
[5612]
[5613]
[5614]
[5615]
[5616]
[5617]
[5618]
[5619]
[5620]
[5621]
[5622]
[5623]
[5624]
[5625]
[5626]
[5627]
[5628]
[5629]
[5630]
[5631]
[5632]
[5633]
[5634]
[5635]
[5636]
[5637]
[5638]
[5639]
[5640]
[5641]
[5642]
[5643]
[5644]
[5645]
[5646]
[5647]
[5648]
[5649]
[5650]
[5651]
[5652]
[5653]
[5654]
[5655]
[5656]
[5657]
[5658]
[5659]
[5660]
[5661]
[5662]
[5663]
[5664]
[5665]
[5666]
[5667]
[5668]
[5669]
[5670]
[5671]
[5672]
[5673]
[5674]
[5675]
[5676]
[5677]
[5678]
[5679]
[5680]
[5681]
[5682]
[5683]
[5684]
[5685]
[5686]
[5687]
[5688]
[5689]
[5690]
[5691]
[5692]
[5693]
[5694]
[5695]
[5696]
[5697]
[5698]
[5699]
[5700]
[5701]
[5702]
[5703]
[5704]
[5705]
[5706]
[5707]
[5708]
[5709]
[5710]
[5711]
[5712]
[5713]
[5714]
[5715]
[5716]
[5717]
[5718]
[5719]
[5720]
[5721]
[5722]
[5723]
[5724]
[5725]
[5726]
[5727]
[5728]
[5729]
[5730]
[5731]
[5732]
[5733]
[5734]
[5735]
[5736]
[5737]
[5738]
[5739]
[5740]
[5741]
[5742]
[5743]
[5744]
[5745]
[5746]
[5747]
[5748]
[5749]
[5750]
[5751]
[5752]
[5753]
[5754]
[5755]
[5756]
[5757]
[5758]
[5759]
[5760]
[5761]
[5762]
[5763]
[5764]
[5765]
[5766]
[5767]
[5768]
[5769]
[5770]
[5771]
[5772]
[5773]
[5774]
[5775]
[5776]
[5777]
[5778]
[5779]
[5780]
[5781]
[5782]
[5783]
[5784]
[5785]
[5786]
[5787]
[5788]
[5789]
[5790]
[5791]
[5792]
[5793]
[5794]
[5795]
[5796]
[5797]
[5798]
[5799]
[5800]
[5801]
[5802]
[5803]
[5804]
[5805]
[5806]
[5807]
[5808]
[5809]
[5810]
[5811]
[5812]
[5813]
[5814]
[5815]
[5816]
[5817]
[5818]
[5819]
[5820]
[5821]
[5822]
[5823]
[5824]
[5825]
[5826]
[5827]
[5828]
[5829]
[5830]
[5831]
[5832]
[5833]
[5834]
[5835]
[5836]
[5837]
[5838]
[5839]
[5840]
[5841]
[5842]
[5843]
[5844]
[5845]
[5846]
[5847]
[5848]
[5849]
[5850]
[5851]
[5852]
[5853]
[5854]
[5855]
[5856]
[5857]
[5858]
[5859]
[5860]
[5861]
[5862]
[5863]
[5864]
[5865]
[5866]
[5867]
[5868]
[5869]
[5870]
[5871]
[5872]
[5873]
[5874]
[5875]
[5876]
[5877]
[5878]
[5879]
[5880]
[5881]
[5882]
[5883]
[5884]
[5885]
[5886]
[5887]
[5888]
[5889]
[5890]
[5891]
[5892]
[5893]
[5894]
[5895]
[5896]
[5897]
[5898]
[5899]
[5900]
[5901]
[5902]
[5903]
[5904]
[5905]
[5906]
[5907]
[5908]
[5909]
[5910]
[5911]
[5912]
[5913]
[5914]
[5915]
[5916]
[5917]
[5918]
[5919]
[5920]
[5921]
[5922]
[5923]
[5924]
[5925]
[5926]
[5927]
[5928]
[5929]
[5930]
[5931]
[5932]
[5933]
[5934]
[5935]
[5936]
[5937]
[5938]
[5939]
[5940]
[5941]
[5942]
[5943]
[5944]
[5945]
[5946]
[5947]
[5948]
[5949]
[5950]
[5951]
[5952]
[5953]
[5954]
[5955]
[5956]
[5957]
[5958]
[5959]
[5960]
[5961]
[5962]
[5963]
[5964]
[5965]
[5966]
[5967]
[5968]
[5969]
[5970]
[5971]
[5972]
[5973]
[5974]
[5975]
[5976]
[5977]
[5978]
[5979]
[5980]
[5981]
[5982]
[5983]
[5984]
[5985]
[5986]
[5987]
[5988]
[5989]
[5990]
[5991]
[5992]
[5993]
[5994]
[5995]
[5996]
[5997]
[5998]
[5999]
[6000]
[6001]
[6002]
[6003]
[6004]
[6005]
[6006]
[6007]
[6008]
[6009]
[6010]
[6011]
[6012]
[6013]
[6014]
[6015]
[6016]
[6017]
[6018]
[6019]
[6020]
[6021]
[6022]
[6023]
[6024]
[6025]
[6026]
[6027]
[6028]
[6029]
[6030]
[6031]
[6032]
[6033]
[6034]
[6035]
[6036]
[6037]
[6038]
[6039]
[6040]
[6041]
[6042]
[6043]
[6044]
[6045]
[6046]
[6047]
[6048]
[6049]
[6050]
[6051]
[6052]
[6053]
[6054]
[6055]
[6056]
[6057]
[6058]
[6059]
[6060]
[6061]
[6062]
[6063]
[6064]
[6065]
[6066]
[6067]
[6068]
[6069]
[6070]
[6071]
[6072]
[6073]
[6074]
[6075]
[6076]
[6077]
[6078]
[6079]
[6080]
[6081]
[6082]
[6083]
[6084]
[6085]
[6086]
[6087]
[6088]
[6089]
[6090]
[6091]
[6092]
[6093]
[6094]
[6095]
[6096]
[6097]
[6098]
[6099]
[6100]
[6101]
[6102]
[6103]
[6104]
[6105]
[6106]
[6107]
[6108]
[6109]
[6110]
[6111]
[6112]
[6113]
[6114]
[6115]
[6116]
[6117]
[6118]
[6119]
[6120]
[6121]
[6122]
[6123]
[6124]
[6125]
[6126]
[6127]
[6128]
[6129]
[6130]
[6131]
[6132]
[6133]
[6134]
[6135]
[6136]
[6137]
[6138]
[6139]
[6140]
[6141]
[6142]
[6143]
[6144]
[6145]
[6146]
[6147]
[6148]
[6149]
[6150]
[6151]
[6152]
[6153]
[6154]
[6155]
[6156]
[6157]
[6158]
[6159]
[6160]
[6161]
[6162]
[6163]
[6164]
[6165]
[6166]
[6167]
[6168]
[6169]
[6170]
[6171]
[6172]
[6173]
[6174]
[6175]
[6176]
[6177]
[6178]
[6179]
[6180]
[6181]
[6182]
[6183]
[6184]
[6185]
[6186]
[6187]
[6188]
[6189]
[6190]
[6191]
[6192]
[6193]
[6194]
[6195]
[6196]
[6197]
[6198]
[6199]
[6200]
[6201]
[6202]
[6203]
[6204]
[6205]
[6206]
[6207]
[6208]
[6209]
[6210]
[6211]
[6212]
[6213]
[6214]
[6215]
[6216]
[6217]
[6218]
[6219]
[6220]
[6221]
[6222]
[6223]
[6224]
[6225]
[6226]
[6227]
[6228]
[6229]
[6230]
[6231]
[6232]
[6233]
[6234]
[6235]
[6236]
[6237]
[6238]
[6239]
[6240]
[6241]
[6242]
[6243]
[6244]
[6245]
[6246]
[6247]
[6248]
[6249]
[6250]
[6251]
[6252]
[6253]
[6254]
[6255]
[6256]
[6257]
[6258]
[6259]
[6260]
[6261]
[6262]
[6263]
[6264]
[6265]
[6266]
[6267]
[6268]
[6269]
[6270]
[6271]
[6272]
[6273]
[6274]
[6275]
[6276]
[6277]
[6278]
[6279]
[6280]
[6281]
[6282]
[6283]
[6284]
[6285]
[6286]
[6287]
[6288]
[6289]
[6290]
[6291]
[6292]
[6293]
[6294]
[6295]
[6296]
[6297]
[6298]
[6299]
[6300]
[6301]
[6302]
[6303]
[6304]
[6305]
[6306]
[6307]
[6308]
[6309]
[6310]
[6311]
[6312]
[6313]
[6314]
[6315]
[6316]
[6317]
[6318]
[6319]
[6320]
[6321]
[6322]
[6323]
[6324]
[6325]
[6326]
[6327]
[6328]
[6329]
[6330]
[6331]
[6332]
[6333]
[6334]
[6335]
[6336]
[6337]
[6338]
[6339]
[6340]
[6341]
[6342]
[6343]
[6344]
[6345]
[6346]
[6347]
[6348]
[6349]
[6350]
[6351]
[6352]
[6353]
[6354]
[6355]
[6356]
[6357]
[6358]
[6359]
[6360]
[6361]
[6362]
[6363]
[6364]
[6365]
[6366]
[6367]
[6368]
[6369]
[6370]
[6371]
[6372]
[6373]
[6374]
[6375]
[6376]
[6377]
[6378]
[6379]
[6380]
[6381]
[6382]
[6383]
[6384]
[6385]
[6386]
[6387]
[6388]
[6389]
[6390]
[6391]
[6392]
[6393]
[6394]
[6395]
[6396]
[6397]
[6398]
[6399]
[6400]
[6401]
[6402]
[6403]
[6404]
[6405]
[6406]
[6407]
[6408]
[6409]
[6410]
[6411]
[6412]
[6413]
[6414]
[6415]
[6416]
[6417]
[6418]
[6419]
[6420]
[6421]
[6422]
[6423]
[6424]
[6425]
[6426]
[6427]
[6428]
[6429]
[6430]
[6431]
[6432]
[6433]
[6434]
[6435]
[6436]
[6437]
[6438]
[6439]
[6440]
[6441]
[6442]
[6443]
[6444]
[6445]
[6446]
[6447]
[6448]
[6449]
[6450]
[6451]
[6452]
[6453]
[6454]
[6455]
[6456]
[6457]
[6458]
[6459]
[6460]
[6461]
[6462]
[6463]
[6464]
[6465]
[6466]
[6467]
[6468]
[6469]
[6470]
[6471]
[6472]
[6473]
[6474]
[6475]
[6476]
[6477]
[6478]
[6479]
[6480]
[6481]
[6482]
[6483]
[6484]
[6485]
[6486]
[6487]
[6488]
[6489]
[6490]
[6491]
[6492]
[6493]
[6494]
[6495]
[6496]
[6497]
[6498]
[6499]
[6500]
[6501]
[6502]
[6503]
[6504]
[6505]
[6506]
[6507]
[6508]
[6509]
[6510]
[6511]
[6512]
[6513]
[6514]
[6515]
[6516]
[6517]
[6518]
[6519]
[6520]
[6521]
[6522]
[6523]
[6524]
[6525]
[6526]
[6527]
[6528]
[6529]
[6530]
[6531]
[6532]
[6533]
[6534]
[6535]
[6536]
[6537]
[6538]
[6539]
[6540]
[6541]
[6542]
[6543]
[6544]
[6545]
[6546]
[6547]
[6548]
[6549]
[6550]
[6551]
[6552]
[6553]
[6554]
[6555]
[6556]
[6557]
[6558]
[6559]
[6560]
[6561]
[6562]
[6563]
[6564]
[6565]
[6566]
[6567]
[6568]
[6569]
[6570]
[6571]
[6572]
[6573]
[6574]
[6575]
[6576]
[6577]
[6578]
[6579]
[6580]
[6581]
[6582]
[6583]
[6584]
[6585]
[6586]
[6587]
[6588]
[6589]
[6590]
[6591]
[6592]
[6593]
[6594]
[6595]
[6596]
[6597]
[6598]
[6599]
[6600]
[6601]
[6602]
[6603]
[6604]
[6605]
[6606]
[6607]
[6608]
[6609]
[6610]
[6611]
[6612]
[6613]
[6614]
[6615]
[6616]
[6617]
[6618]
[6619]
[6620]
[6621]
[6622]
[6623]
[6624]
[6625]
[6626]
[6627]
[6628]
[6629]
[6630]
[6631]
[6632]
[6633]
[6634]
[6635]
[6636]
[6637]
[6638]
[6639]
[6640]
[6641]
[6642]
[6643]
[6644]
[6645]
[6646]
[6647]
[6648]
[6649]
[6650]
[6651]
[6652]
[6653]
[6654]
[6655]
[6656]
[6657]
[6658]
[6659]
[6660]
[6661]
[6662]
[6663]
[6664]
[6665]
[6666]
[6667]
[6668]
[6669]
[6670]
[6671]
[6672]
[6673]
[6674]
[6675]
[6676]
[6677]
[6678]
[6679]
[6680]
[6681]
[6682]
[6683]
[6684]
[6685]
[6686]
[6687]
[6688]
[6689]
[6690]
[6691]
[6692]
[6693]
[6694]
[6695]
[6696]
[6697]
[6698]
[6699]
[6700]
[6701]
[6702]
[6703]
[6704]
[6705]
[6706]
[6707]
[6708]
[6709]
[6710]
[6711]
[6712]
[6713]
[6714]
[6715]
[6716]
[6717]
[6718]
[6719]
[6720]
[6721]
[6722]
[6723]
[6724]
[6725]
[6726]
[6727]
[6728]
[6729]
[6730]
[6731]
[6732]
[6733]
[6734]
[6735]
[6736]
[6737]
[6738]
[6739]
[6740]
[6741]
[6742]
[6743]
[6744]
[6745]
[6746]
[6747]
[6748]
[6749]
[6750]
[6751]
[6752]
[6753]
[6754]
[6755]
[6756]
[6757]
[6758]
[6759]
[6760]
[6761]
[6762]
[6763]
[6764]
[6765]
[6766]
[6767]
[6768]
[6769]
[6770]
[6771]
[6772]
[6773]
[6774]
[6775]
[6776]
[6777]
[6778]
[6779]
[6780]
[6781]
[6782]
[6783]
[6784]
[6785]
[6786]
[6787]
[6788]
[6789]
[6790]
[6791]
[6792]
[6793]
[6794]
[6795]
[6796]
[6797]
[6798]
[6799]
[6800]
[6801]
[6802]
[6803]
[6804]
[6805]
[6806]
[6807]
[6808]
[6809]
[6810]
[6811]
[6812]
[6813]
[6814]
[6815]
[6816]
[6817]
[6818]
[6819]
[6820]
[6821]
[6822]
[6823]
[6824]
[6825]
[6826]
[6827]
[6828]
[6829]
[6830]
[6831]
[6832]
[6833]
[6834]
[6835]
[6836]
[6837]
[6838]
[6839]
[6840]
[6841]
[6842]
[6843]
[6844]
[6845]
[6846]
[6847]
[6848]
[6849]
[6850]
<!DOCTYPE html>
<!-- WASDOC AXP-2.0.0 (CGILIB AXP-1.9.9) -->
<!-- wasDOC Copyright (C) 2019,2020 Mark G.Daniel - Apache-2.0 licenced -->
<!--  3-NOV-2021 02:57 -->
<noscript>NOTE: SOME FUNCTIONALITY EMPLOYS JAVASCRIPT</noscript>
<div id="erreport1" style="display:none;"></div>
<script>
function errorReport(string) {
   for (var cnt = 1; cnt <= 2; cnt++) {
      var err = document.getElementById('erreport'+cnt);
      err.style.display = 'block';
      err.innerHTML += string;
   }
}
</script>
<style type="text/css">
html { font-family: arial, verdana, sans-serif; font-size:12pt; margin:1em; }
h1 { font-size:124%; font-style:bold;
     margin-top:1em; margin-bottom:0.5em; }
h2 { font-size:120%; font-style:bold;
     margin-top:1.1em; margin-bottom:0.4em; }
h3 { font-size:116%; font-style:bold;
     margin-top:1.0em; margin-bottom:0.3em; }
h4 { font-size:112%; font-style:bold;
     margin-top:1.1em; margin-bottom:0.3em; }
h5 { font-size:112%; font-style:bold; 
     margin-top:1.1em; margin-bottom:0.3em; }
h6 { font-size:112%; font-style:bold; padding:0; margin:0; }

h1 .text { text-decoration:underline; }
h1 .numb { padding-right:0.8em; }
h1 .numb:empty { display:none; padding-right:0; }
h2 .numb { padding-right:0.8em; }
h2 .numb:empty { display:none; padding-right:0; }
h3 .numb { padding-right:0.8em; }
h3 .numb:empty { display:none; padding-right:0; }
h4 .numb { padding-right:0.8em; }
h4 .numb:empty { display:none; padding-right:0; }
h5 .numb { display:none; padding-right:0; }
h6 .numb { display:none; padding-right:0; }

kbd { font-family:monospace; }

noscript { font-size:1.2em; }

p { line-height:1.1em; margin-top:1em; margin-bottom:1em; }

.chunk { font-size:130%; text-decoration:underline; }
.head {}
.high {}
.bold { font-weight:bold; }
.center { text-align:center; }
.italic { font-style:italic; }
.left { text-align:left; }
.nowrap { white-space:nowrap; }
.prewrap { white-space:pre; }
.right { text-align:right; }
.strike { text-decoration:line-through; }
.under { text-decoration:underline; }

.backlight { background-color:#f2f2f2; }
.display0 { display:none; }

img { max-width:100%; }
.imglink { }

.link { }
.blank { }

.list { margin-bottom:1em; }
.list li { margin-top:0.5em; }
.list0 li { margin-top:0; }
.item {}

.tabl { border-collapse:collapse; text-align:left; margin:0.4em 2em 0.5em 2em; }
.tabu { border-collapse:collapse; text-align:right; margin:0.4em 2em 0.5em 2em; }

.tabr { vertical-align:top; }
.tabh { padding:0.2em 0 0 2em; margin:0; }
.tabd { padding:0.1em 0 0 2em; margin:0; }
.tabh:first-of-type, td:first-of-type { padding-left:0; }

.tabu .tabh,
.tabu .tabd { border:1px solid gray; padding:0.2em 0.3em 0.2em 0.3em; }
.tab0 { border:none; visibility:hidden; max-width:1em; 
        white-space:nowrap; overflow:hidden; }

.tabauto { margin-left:auto; margin-right:auto; }

.tabr:empty { height:0.2em; }
.tabu .tabh:empty, .tabu .tabd:empty { border:none; visibility:hidden; }

.error { font-size:110%; color:black; background-color:yellow;
         font-family:sans-serif; font-weight:bold; font-style:normal;
         width:95%; border:solid 1px gray; padding:0.5em 1em 0.5em 1em; }
.error::before { content:'\026a0\00a0'; }
.image { }
.page { width:98%; border:1px dashed gray; margin:1.5em 0 1.8em 0; }
.epage { width:98%; border:1px dashed black; margin:1.5em 0 1.8em 0; }
.monosp { font-family:monospace; }
.ppage { display:none; }
.simple { list-style-type:none; }
.valtop { vertical-align:top; }
.valmid { vertical-align:middle; }
.valbot { vertical-align:bottom; }

.code { border-style:solid; border-width:0 0 0 1px; padding-left:1em;
        font-family:monospace; white-space:pre; }
.block { }
.blockof { margin:0.4em 2em 0.5em 2em; }
.example { border-style:dashed; border-width:0 0 0 1px; padding-left:1em;
           margin-top:0.5em; margin-bottom:0.5em; white-space:pre; }
.indent { margin-left:2em; margin-right:2em; }
.noindent { margin-left:0; margin-right:0; }
.inblock { display:inline-block; }
.mono { white-space:pre; font-family:monospace; }
.note { margin:0.4em 2em 0.5em 2em; page-break-inside:avoid; }
.note h5 { margin-top:0 }
.note_hr { width:80%; border:1px solid gray; }
.prop { padding-left:1em; margin-top:0.5em; margin-bottom:0.5em; }
.quote { border-style:dashed; border-width:0 0 0 1px; padding-left:1em;
         margin-top:0.5em; margin-bottom:0.5em; }
.this { display:none; }

a:link,a:visited { color:black; text-decoration:none; }
a:hover,a:active { text-decoration:underline; }
a:focus { outline:0; } 

:target:before { content:''; display:block; height:0.1em; margin:-0.1em; }
a.link:link, a.link:visited,a.link:active 
{ color:midnightBlue; text-decoration:underline; text-decoration-style:solid; }

.TOC1cols1 { width:80%; max-width:80%; }
.TOC1cols2 { column-count:2; width:80%; max-width:80%; }
.TOC1cols3 { column-count:3; max-width:90%; max-width:90%; }
.TOC1cols4 { column-count:4; max-width:100%; max-width:100%; }
.TOC1table { margin-left:2em; white-space:nowrap; break-inside:auto; }
.TOC1table tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; }
.TOC1table td+td { padding:0 0 0 0.5em; }
.TOC1table .numb { width:3em; max-width:3em; }
.TOC1table .sepr { width:5em; max-width:6em; overflow:hidden; }
.TOC1table .majr { font-weight:bold; }
.TOC1table .text { white-space:normal; }

/* These are due to Firefox (at least <= 76) recalcitrant multi-column handling.
   Web search "Split table into css columns, issue in Firefox" (stackoverflow).
   "Good grief, Charlie Brown!" */
 
.TOC1cols2 table,
.TOC1cols2 tbody,
.TOC1cols2 tr,
.TOC1cols3 table,
.TOC1cols3 tbody,
.TOC1cols3 tr,
.TOC1cols4 table,
.TOC1cols4 tbody,
.TOC1cols4 tr { display:block; padding:0; }

.TOC2cols1 { width:60%; max-width:60%; }
.TOC2cols2 { column-count:2; width:70%; max-width:70%; }
.TOC2cols3 { column-count:3; width:80%; max-width:80%; }
.TOC2cols4 { column-count:4; width:90%; max-width:90%; }
.TOC2table { margin-left:2em; white-space:nowrap; break-inside:auto; }
.TOC2table tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; }
.TOC2table .numb { font-weight:bold; padding-right:0.5em; }
.TOC2table .text { width:100%; white-space:normal; }

/* see "recalcitrant" above */
.TOC2cols2 table,
.TOC2cols2 tbody,
.TOC2cols2 tr,
.TOC2cols3 table,
.TOC2cols3 tbody,
.TOC2cols3 tr,
.TOC2cols4 table,
.TOC2cols4 tbody,
.TOC2cols4 tr { display:block; padding:0; }

.NAVtable { margin:0.1em 0 0 2em; }
.NAVtable td { font-size:110%; font-weight:bold; padding:0; margin:0; }
.NAVtable a { padding:0 0.5em 0 0.5em; text-decoration:none; }

.IDXcols1 { width:80%; max-width:80%; }
.IDXcols2 { column-count:2; width:90%; max-width:90%; }
.IDXcols3 { column-count:3; width:95%; max-width:95%;  }
.IDXcols4 { column-count:4; width:100%; max-width:100%;  }
.IDXtable { margin:1em 0 1em 2em; white-space:nowrap; break-inside:auto; }
.IDXtable tr { vertical-align:top; text-align:left; break-inside:avoid; break-after:auto; }
.IDXtable .alpha { font-weight:bold; min-width:2em; }
.IDXtable .text  { width:100%; white-space:normal; }
.IDXtable .para:before { content:'\00b6\00a0'; }

/* see "recalcitrant" above */
.IDXcols2 table,
.IDXcols2 tbody,
.IDXcols2 tr,
.IDXcols3 table,
.IDXcols3 tbody,
.IDXcols3 tr,
.IDXcols4 table,
.IDXcols4 tbody,
.IDXcols4 tr { display:block; padding:0; }

.insight { background-color:cyan; font-family:monospace;
           padding:0 0.2em 0 0.2em; margin:0 0.2em 0 0.2em;
           font-size:100%; font-style:normal; font-weight:normal;
           text-decoration:none; }

.wasdoc { font-family: "Lucida Console", Monaco, monospace; 
          letter-spacing:-0.07em; }

@media screen { .blank::after { content:"\2924"; } 
                .print { display:none; }
}

@media print {
   table { page-break-inside:avoid; }
   .noprint { display:none; }
   .page { border:none; page-break-after: always; }
   .epage { display:none; }
   .ppage { page-break-after:always; }
   .NAVtable { display:none; }
   .NAVprint { display:block!important; }
}

@page { margin:2cm 1cm 2cm 1cm;  }
</style>
<!-- source:0000_SCRIPTING.WASDOC -->

<style type="text/css">._smiley::after { font-size:150%; vertical-align:middle; content:'\263a' }</style>
<style type="text/css">._frowny::after { font-size:150%; vertical-align:middle; content:'\2639' }</style>

<a id="0." href="#"></a>
<a id="0.0.0.0.1" href="#"></a>
<a id="0.wasdscriptingenvironment" href="#"></a>
<a id="wasdscriptingenvironment" href="#"></a>
<h1 class="head" style="font-size:140%;"><span class="text">WASD Scripting Environment</span></h1>

<p> For version 12.0 release of WASD VMS Web Services.

<p> Published November 2021

<p> Document generated using <span class="high wasdoc">wasDOC</span> version 2.0.0

<a id="0.0.0.0.2" href="#"></a>
<a id="0.abstract" href="#"></a>
<a id="abstract" href="#"></a>
<h5 class="head"><span class="text">Abstract</span></h5>

<p> This document introduces the WASD Web Services package and provides detailed
installation, update and configuration instructions.

<p> For installation and update details see
<a class="link blank" target="_blank" href="../install/">WASD Web Services - Installation</a>

<p> For detailed configuration information see
<a class="link blank" target="_blank" href="../config/">WASD Web Services - Configuration</a>

<p> For the more significant features and facilities available see
<a class="link blank" target="_blank" href="../features/">WASD Web Services - Features</a>

<p> And for a description of WASD Web document, SSI and directory listing
behaviours and options, <a class="link blank" target="_blank" href="../env/">WASD Web Services - Environment</a>

<a id="0.0.0.0.3" href="#"></a>
<a id="0.onlinesearch" href="#"></a>
<a id="onlinesearch" href="#"></a>
<h5 class="head"><span class="text">Online Search</span></h5>
<p>
<table class="tabl noindent" style="border:1px #808080 solid;background-color:#eeeeee;margin-bottom:1.5em;">
<tr class="tabr">
<td class="tabd" style="padding:0.5em;"><form action="/cgi-bin/query/wasd_root/wasdoc/config/*.html" target="_top">
<input type="submit" value="Search for:">&nbsp;
<input type="text" name="search" size="20">&nbsp;
<input type="reset" value="Reset">
</form>
</table>

<p> <span class="high bold">WASD VMS Web Services &ndash; Copyright &copy; 1996-2021 Mark G. Daniel</span>

<a id="0.0.0.0.3.1" href="#"></a>
<a id="0.apachelicenseversion20" href="#"></a>
<a id="apachelicenseversion20" href="#"></a>
<h6 class="head display0"><span class="text">Apache License, Version 2.0</span></h6>
<a id="0.0.0.0.3.2" href="#"></a>
<a id="0.license" href="#"></a>
<a id="license" href="#"></a>
<h6 class="head display0"><span class="text">License</span></h6>
<p> Licensed under the <span class="high bold">Apache License</span>, Version 2.0 (the &quot;License&quot;);
<div class="blockof quote" style="font-size:0.9em;width:49em;margin:-0.5em 0 0 1em;">you may not use this software except in compliance with the License.
You may obtain a copy of the License at
<p> <a class="link blank" target="_blank" style="margin-left:1em;" href="https://www.apache.org/licenses/LICENSE-2.0">https://www.apache.org/licenses/LICENSE-2.0</a>
<p> Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</div>

<p> <a class="link" href="mailto:Mark.Daniel@wasd.vsm.com.au">Mark.Daniel@wasd.vsm.com.au</a>
<br> <span class="high bold italic">A pox on the houses of all spamers.  Make that two poxes.</span>

<p> All copyright and trademarks within this document belong to their rightful
owners.  See <a class="link" href="#13.attributionandacknowledgement">13. Attribution and Acknowledgement</a>.


<p> This is a static (file), single document.
<br> Alternative <a class="link" href="/wasd_root/wasdoc/scripting/scripting.html">multi-part</a> static and
<a class="link" href="/cgi-bin/wasdoc/wasd_root/wasdoc/scripting/">dynamic</a> documents.

<br> Links followed by &#10532; open in a new page.

<a id="0.0.0.0.4.2" href="#"></a>
<a id="0.tableofcontent" href="#"></a>
<a id="tableofcontent" href="#"></a>
<h1 class="head" style="font-size:120%;"><span class="text">Table of Content</span></h1>


<div class="TOC1cols2">
<table class="TOC1table">
<tr><td class="sepr"><a href="#1.introduction">1.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#1.introduction">Introduction</a>
<tr><td class="sepr"><a href="#1.1.scriptingaccounts">1.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.1.scriptingaccounts">Scripting Accounts</a>
<tr><td class="sepr"><a href="#1.2.scriptingprocesses">1.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.scriptingprocesses">Scripting Processes</a>
<tr><td class="sepr"><a href="#1.2.1.processmanagement">1.2.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.1.processmanagement">Process Management</a>
<tr><td class="sepr"><a href="#1.2.2.processnomenclature">1.2.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.2.processnomenclature">Process Nomenclature</a>
<tr><td class="sepr"><a href="#1.2.3.processscripting">1.2.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.3.processscripting">Process Scripting</a>
<tr><td class="sepr"><a href="#1.2.3.1.personascripting">1.2.3.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.3.1.personascripting">Persona Scripting</a>
<tr><td class="sepr"><a href="#1.2.3.2.restrictingpersonascripting">1.2.3.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.3.2.restrictingpersonascripting">Restricting Persona Scripting</a>
<tr><td class="sepr"><a href="#1.2.3.3.processpriorities">1.2.3.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.3.3.processpriorities">Process Priorities</a>
<tr><td class="sepr"><a href="#1.2.4.scriptprocessdefault">1.2.4</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.4.scriptprocessdefault">Script Process Default</a>
<tr><td class="sepr"><a href="#1.2.5.scriptprocessparsetype">1.2.5</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.5.scriptprocessparsetype">Script Process Parse Type</a>
<tr><td class="sepr"><a href="#1.2.6.scriptprocessrundown">1.2.6</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.6.scriptprocessrundown">Script Process Run-Down</a>
<tr><td class="sepr"><a href="#1.2.7.clientrecalcitrance">1.2.7</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.2.7.clientrecalcitrance">Client Recalcitrance</a>
<tr><td class="sepr"><a href="#1.3.scriptproctor">1.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.3.scriptproctor">Script Proctor</a>
<tr><td class="sepr"><a href="#1.4.cachingscriptoutput">1.4</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.4.cachingscriptoutput">Caching Script Output</a>
<tr><td class="sepr"><a href="#1.5.enablingascript">1.5</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.5.enablingascript">Enabling A Script</a>
<tr><td class="sepr"><a href="#1.6.scriptmapping">1.6</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.6.scriptmapping">Script Mapping</a>
<tr><td class="sepr"><a href="#1.7.scriptruntime">1.7</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.7.scriptruntime">Script Run-Time</a>
<tr><td class="sepr"><a href="#1.8.unixsyntax">1.8</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.8.unixsyntax">Unix Syntax</a>
<tr><td class="sepr"><a href="#1.9.scriptinglogicals">1.9</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.9.scriptinglogicals">Scripting Logicals</a>
<tr><td class="sepr"><a href="#1.10.scriptingscratchspace">1.10</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.10.scriptingscratchspace">Scripting Scratch Space</a>
<tr><td class="sepr"><a href="#1.11.dclprocessingofrequests">1.11</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.11.dclprocessingofrequests">DCL Processing of Requests</a>
<tr><td class="sepr"><a href="#1.12.scriptingfunctionlibrary">1.12</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.12.scriptingfunctionlibrary">Scripting Function Library</a>
<tr><td class="sepr"><a href="#1.13.scriptrequestedservergeneratederrorresponses">1.13</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#1.13.scriptrequestedservergeneratederrorresponses">Script-Requested, Server-Generated Error Responses</a>
<tr><td class="sepr"><a href="#2.cgi">2.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#2.cgi">CGI</a>
<tr><td class="sepr"><a href="#2.1.cgienvironmentvariables">2.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#2.1.cgienvironmentvariables">CGI Environment Variables</a>
<tr><td class="sepr"><a href="#2.2.scriptoutput">2.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#2.2.scriptoutput">Script Output</a>
<tr><td class="sepr"><a href="#2.2.1.cgicompliantoutput">2.2.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#2.2.1.cgicompliantoutput">CGI Compliant Output</a>
<tr><td class="sepr"><a href="#2.2.2.nonparsedheaderoutput">2.2.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#2.2.2.nonparsedheaderoutput">Non-Parsed-Header Output</a>
<tr><td class="sepr"><a href="#2.2.3.bulkcontentoutput">2.2.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#2.2.3.bulkcontentoutput">Bulk Content Output</a>
<tr><td class="sepr"><a href="#2.3.rawhttpinputpostprocessing">2.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#2.3.rawhttpinputpostprocessing">Raw HTTP Input (POST Processing)</a>
<tr><td class="sepr"><a href="#2.4.cgifunctionlibrary">2.4</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#2.4.cgifunctionlibrary">CGI Function Library</a>
<tr><td class="sepr"><a href="#2.5.cgiutlutility">2.5</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#2.5.cgiutlutility">CGIUTL Utility</a>
<tr><td class="sepr"><a href="#3.cgiplus">3.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#3.cgiplus">CGIplus</a>
<tr><td class="sepr"><a href="#3.1.cgiplusprogramming">3.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#3.1.cgiplusprogramming">CGIplus Programming</a>
<tr><td class="sepr"><a href="#3.2.codeexamples">3.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#3.2.codeexamples">Code Examples</a>
<tr><td class="sepr"><a href="#3.3.otherconsiderations">3.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#3.3.otherconsiderations">Other Considerations</a>
<tr><td class="sepr"><a href="#4.runtimeenvironments">4.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#4.runtimeenvironments">Run-Time Environments</a>
<tr><td class="sepr"><a href="#4.1.rteprogramming">4.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#4.1.rteprogramming">RTE Programming</a>
<tr><td class="sepr"><a href="#4.2.serverconfiguration">4.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#4.2.serverconfiguration">Server Configuration</a>
<tr><td class="sepr"><a href="#5.websocket">5.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#5.websocket">WebSocket</a>
<tr><td class="sepr"><a href="#5.1.multiclientwebsocketapplications">5.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.1.multiclientwebsocketapplications">Multi-Client WebSocket Applications</a>
<tr><td class="sepr"><a href="#5.2.websocketapplication">5.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.2.websocketapplication">WebSocket Application</a>
<tr><td class="sepr"><a href="#5.3.websocketlibrary">5.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.3.websocketlibrary">WebSocket Library</a>
<tr><td class="sepr"><a href="#5.4.websocketapplicationexamples">5.4</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.4.websocketapplicationexamples">WebSocket Application Examples</a>
<tr><td class="sepr"><a href="#5.4.1.chat">5.4.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.4.1.chat">Chat</a>
<tr><td class="sepr"><a href="#5.4.2.echo">5.4.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.4.2.echo">Echo</a>
<tr><td class="sepr"><a href="#5.4.3.mouse">5.4.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.4.3.mouse">Mouse</a>
<tr><td class="sepr"><a href="#5.5.websocketconfiguration">5.5</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.5.websocketconfiguration">WebSocket Configuration</a>
<tr><td class="sepr"><a href="#5.5.1.websocketthrottle">5.5.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.5.1.websocketthrottle">WebSocket Throttle</a>
<tr><td class="sepr"><a href="#5.5.2.websocketcommandline">5.5.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.5.2.websocketcommandline">WebSocket Command-Line</a>
<tr><td class="sepr"><a href="#5.5.3.websocketversion">5.5.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.5.3.websocketversion">WebSocket Version</a>
<tr><td class="sepr"><a href="#5.6.websocketthroughput">5.6</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.6.websocketthroughput">WebSocket Throughput</a>
<tr><td class="sepr"><a href="#5.7.websocketreferences">5.7</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.7.websocketreferences">WebSocket References</a>
<tr><td class="sepr"><a href="#5.8.wasdquotrawquotsocket">5.8</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.8.wasdquotrawquotsocket">WASD &quot;Raw&quot;Socket</a>
<tr><td class="sepr"><a href="#5.8.1.rawsocketapplication">5.8.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.8.1.rawsocketapplication">RawSocket Application</a>
<tr><td class="sepr"><a href="#5.8.2.rawsocketlibrary">5.8.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.8.2.rawsocketlibrary">RawSocket Library</a>
<tr><td class="sepr"><a href="#5.8.3.rawsocketapplicationexamples">5.8.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.8.3.rawsocketapplicationexamples">RawSocket Application Examples</a>
<tr><td class="sepr"><a href="#5.8.3.1.chat">5.8.3.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.8.3.1.chat">Chat</a>
<tr><td class="sepr"><a href="#5.8.3.2.echo">5.8.3.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.8.3.2.echo">Echo</a>
<tr><td class="sepr"><a href="#5.8.3.3.terminalserver">5.8.3.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.8.3.3.terminalserver">Terminal Server</a>
<tr><td class="sepr"><a href="#5.8.4.rawsocketconfiguration">5.8.4</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#5.8.4.rawsocketconfiguration">RawSocket Configuration</a>
<tr><td class="sepr"><a href="#6.cgicallouts">6.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#6.cgicallouts">CGI Callouts</a>
<tr><td class="sepr"><a href="#6.1.requestsandresponses">6.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#6.1.requestsandresponses">Requests and Responses</a>
<tr><td class="sepr"><a href="#6.2.codeexamples">6.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#6.2.codeexamples">Code Examples</a>
<tr><td class="sepr"><a href="#7.isapi">7.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#7.isapi">ISAPI</a>
<tr><td class="sepr"><a href="#7.1.cgisapi">7.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#7.1.cgisapi">CGIsapi</a>
<tr><td class="sepr"><a href="#7.2.writingisapiscripts">7.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#7.2.writingisapiscripts">Writing ISAPI Scripts</a>
<tr><td class="sepr"><a href="#7.3.serverconfiguration">7.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#7.3.serverconfiguration">Server Configuration</a>
<tr><td class="sepr"><a href="#8.decnetamposu">8.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#8.decnetamposu">DECnet &amp; OSU</a>
<tr><td class="sepr"><a href="#8.1.scriptsystemenvironment">8.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#8.1.scriptsystemenvironment">Script System Environment</a>
<tr><td class="sepr"><a href="#8.1.1.proxyaccess">8.1.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#8.1.1.proxyaccess">Proxy Access</a>
<tr><td class="sepr"><a href="#8.1.2.decnetobjects">8.1.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#8.1.2.decnetobjects">DECnet Objects</a>
<tr><td class="sepr"><a href="#8.1.3.reducingscriptlatency">8.1.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#8.1.3.reducingscriptlatency">Reducing Script Latency</a>
<tr><td class="sepr"><a href="#8.1.4.decnetosustartup">8.1.4</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#8.1.4.decnetosustartup">DECnet/OSU Startup</a>
<tr><td class="sepr"><a href="#8.2.cgi">8.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#8.2.cgi">CGI</a>
<tr><td class="sepr"><a href="#8.3.osudecthreadsemulation">8.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#8.3.osudecthreadsemulation">OSU (DECthreads) Emulation</a>
<tr><td class="sepr"><a href="#8.4.userscripts">8.4</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#8.4.userscripts">User Scripts</a>
<tr><td class="sepr"><a href="#9.otherenvironments">9.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#9.otherenvironments">Other Environments</a>
<tr><td class="sepr"><a href="#9.1.java">9.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.1.java">Java</a>
<tr><td class="sepr"><a href="#9.1.1.cgiplusonly">9.1.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.1.1.cgiplusonly">CGIplus Only</a>
<tr><td class="sepr"><a href="#9.1.2.requirements">9.1.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.1.2.requirements">Requirements</a>
<tr><td class="sepr"><a href="#9.1.3.carriagecontrol">9.1.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.1.3.carriagecontrol">Carriage Control</a>
<tr><td class="sepr"><a href="#9.2.perl">9.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.2.perl">Perl</a>
<tr><td class="sepr"><a href="#9.2.1.activatingperl">9.2.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.2.1.activatingperl">Activating Perl</a>
<tr><td class="sepr"><a href="#9.2.2.cgienvironment">9.2.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.2.2.cgienvironment">CGI Environment</a>
<tr><td class="sepr"><a href="#9.2.3.postedrequests">9.2.3</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.2.3.postedrequests">POSTed Requests</a>
<tr><td class="sepr"><a href="#9.2.4.reducinglatency">9.2.4</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.2.4.reducinglatency">Reducing Latency</a>
<tr><td class="sepr"><a href="#9.2.4.1.cgiplus">9.2.4.1</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.2.4.1.cgiplus">CGIplus</a>
<tr><td class="sepr"><a href="#9.2.4.2.runtimeenvironment">9.2.4.2</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.2.4.2.runtimeenvironment">Run-Time Environment</a>
<tr><td class="sepr"><a href="#9.2.5.requirements">9.2.5</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text"><a href="#9.2.5.requirements">Requirements</a>
<tr><td class="sepr"><a href="#10.requestredaction">10.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#10.requestredaction">Request Redaction</a>
<tr><td class="sepr"><a href="#11.rawtcpipsocket">11.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#11.rawtcpipsocket">Raw TCP/IP Socket</a>
<tr><td class="sepr"><a href="#12.index">12.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#12.index">Index</a>
<tr><td class="sepr"><a href="#13.attributionandacknowledgement">13.</a>&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip<td class="text majr"><a href="#13.attributionandacknowledgement">Attribution and Acknowledgement</a>
</table>
</div>

<br>
<!-- source:0100_INTRO.WASDOC -->
<hr class="page">
<a id="1." href="#"></a>
<a id="1.introduction" href="#"></a>
<a id="introduction" href="#"></a>
<h1 class="head"><span class="numb">1.</span><span class="text">Introduction</span></h1>

<div class="TOC2cols2">
<table class="TOC2table">
<tr><td><a href="#1.1.scriptingaccounts"><span class="numb">1.1</span><span class="text">Scripting Accounts</span></a>
<tr><td><a href="#1.2.scriptingprocesses"><span class="numb">1.2</span><span class="text">Scripting Processes</span></a>
<tr><td><a href="#1.2.1.processmanagement"><span class="numb">1.2.1</span><span class="text">Process Management</span></a>
<tr><td><a href="#1.2.2.processnomenclature"><span class="numb">1.2.2</span><span class="text">Process Nomenclature</span></a>
<tr><td><a href="#1.2.3.processscripting"><span class="numb">1.2.3</span><span class="text">Process Scripting</span></a>
<tr><td><a href="#1.2.3.1.personascripting"><span class="numb">1.2.3.1</span><span class="text">Persona Scripting</span></a>
<tr><td><a href="#1.2.3.2.restrictingpersonascripting"><span class="numb">1.2.3.2</span><span class="text">Restricting Persona Scripting</span></a>
<tr><td><a href="#1.2.3.3.processpriorities"><span class="numb">1.2.3.3</span><span class="text">Process Priorities</span></a>
<tr><td><a href="#1.2.4.scriptprocessdefault"><span class="numb">1.2.4</span><span class="text">Script Process Default</span></a>
<tr><td><a href="#1.2.5.scriptprocessparsetype"><span class="numb">1.2.5</span><span class="text">Script Process Parse Type</span></a>
<tr><td><a href="#1.2.6.scriptprocessrundown"><span class="numb">1.2.6</span><span class="text">Script Process Run-Down</span></a>
<tr><td><a href="#1.2.7.clientrecalcitrance"><span class="numb">1.2.7</span><span class="text">Client Recalcitrance</span></a>
<tr><td><a href="#1.3.scriptproctor"><span class="numb">1.3</span><span class="text">Script Proctor</span></a>
<tr><td><a href="#1.4.cachingscriptoutput"><span class="numb">1.4</span><span class="text">Caching Script Output</span></a>
<tr><td><a href="#1.5.enablingascript"><span class="numb">1.5</span><span class="text">Enabling A Script</span></a>
<tr><td><a href="#1.6.scriptmapping"><span class="numb">1.6</span><span class="text">Script Mapping</span></a>
<tr><td><a href="#1.7.scriptruntime"><span class="numb">1.7</span><span class="text">Script Run-Time</span></a>
<tr><td><a href="#1.8.unixsyntax"><span class="numb">1.8</span><span class="text">Unix Syntax</span></a>
<tr><td><a href="#1.9.scriptinglogicals"><span class="numb">1.9</span><span class="text">Scripting Logicals</span></a>
<tr><td><a href="#1.10.scriptingscratchspace"><span class="numb">1.10</span><span class="text">Scripting Scratch Space</span></a>
<tr><td><a href="#1.11.dclprocessingofrequests"><span class="numb">1.11</span><span class="text">DCL Processing of Requests</span></a>
<tr><td><a href="#1.12.scriptingfunctionlibrary"><span class="numb">1.12</span><span class="text">Scripting Function Library</span></a>
<tr><td><a href="#1.13.scriptrequestedservergeneratederrorresponses"><span class="numb">1.13</span><span class="text">Script-Requested, Server-Generated Error Responses</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#0.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#2.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> This document is <span class="high bold">not a general tutorial on authoring scripts</span>, CGI or any
other. A large number of references in the popular computing press covers all
aspects of this technology, usually quite comprehensively.  The information
here is about the specifics of scripting in the WASD environment, which is
generally very much like any other implementation, VMS or otherwise (although
there are always annoying idiosyncracies, see <a class="link" href="#2.4.cgifunctionlibrary">2.4 CGI Function Library</a> for a
partial solution to smoothing out some of these wrinkles for VMS environments).

<p> <span class="high italic">Scripts</span> are mechanisms for creating Web applications and services,
sending data to (and often receiving data from) a client, extending the
capabilities of the basic server.  Scripts execute in processes and accounts
separate from the actual HTTP server but under its control and interacting with
it.

<p> WASD manages a script's execution environment as an independent detached
process created and managed by the HTTP server.  By configuration a script also
can be executed in a process created using DECnet.  Originally, WASD scripted in
subprocesses but this is obsolete.  There is no analogue of the Apache loadable
module executed within the server process itself.

<p> WASD scripting can be deployed in a number of environments.  Other sections
cover the specifics of these.  Don't become bewildered or be put off by all
these apparent options, they are basically variations on a CGI theme.

<ul class="list simple list0">
<li class="item"> <a class="link" href="#2.cgi">2. CGI</a>
<li class="item"> <a class="link" href="#3.cgiplus">3. CGIplus</a>
<li class="item"> <a class="link" href="#4.runtimeenvironments">4. Run-Time Environments</a>
<li class="item"> <a class="link" href="#5.websocket">5. WebSocket</a>
<li class="item"> <a class="link" href="#6.cgicallouts">6. CGI Callouts</a>
<li class="item"> <a class="link" href="#7.isapi">7. ISAPI</a>
<li class="item"> <a class="link" href="#8.decnetamposu">8. DECnet &amp; OSU</a>
<li class="item"> <a class="link" href="#9.otherenvironments">9. Other Environments</a>
<li class="item"> <a class="link" href="#10.requestredaction">10. Request Redaction</a>
<li class="item"> <a class="link" href="#11.rawtcpipsocket">11. Raw TCP/IP Socket</a>
</ul>

<a id="1.1" href="#"></a>
<a id="1.1.scriptingaccounts" href="#"></a>
<a id="scriptingaccounts" href="#"></a>
<h2 class="head"><span class="numb">1.1</span><span class="text">Scripting Accounts</span></h2>

<p> It is strongly recommended to execute scripts in an account distinct from
that executing the server.  This minimises the risk of both unintentional and
malicious interference with server operation through either Inter-Process
Communication (IPC) or scripts manipulating files used by the server.

<p> The default WASD installation creates two such accounts, with distinct
UICs, usernames and default directory space.  The UICs and home areas can be
specified differently to the displayed defaults.  Nothing should be assumed or
read into the scripting account username &ndash; it's just a username.

<a id="1.1.0.0.1" href="#"></a>
<a id="1.1.defaultaccounts" href="#"></a>
<a id="defaultaccounts" href="#"></a>
<h5 class="head"><span class="text">Default Accounts</span></h5>
<table class="tabl">
<tr class="tabr under">
<th class="tabh">Username
<th class="tabh">UIC
<th class="tabh">Default
<th class="tabh">Description
<tr class="tabr">
<tr class="tabr">
<td class="tabd">HTTP&dollar;SERVER
<td class="tabd">[077,001]
<td class="tabd">WASD_ROOT:[HTTP&dollar;SERVER]
<td class="tabd">Server Account
<tr class="tabr">
<td class="tabd">HTTP&dollar;NOBODY
<td class="tabd">[076,001]
<td class="tabd">WASD_ROOT:[HTTP&dollar;NOBODY]
<td class="tabd">Scripting Account
</table>

<p> During startup the server checks for the existence of the default scripting
account and automatically configures  itself to use this for scripting.  If it
is not present it falls-back to using the server account.  Other account names
can be used if the startup procedures are modified accordingly.  The default
scripting username may be overridden using the /SCRIPT=AS=&lt;username&gt;
qualifier (see <a class="link blank" target="_blank" href="../install/#serverstartup">Server Startup</a> in <a class="link blank" target="_blank" href="../install/#0.">WASD Installation</a>). 
The default scripting account cannot be a member of the SYSTEM group and cannot
have any privilege other than NETMBX and TMPMBX (<a class="link" href="#1.2.3.1.privilegeduserscripting">&lsquo;Privileged User Scripting&rsquo; in 1.2.3.1 Persona Scripting</a> describes how to configure to allow this).

<p> Scripting under a separate account is not available with subprocess
scripting and is distinct from PERSONA scripting (even though it uses the same
mechanism, see below).

<a id="1.2" href="#"></a>
<a id="1.2.scriptingprocesses" href="#"></a>
<a id="scriptingprocesses" href="#"></a>
<h2 class="head"><span class="numb">1.2</span><span class="text">Scripting Processes</span></h2>

<p> Process creation under the VMS operating system is notoriously slow and
expensive. This is an inescapable overhead when scripting via child processes.
An obvious strategy is to avoid, at least as much as possible, the creation of
these processes.  The only way to do this is to share processes between
multiple scripts/requests, addressing the attendant complications of isolating
potential interactions between requests. These could occur through changes made
by any script to the process' enviroment. For VMS this involves symbol and
logical name creation, and files opened at the DCL level. In reality few
scripts need to make logical name changes and symbols are easily removed
between uses. DCL-opened files are a little more problematic, but again, in
reality most scripts doing file manipulation will be images.

<p> A reasonable assumption is that for almost all environments scripts can
quite safely share processes with <span class="high under">great</span> benefit to response
latency and system impact
(see <a class="link blank" target="_blank" href="../features/#serverperformance">Server Performance</a> of <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>)
for a table with some comparative performances). If the local environment
requires absolute script isolation for some reason then this
process-persistance may easily be disabled with a consequent trade-off on
performance.

<p> The term <span class="high italic">zombie</span> is used to describe processes when
persisting between uses (the reason should be obvious, they are neither
&quot;alive&quot; (processing a request) nor are they &quot;dead&quot; (deleted <span class="high monosp">:^)</span>
Zombie processes have a finite time to exist (<span class="high italic">non-</span>life-time?)
before they are automatically run-down (see below).  This keeps process clutter
on the system to a minimum.

<a id="1.2.1" href="#"></a>
<a id="1.2.1.processmanagement" href="#"></a>
<a id="processmanagement" href="#"></a>
<h3 class="head"><span class="numb">1.2.1</span><span class="text">Process Management</span></h3>

<p> Scripting processes are created on-demand, within configuration limits
and timeout periods.  There are no arbitrary limits, only system resource
limits, on the number of scripting processes.  WASD_CONFIG_GLOBAL directives
control the configuration limits of these (see
<a class="link blank" target="_blank" href="../config/#globalconfiguration">Global Configuration</a> of <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>).

<div class="blockof code">[DclHardLimit]  100
[DclSoftLimit]   90
[DclZombieLifeTime]  00:10:00
[DclCgiPlusLifeTime]  00:30:00
</div>
 Other configuration directives are discussed later in this chapter.

<a id="1.2.1.0.1" href="#"></a>
<a id="1.2.1.hardlimit" href="#"></a>
<a id="hardlimit" href="#"></a>
<h5 class="head"><span class="text">Hard Limit</span></h5>

<p> Scripting processes of all kinds (CGI, CGIplus and RTE) are created
on-demand up until [DclHardLimit] is reached.  If all scripting processes are
busy with requests at that limit then the server provides a 503 (too busy)
response.

<a id="1.2.1.0.2" href="#"></a>
<a id="1.2.1.softlimit" href="#"></a>
<a id="softlimit" href="#"></a>
<h5 class="head"><span class="text">Soft Limit</span></h5>

<p> If there are more than [DclSoftLimit] scripting processes then the
least-recently-used of any idle processes (those not currently processing a
request) are proactively run-down until the soft-limit is reached.  This
provides <span class="high italic">head-room</span> for the immediate creation of additional
scripting processes for new requests that cannot be satisfied from currently
instantiated processes.   Soft-limit should of course be configured less than
hard-limit (and if not WASD makes it that way).

<a id="1.2.1.0.3" href="#"></a>
<a id="1.2.1.lifetimes" href="#"></a>
<a id="lifetimes" href="#"></a>
<h5 class="head"><span class="text">Lifetimes</span></h5>

<p> Idle scripting processes (those not having been given a request to process)
are proactively run-down (see <a class="link" href="#1.2.6.scriptprocessrundown">1.2.6 Script Process Run-Down</a>) after configured
periods. 

<p> [DclZombieLifeTime] specifies the period in minutes a CGI scripting process
can remain idle.

<p> [DclCgiPlusLifeTime] specifies the period a CGIplus script (inside a
CGIplus scripting process) or a RTE process can remain idle.

<p> If requests being serviced by scripts drop to zero for a period (governed
by the above lifetimes) then eventually all scripting processes should be
run-down leaving only the server process.

<a id="1.2.2" href="#"></a>
<a id="1.2.2.processnomenclature" href="#"></a>
<a id="processnomenclature" href="#"></a>
<h3 class="head"><span class="numb">1.2.2</span><span class="text">Process Nomenclature</span></h3>

<p> Script process naming occurs with the intention of providing some obvious
indication of the activity of the process.

<p> During script process creation the name momentarily is seen using the schema
<span class="high monosp">WASD:80-1</span> ... <span class="high monosp">WASD:80-999</span> but quickly moves to <span class="high monosp">WASD:80-<span class="high italic">pid</span></span> where
<span class="high italic">pid</span> are four hex digits of the LSW of the process PID (essentially to ensure
uniqueness).

<ol class="list">

<li class="item"> If a <span class="high bold">plain CGI script</span> is activated the process name incorporates as
much of the script name as can be accomodated.

<br> So CGI script <span class="high monosp">/cgi-bin/cgi_symbols</span> during processing would have the
name &quot;<span class="high monosp">/cgi_symbo_<span class="high italic">pid</span></span>&quot;.

<li class="item"> Similarly, if a <span class="high bold">CGIplus script</span> is activated the script name is
incororated, but with the PID element separated using a <span class="high italic">plus</span> symbol.

<br> So the <span class="high italic">conan</span> script would appear &quot;<span class="high monosp">/conan+<span class="high italic">pid</span></span>&quot;.

<li class="item"> With a <span class="high bold">WebSocket script</span> the PID element is separated using a
<span class="high italic">tilde</span> symbol.

<br> So the <span class="high italic">ws_mouse</span> example script would appear &quot;<span class="high monosp">/ws_mouse~<span class="high italic">pid</span></span>&quot;.

<li class="item"> An <span class="high bold">RTE</span> has the <span class="high italic">RTE name</span> (not script name) incorporated with
the PID element separated using an <span class="high italic">equals</span> symbol.

<br> So the <span class="high italic">PERL</span> RTE would appear &quot;<span class="high monosp">/perlrte=<span class="high italic">pid</span></span>&quot;.

<li class="item"> Where a script process is directly executing <span class="high bold">CLI commands</span> the
underscore changes to a <span class="high italic">dollar</span> symbol, as in &quot;<span class="high monosp">WASD:80&dollar;<span class="high italic">pid</span></span>.

</ol>

<p> Historically, WASD scripting processes have been named sequentially
<span class="high monosp">WASD:80-1</span> ... <span class="high monosp">WASD:80-999</span>.  A script <span class="high italic">could</span> change that and it would
remain even if the process was reused for another script.  Now at conclusion of
script processing v12 reverts the name.

<p> The v12 schema may be disabled by defining the logical name
WASD_DCL_PRCNAM_PRE12 prior to server start.

<a id="1.2.3" href="#"></a>
<a id="1.2.3.processscripting" href="#"></a>
<a id="processscripting" href="#"></a>
<h3 class="head"><span class="numb">1.2.3</span><span class="text">Process Scripting</span></h3>

<p> The default is for WASD to execute scripts in detached processes created
and managed completely independently of the server process itself.  This offers
a significant number of advantages

<ul class="list list0">
<li class="item"> pooled quotas are not a consideration
<li class="item"> buggy scripts cannot directly affect the server process
<li class="item"> can be created with more appropriate process priorities
<li class="item"> can be executed under accounts different to that of the server
<li class="item"> allows secure but yet full-featured user scripting
<li class="item"> processes created through the full account login process
</ul>

<p> Creation of a process is expensive in terms of system resources and initial
invocation response latency (particularly if extensive login procedures are
required), but this quickly becomes negligable as most script processes are used
multiple times for successive scripts and/or requests.

<p> There is no WASD analogue of the Apache loadable module executed within the
server process itself.

<a id="1.2.3.0.1" href="#"></a>
<a id="1.2.3.processmanagement" href="#"></a>
<a id="processmanagement" href="#"></a>
<h5 class="head"><span class="text">Process Management</span></h5>

<p> With detached processes the server must explicitly ensure that each
scripting process is removed from the system during server shutdown (cf.
subprocesses where the VMS <span class="high italic">executive</span> provides that automatically).  This
is performed by the server exit handler.  With VMS it is possible to bypass the
exit handler (using a &dollar;DELPRC or the equivalent &dollar;STOP/ID= for instance),
making it possible for &quot;orphaned&quot; scripting processes to remain &ndash; and
potentially accumulate on the system!

<p> To address this possibility the server scans the system for
candidate processes during each startup.  These are identified by a
<span class="high italic">terminal</span> mailbox (SYS&dollar;COMMAND device), and then further that the
mailbox has an ACL with two entries; the first identifying itself as a WASD
HTTPd mailbox and the second allowing access to the account the script is being
executed under.  Such a device ACL looks like the following example.

<div class="blockof code">Device MBA335:, device type local memory mailbox, is online, record-oriented
  device, shareable, mailbox device.

  Error count                    0    Operations completed                  0
  Owner process                 &quot;&quot;    Owner UIC             [WEB,HTTP&dollar;NOBODY]
  Owner process ID        00000000    Dev Prot              S:RWPL,O:RWPL,G,W
  Reference count                1    Default buffer size                2048
  Device access control list:
    (IDENTIFIER=WASD_HTTPD_80,ACCESS=NONE)
    (IDENTIFIER=[WEB,HTTP&dollar;NOBODY],ACCESS=READ+WRITE+PHYSICAL+LOGICAL)
</div>

<p> This rights identifier is generated from the server process name and is
therefore system-unique (so multiple autonomous servers will not accidentally
cleanup the script processes of others), and <span class="high bold">is created  during
server startup</span> if it does not already exist.  For example, if the process
name was &quot;HTTPd:80&quot; (the default for a standard service) the rights
identifier name would be &quot;WASD_HTTPD_80&quot; (as shown in the example
above).

<a id="1.2.3.0.2" href="#"></a>
<a id="1.2.3.syloginandloginprocedures" href="#"></a>
<a id="syloginandloginprocedures" href="#"></a>
<h5 class="head"><span class="text">SYLOGIN and LOGIN Procedures</span></h5>

<p> Scripting processes are created through the full &quot;LOGINOUT&quot; life-cycle and
execute all system and account LOGIN procedures.  Although immune to the effects
of most actions within these procedures, and absorbing any output generated
during this phase of the process life-cycle, some consideration should be given
to minimising the LOGIN procedure paths.  This can noticably reduce initial
script latency on less powerful platforms.

<p> The usual recommendations for non-interactive LOGIN procedures apply for
script environments as well.  Avoid interactive-only commands and reduce
unnecessary interactive process environment setup.  This is usually
accomplished though code structures such as the following

<div class="blockof code">&dollar; IF F&dollar;MODE() .EQS. &quot;INTERACTIVE&quot;
&dollar; THEN
     &hellip;
&dollar; ENDIF

&dollar; IF F&dollar;MODE() .NES. &quot;INTERACTIVE&quot; THEN EXIT
</div>

<p> WASD scripting processes can be specifically detected using DCL tests
similar to the following.  This checks the mode, that standard output is a
mailbox, and the process name.  These are fairly reliable (but not absolutely
infallible) indicators.

<div class="blockof code">&dollar; IF F&dollar;MODE() .NES. &quot;INTERACTIVE&quot; .AND. -
     F&dollar;GETDVI(&quot;SYS&dollar;OUTPUT&quot;,&quot;MBX&quot;) .AND. -
     F&dollar;EXTRACT(0,4,F&dollar;PROCESS()) .EQS. &quot;WASD&quot; .AND. -
     F&dollar;EXTRACT(5,1,F&dollar;PROCESS()) .EQS. &quot;:&quot; .AND. -
     F&dollar;ELEMENT(1,&quot;-&quot;,F&dollar;PROCESS()) .NES. &quot;-&quot;
&dollar; THEN
&dollar;!   WASD scripting process!
     &hellip;
&dollar; ENDIF
</div>

<a id="1.2.3.1" href="#"></a>
<a id="1.2.3.1.personascripting" href="#"></a>
<a id="personascripting" href="#"></a>
<h4 class="head"><span class="numb">1.2.3.1</span><span class="text">Persona Scripting</span></h4>

<p> There are advantages in running a script under a non-server account.  The
most obvious of these is the security isolation it offers with respect to the
rest of the Web and server environment.  It also means that the server account
does not need to be resourced especially for any particularly demanding
application.

<a id="1.2.3.1.1" href="#"></a>
<a id="1.2.3.1.enablingpersonascripting" href="#"></a>
<a id="enablingpersonascripting" href="#"></a>
<h5 class="head"><span class="text">Enabling Persona Scripting</span></h5>

<p> The &dollar;PERSONA functionality must be explicitly enabled at server startup
using the /PERSONA qualifier
(<a class="link blank" target="_blank" href="../install/#serveraccountandenvironment">Server Account and Environment</a> of <a class="link blank" target="_blank" href="../install/#0.">WASD Installation</a>). 
The ability for the server to be able to execute scripts under any user
account is a very powerful (and potentially dangerous) capability, and so is
designed that the site administrator must explicitly and deliberately enable
the functionality.  Configuration files need to be rigorously protected against
unauthorized modification.

<p> A specific script or directory of scripts can be designated for execution
under a specified account using the WASD_CONFIG_MAP configuration file
<span class="high italic">set script=as=</span> mapping rule.  The following example illustrates the
essentials.

<div class="blockof code"># one script to be executed under the account
SET  /cgi-bin/a_big_script*  script=as=BIG_ACCOUNT
# all scripts in this area to be executed under this account
SET  /database-bin/*  script=as=DBACCNT
</div> 

<p> Access to package scripting directories (e.g. WASD_ROOT:[CGI-BIN]) is
controlled by ACLs and possession of the rights identifier WASD_HTTP_NOBODY. 
If a non-server account requires access to these areas it too will need to be
granted this identifier.

<a id="1.2.3.1.2" href="#"></a>
<a id="1.2.3.1.useraccountscripting" href="#"></a>
<a id="useraccountscripting" href="#"></a>
<h5 class="head"><span class="text">User Account Scripting</span></h5>

<p> In some situations it may be desirable to allow the average Web user to
experiment with or implement scripts.  If the <span class="high italic">set script=as=</span>
mapping rule specifies a tilde character then for a user request the mapped
SYSUAF username is substituted.  Note that this requires the script to be
colocated with the user account Web location and that the script is run under
that account.

<p> The following example shows the essentials of setting up a user environment
where access to a subdirectory in the user's home directory, [.WWW] with
script's located in a subdirectory of that, [.WWW.CGI-BIN].

<div class="blockof code">SET   /~*/www/cgi-bin/*  script=AS=~
UXEC  /~*/cgi-bin/*  /*/www/cgi-bin/*
USER  /~*/*  /*/www/*
REDIRECT  /~*  /~*/
PASS  /~*/*  /dka0/users/*/*
</div> 
 To enable user CGIplus scripting include something like

<div class="blockof code">UXEC+  /~*/cgiplus-bin/*  /*/www/cgi-bin/*
</div> 

<p> Where the site administrator has less than full control of the scripting
environment it may be prudent to put some constraints on the quantity of
resource that potentially can be consumed by non-core or errant scripting. 
The following WASD_CONFIG_MAP rule allows the &quot;maximum&quot; CPU time consumed by a
single script to be constrained.

<div class="blockof code">SET   /cgi-bin/cgi_process  script=CPU=00:00:05
</div> 

<p> Note that this is on a per-script basis, contrasted to the sort of limit a
CPULM-type constraint would place on a scripting process.

<p> The following WASD_CONFIG_GLOBAL rule specifies at which priority the
scripting process executes.  This can be used to provide the server and its
infrastructure an advantage over user scripts.

<div class="blockof code">[DclDetachProcessPriority]  1,2
</div>

See <a class="link" href="#1.2.3.3.processpriorities">1.2.3.3 Process Priorities</a> for further detail.

<a id="1.2.3.1.3" href="#"></a>
<a id="1.2.3.1.authenticateduserscripting" href="#"></a>
<a id="authenticateduserscripting" href="#"></a>
<h5 class="head"><span class="text">Authenticated User Scripting</span></h5>

<p> If the <span class="high italic">set script=as=</span> mapping rule specifies a dollar then a
request that has been SYSUAF authenticated has the SYSUAF username substituted. 
Note that the script itself can be located anywhere provided the user account
has read and/or execute access to the area and file.

<div class="blockof code">SET   /cgi-bin/cgi_process  script=AS=&dollar;
</div> 

<p> If the script has not been subject to SYSUAF authorization then this causes
the script activation to fail.  To allow authenticated requests to be executed
under the corresponding VMS account and non-authenticated requests to script as
the usual server/scripting account use the following variant.

<div class="blockof code">SET   /cgi-bin/cgi_process  script=AS=&dollar;?
</div> 

<p> If the server startup included /PERSONA=AUTHORIZED then only requests that
have been subject to HTTP authorization and authentication are allowed to
script under non-server accounts.

<a id="1.2.3.1.4" href="#"></a>
<a id="1.2.3.1.privilegeduserscripting" href="#"></a>
<a id="privilegeduserscripting" href="#"></a>
<h5 class="head"><span class="text">Privileged User Scripting</span></h5>

<p> By default a privileged account cannot be used for scripting.  This is done
to reduce the chance of unintended capabilities when executing scripts.  With
additional configuration it is possible to use such accounts.  Great care
should be exercised when undertaking this.

<p> To allow the server to activate a script using a privileged account the
keyword /PERSONA=RELAXED must be used with the persona startup qualifier.  If
the keywords /PERSONA=RELAXED=AUTHORIZED are used then privileged accounts are
allowed for scripting but only if the request has been subject to HTTP
authorization and authentication.

<a id="1.2.3.2" href="#"></a>
<a id="1.2.3.2.restrictingpersonascripting" href="#"></a>
<a id="restrictingpersonascripting" href="#"></a>
<h4 class="head"><span class="numb">1.2.3.2</span><span class="text">Restricting Persona Scripting</span></h4>

<p> By default, activating the /PERSONA server startup qualifier allows all the
modes described above to be deployed using appropriate mapping rules.  Of
course there may be circumstances where such broad capabilities are
inappropriate or otherwise undesirable.  It is possible to control which user
accounts are able to be used in this fashion with a rights identifier.  Only
those accounts granted the identifier can have scripts activated under them. 
This means <span class="high under">all</span> accounts &hellip; including the server account!

<div class="note">
<a id="1.2.3.2.1" href="#"></a>
<a id="1.2.3.2.recommendation" href="#"></a>
<a id="recommendation" href="#"></a>
<h5 class="head center"><span class="text">Recommendation</span></h5>
<hr class="note_hr">
The simplest solution might appear to be to just grant all required accounts
the WASD_HTTP_NOBODY identifier described above.  While this is certainly
possible it does provide read access to all parts of the server package this
identifier controls, and write access to the WASD_ROOT:[SCRATCH] default file
scratch space (<a class="link" href="#1.10.scriptingscratchspace">1.10 Scripting Scratch Space</a>).  If scripting outside of the
site administrator's control is being deployed it may be better to create a
separate identifier as just described.
<hr class="note_hr">
</div>

<p> This is enabled by specifying the name of a rights identifier as a
parameter to the /PERSONA qualifier.  This may be any identifier but the 
one shown in the following example is probably as good as any.

<div class="blockof code">&dollar; HTTPD /PERSONA=WASD_SCRIPTING
</div> 

<p> This identifier could be created using the following commands

<div class="blockof code">&dollar; SET DEFAULT SYS&dollar;SYSTEM
&dollar; MCR AUTHORIZE
UAF&gt; ADD /IDENTIFIER WASD_SCRIPTING
</div>
 and granted to accounts using

<div class="blockof code">UAF&gt; GRANT /IDENTIFIER WASD_SCRIPTING HTTP&dollar;NOBODY
</div>

<p> Meaningful combinations of startup parameters are possible:

<div class="blockof code">/PERSONA=(RELAXED)
/PERSONA=(RELAXED=AUTHORIZED)
/PERSONA=(AUTHORIZED,RELAXED)
/PERSONA=(<span class="high italic">ident-name</span>,RELAXED)
/PERSONA=(<span class="high italic">ident-name</span>,AUTHORIZED,RELAXED)
/PERSONA=(<span class="high italic">ident-name</span>,RELAXED=AUTHORIZED)
</div>

<a id="1.2.3.3" href="#"></a>
<a id="1.2.3.3.processpriorities" href="#"></a>
<a id="processpriorities" href="#"></a>
<h4 class="head"><span class="numb">1.2.3.3</span><span class="text">Process Priorities</span></h4>

<p> When detached processes are created they can be assigned differing
priorities depending on the origin and purpose.  The objective is to give the
server process a slight advantage when competing with scripts for system
resources.  This allows the server to respond to new requests more quickly
(reducing latency) even if a script may then take some time to complete the
request.

<p> The allocation of base process priorities is determined from the
WASD_CONFIG_GLOBAL [DclDetachProcessPriority] configuration directive, which
takes one or two (comma-separated) integers that determine how many priorities
lower than the server scripting processes are created.  The first integer
determines server processes.  A second, if supplied, determines user scripts. 
User scripts may never be a higher priority that server scripts.  The following
provides example directives.

<div class="blockof code">[DclDetachProcessPriority]  1
[DclDetachProcessPriority]  0,1
[DclDetachProcessPriority]  1,2
</div>

<p> Scripts executed under the server account, or those created using a mapped
username (i.e. &quot;script=as=<span class="high italic">username</span>&quot;), have a process
priority set by the first/only integer.

<p> Scripts activated from user mappings (i.e. &quot;script=as=~&quot; or
&quot;script=as=&dollar;&quot;) have a process priority set by any second integer, or
fall back to the priority of the first/only integer. 

<a id="1.2.4" href="#"></a>
<a id="1.2.4.scriptprocessdefault" href="#"></a>
<a id="scriptprocessdefault" href="#"></a>
<h3 class="head"><span class="numb">1.2.4</span><span class="text">Script Process Default</span></h3>

<p> For standard CGI and CGIplus script the script process' default device and
directory is established using a SET DEFAULT command immediately before
activating the script.  This default is derived from the script file
specification.

<p> An alternative default location may be specified using the mapping rule
shown in the following example.

<div class="blockof code">set /cgi-bin/this-script* script=default=WEB:[THIS-SCRIPT]
</div>

<p> The default may be specified in VMS or Unix file system syntax as
appropriate.  If in Unix syntax (beginning with a forward-slash) no SET
DEFAULT is performed using DCL.  The script itself must access this value using
the SCRIPT_DEFAULT CGI variable and perform a <span class="high italic">chdir()</span>.

<a id="1.2.5" href="#"></a>
<a id="1.2.5.scriptprocessparsetype" href="#"></a>
<a id="scriptprocessparsetype" href="#"></a>
<h3 class="head"><span class="numb">1.2.5</span><span class="text">Script Process Parse Type</span></h3>

<p> On platforms where the Extended File Specification (EFS) is supported
a SET PROCESS /PARSE=EXTENDED or SET PROCESS /PARSE=TRADITIONAL is executed by
the scripting process before script activation depending on whether the script
path is located on an ODS-2 or ODS-5 volume.

<a id="1.2.6" href="#"></a>
<a id="1.2.6.scriptprocessrundown" href="#"></a>
<a id="scriptprocessrundown" href="#"></a>
<h3 class="head"><span class="numb">1.2.6</span><span class="text">Script Process Run-Down</span></h3>

<p> The server can stop a script process at any point, although this is
generally done at a time and in such a way as to eliminate any disruption to
request processing.  Reasons for the server running-down a script process.

<ul class="list">

<li class="item"> Server script process limit reached.  Less-used must be purged to allow
execution of in-demand scripts.

<li class="item"> A script provides output that is not CGI or NPH compliant (i.e. the
script is obviously in error).

<li class="item"> The administrator proactively purges scripts using the Administration
Menu or command-line /DO=DCL=<span class="high italic">PURGE</span>&verbar;<span class="high italic">DELETE</span>.

<li class="item"> A client has cancelled its request against a long-running script and the
[DclBitBucketTimeout] period expires.

<li class="item"> The script itself exits or deletes its own process.

</ul>

<p> In running down a script process the server must both update its own
internal data structures as well as manage the run-down of the script process
environment and script process itself.  These are the steps.

<ol class="list">

<li class="item"> Exit handling.

<ul class="list">

<li class="item"> If the script process is at DCL level no exit handling is possible.

<li class="item"> If the script is executing an image a &dollar;FORCEX is issued against the
process.  This activates declared exit handlers (standard C library atexit(),
VMS system service &dollar;DCLEXH, etc.).  An exit handler should always be declared
for programs that need to cleanup after themselves or otherwise exit elegantly. 

<p> Generally CGIplus processes delete themselves immediately.  With standard
CGI scripts executing an image it may take from zero to a few seconds for the
image run-down to be detected by the server.  A script is allowed approximately
one minute to complete the image run-down.

</ul>

<li class="item"> Input and output to all of the process' streams is cancelled.  For
scripts that may still be still processing this can result in I/O stream
errors.  The server waits for all queued I/O to disappear.

<li class="item"> If the script process has not already deleted itself the server issues a
&dollar;DELPRC against it.

<li class="item"> The server receives the process termination AST and this completes the
process run-down sequence.

</ol>

<a id="1.2.7" href="#"></a>
<a id="1.2.7.clientrecalcitrance" href="#"></a>
<a id="clientrecalcitrance" href="#"></a>
<h3 class="head"><span class="numb">1.2.7</span><span class="text">Client Recalcitrance</span></h3>

<p> If a client disconnects from a running script (by hitting the browser
<span class="high italic">Stop</span> button, or selecting another hyperlink) the loss of network
connectivity is detected by the server at the next output write.

<p> Generally it is necessary for there to be some mechanism for a client to
stop long-running (and presumably resource consuming) scripts.  Network
disconnection is the only viable one.  Experience would indicate however that
most scripts are short running and most disconnections are due to clients
changing their minds about waiting for a page to build or having seen the page
superstructure moving on to something else.

<p> With these considerations in mind there is significiant benefit in not
running-down a script immediately the client disconnection is detected.  A
short wait will result in most scripts completing their output elegantly (the
script itself unaware the output is not being transmitted on to the client),
and in the case of persistent scripts remaining available for the next request,
or for standard CGI the process remaining for use in the next CGI script.

<p> The period allowing the script to complete its processing may be set using
the WASD_CONFIG_GLOBAL configuration directive [DclBitBucketTimeout].  It
should be set to say fifteen seconds, or whatever is appropriate to the local
site.

<div class="blockof code">[DclBitBucketTimeout]  00:00:15
</div>

<p> NB.  &quot;Bit-bucket&quot; is a common term for the <span class="high italic">place</span>
discarded data is <span class="high italic">stored</span>.  <span class="high monosp">:^)</span>

<a id="1.3" href="#"></a>
<a id="1.3.scriptproctor" href="#"></a>
<a id="scriptproctor" href="#"></a>
<h2 class="head"><span class="numb">1.3</span><span class="text">Script Proctor</span></h2>

<p> Script proctoring proactively creates and maintains the specified minimum
number of scripting processes, configured persistent scripts, and scripting
environments (RTEs).  It is primarily intended for those environments that have
significant startup latency but can also be used to maintain idle scripting
processes ready for immediate use.

<p> The script proctor initially instantiates configured items during server
startup and before enabling request acceptance and processing.

<p> Then during subsequent request processing, at each scripting process
run-down it scans current DCL task list counting the number of instances of
each configured item.  The proctor facility can differentiate between idle and
active instances of the script/RTE and will optionally maintain a specified
number of idle processes in addition to any currently active.  If fewer than
the configured requirement(s) one or more new processes are instantiated.

<p> It is possible (and probably likely) that a proctored script specification
will at some stage fail to activate the script (activation specification error,
script unavailable for some reason, etc.) which would lead to a runaway series
of attempts to proctor with each process exit.  To help avoid this situation
proctored processes that exit before successfully completing initial startup
are quickly suppressed from further proctoring action.  This suppression then
more slowly times out, again allowing proctoring for that item.

<p> <span class="high bold">Proctored scripts and RTEs contain nothing of the usual request-related
environment</span>.  No CGI variables to speak of, no service, no request method,
nothing!  This means that rules used for proctor activations must be outside
all virtual service conditionals (i.e. outside of any specific
[[<span class="high italic">service</span>:<span class="high italic">port</span>]] in the rules, can be inside [[*:*]]) and anything else
that may be dependent on a request characteristic.

<p> The easiest way for a script to detect if its been proctored into existence
is to look for the absence of this or these.  No REQUEST_METHOD is a fair
indicator as it should exist with all &quot;real&quot; requests.   Of course a proctored
script is really just there to instantiate itself, not to do anything directly
productive, and so a script/RTE can just recognise this and conclude with
perhaps a 204 HTTP status (no content) and then remain quiescent (awaiting its
first actual request). Any and all output from a proctored script goes to the
bit-bucket.

<p> Once proctored into existance the script process is then subject to the
normal scripting process management and (for example) if idle for a period
exceeding a lifetime value will be procactively removed.  Of course, during
that process rundown the proctor facility will effectively replace it with a
new instance, maintaining the overall requirement.

<p> The Server Admin, DCL Report includes a Proctor List with the currently
configured proctor items and associated statistics.

<p> Proctored script activation can be WATCHed just like any other script
activation using the [x]CGI and [x]DCL items.  To explicitly trigger such an
event merely &dollar;STOP/ID=<span class="high italic">pid</span> a proctored scripting process.

<a id="1.3.0.0.1" href="#"></a>
<a id="1.3.proctorconfiguration" href="#"></a>
<a id="proctorconfiguration" href="#"></a>
<h5 class="head"><span class="text">Proctor Configuration</span></h5>

<p> Proctor global configuration is introduced with the WASD_CONFIG_GLOBAL
[DclScriptProctor]  item with each following line representing one script/RTE
to be proctored.  Each line contains three mandatory and one optional,
space-separated components.

<ul class="list simple">
<li class="item"> <span class="high italic">integer</span>[+<span class="high italic">integer</span>] <span class="high italic">identification</span> <span class="high italic">activation</span> <span class="high italic">notepad</span>
</ul>

which are, in order

<ol class="list list0">
<li class="item"> the minimum <span class="high italic">integer</span> number of instances of the item 
<br>plus an optional minimum <span class="high italic">integer</span> number of <span class="high under">idle</span> instances
<li class="item"> an <span class="high italic">identification string</span> used to match already running instances of the item
<li class="item"> the <span class="high italic">activation path</span> that can be used to activate the item
<li class="item"> an optional <span class="high italic">string</span> that is passed to the mapping notepad facility
</ol>

<p> The <span class="high italic">zombie</span> form is

<ul class="list simple">
<li class="item"> <span class="high italic">integer</span> * [<span class="high italic">activation</span>]
</ul>

where the specified number of idle <span class="high italic">processes</span> is maintained. 

<p> The minimum plus any idle requirement cannot exceed the [DclSoftLimit]
configuration value (in order to minimise potential process thrashing).

<p> The proctor facility works by matching the identification string to the
script paths as present in the DCL task list (and as presented in the Server
Admin, DCL Report).  So it needs to contain something unique to that script or
environment and often contains a wildcard specification.

<p> The activation path used to activate the script/RTE is the same as if it
was activated via a scripting request.

<p> For an RTE the activation script specification does not actually need to
exist.  It must contain a minimum path to activate the desired environment but
the script itself is not checked to exist by WASD and does not need to exist. 
If it does then it should do whatever is required to instantiate its required
environment and return a 204 (no content) response.  If it does not exist then
the RTE itself should detect it's a proctored activation and return a default
204 response itself, instantiating only the RTE environment.

<div class="note center">
<a id="1.3.0.0.2" href="#"></a>
<a id="1.3.remember" href="#"></a>
<a id="remember" href="#"></a>
<h5 class="head center"><span class="text">Remember</span></h5>
<hr class="note_hr">
Rules for mapping proctored scripts and RTEs must be outside of any
request-dependent conditionals including specific virtual services. 
<hr class="note_hr">
</div>

<p> Proctored scripts can be detected during mapping using

<div class="blockof code">if (proctor:)
</div>

or

<div class="blockof code">if (!request-method:)
</div>
(i.e. no request method) and specific data passed using the optional notepad
string  
(see <a class="link blank" target="_blank" href="../config/#notepadkeyword">Notepad: Keyword</a> of <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>)

and then conditionally processed using something like

<div class="blockof code">if (notepad:<span class="high italic">blah</span>)  
</div>

<p> Specific information can also be passed to the proctored script during
mapping using such conditional processing in concert with the SET

<div class="blockof code">script=param=<span class="high italic">name</span>=<span class="high italic">value</span>
</div>
mapping rule.  This appears as a [WWW_]NAME CGI variable containing the value
specified.  Proctored scripts could then act according to any such data.

<p> The combination of these allows some control of proctored scripting.

<p> A proctor item with a minimum (and optionally idle) value of zero can be
specified as a place-marker; the facility ignores zero valued items.

<a id="1.3.0.0.3" href="#"></a>
<a id="1.3.proctorexample" href="#"></a>
<a id="proctorexample" href="#"></a>
<h5 class="head"><span class="text">Proctor Example</span></h5>

<p> This example illustrates a number of non-trivial proctoring scenarios. 
Only configuration items directly involved in the proctoring are shown; others
would be involved in the general web-server infrastructure.

<div class="blockof code"># WASD_CONFIG_GLOBAL
[DclScriptProctor]
2 /cgiplus-bin/mgd* /cgiplus-bin/mgd proctor=daniel
2 /apps/script /apps/script anyoldname=dothis
3+1 (*pyrte*)* /py-bin/proctor.py
2 *
3 * proctor=daniel
</div>

<p> The [DclScriptProctor] contains five items.  The first two specify that
two scripts each be maintained, the third specifies four, the final two
maintain zombie <span class="high italic">processes</span>.  The mapping  rules (below) contain a
conditional detecting the absence of a REQUEST_METHOD and processing the
proctored scripts inside that decision structure.  Proctor-specific mapping
rules tend to be used only to supplement otherwise fundamental (but in this
case proctored) scripting.

<div class="blockof code"># WASD_CONFIG_MAP
if (proctor:)
   if (notepad:proctor=daniel) set * script=as=daniel
   if (notepad:anyoldname=dothis) set * script=param=DOTHIS=one
   # not a real script of course!
   script proctor=daniel proctor=daniel script=as=daniel
endif
</div>
 Each of the five items explained in order:

<ol class="list">

<li class="item"> Matches the CGIplus script &quot;/cgiplus-bin/mgd&quot; and the trailing wildcard
any supplementary path provided to that script.  The activation path is a
straight-forward scripting path.  An optional notepad datum is passed to the
mapping facility.  In the mapping rules the notepad datum supplied is detected
(&quot;if (notepad:proctor=daniel)&quot;) and the username under which the script is to
be executed specified.  A minimum of two instances of this script are
maintained.                    

<li class="item"> Matches the script &quot;/apps/script&quot; without trailing wildcard (as it is
&ndash; a hypothetical &ndash; never used with a supplementary path).  The activation
path is again the straight-forward scripting path.  An optional notepad datum
is also passed from the proctor configuration to mapping which specifically
detects it and set as CGI variable name and value that can subsequently be
detected and acted upon by the proctored script.  A minimum of two instances of
this script are maintained.

<li class="item"> Maintains a scripting environment (RTE) and is therefore a little less
straight-forward.  The intention is to maintain a minimum number of Python RTEs
(a rather expensive-to-instantiate interpreter).  The matching string is more
focused on the underlying RTE.  The RTE is not obvious in the activation path
(as all RTE mapping is transparent to the script path).  The RTE is the
environment of interest though and so is the matching string of interest;
&quot;(*pyrte*)*&quot;, where the parentheses indicate an underlying RTE, the wildcards
delimit the RTE name of interest, and the trailing wildcard matches any current
script that the RTE may be executing.  The Server Admin menu, DCL Report can be
used to gain insight into any script or scripting environment strings to be
matched.  In this third case there is no supplementary mapping required.  A
minimum of three instances of this RTE are maintained at least one of which
must be idle or an additional instance will be created.

<li class="item"> Maintains two idle scripting <span class="high italic">processes</span> (under the default scripting
account) available for scripting use without the latency of process creation. 

<li class="item"> Maintains three idle scripting <span class="high italic">processes</span> with an associated mapping
rule to activate them using the specified username.  The <span class="high italic">activation</span> string
is arbitrary, should be unique, and is the  &quot;path&quot; when being mapped.  A
<span class="high italic">notepad</span> string can be specified.

</ol>

<a id="1.4" href="#"></a>
<a id="1.4.cachingscriptoutput" href="#"></a>
<a id="cachingscriptoutput" href="#"></a>
<h2 class="head"><span class="numb">1.4</span><span class="text">Caching Script Output</span></h2>

<p> The WASD cache was originally provided to reduce file-system access (a
somewhat expensive activity under VMS).  With the expansion in the use of
dynamically generated page content (e.g. PHP, Perl, Python) there is an obvious
need to reduce the system impact of some of these activities.  While many such
responses have content specific to the individual request a large number are
also generated as general site pages, perhaps with simple time or date
components, or other periodic information.  Non-file caching is intended for
this type of dynamic content.

<p> Revalidation of non-file content is difficult to implement for a number of
reasons, both by the server and by the scripts, and so is not provided. 
Instead the cache entry is flushed on expiry of the  [CacheValidateSeconds], or
as otherwise specified by path mapping, and the request is serviced by the
content source (script, PHP, Perl, etc.) with the generated response being
freshly cached.  Browser requests specifying no-caching are honoured (within
server configuration parameters) and will flush the entry, resulting in the
content being reloaded.

<a id="1.4.0.0.1" href="#"></a>
<a id="1.4.controllingscriptcaching" href="#"></a>
<a id="controllingscriptcaching" href="#"></a>
<h5 class="head"><span class="text">Controlling Script Caching</span></h5>

<p> Determining which script content is to be cached and which not, and how long
before flushing, is done using mapping rules (described in detail in
<a class="link blank" target="_blank" href="../config/#requestprocessingconfiguration">Request Processing Configuration</a> of <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>).  
The source  of script cache content is specified  using one or a combination of
the following SET rules against general or specific paths in WASD_CONFIG_MAP. 
All mapping rules (script and non-script) are described here to put the script
oriented ones into context.  Those specific to script output caching are noted.

<ul class="list simple list0">
<li class="item"> <span class="high bold">cache=[no]cgi </span> from Common Gateway Interface (CGI) responses (<span class="high bold">for script output</span>)
<li class="item"> <span class="high bold">cache=[no]file </span> from the file system (default and pre-8.4 cache behaviour)
<li class="item"> <span class="high bold">cache=[no]net </span> caches the full data stream irrespective of the source
<li class="item"> <span class="high bold">cache=[no]nph </span> full stream from Non-Parse Header (NPH) response (<span class="high bold">for script output</span>)
<li class="item"> <span class="high bold">cache=[no]query </span> cache requests with query strings (<span class="high bold">use with care</span>)
<li class="item"> <span class="high bold">cache=[no]script </span> both CGI and NPH responses (<span class="high bold">for script output</span>)
<li class="item"> <span class="high bold">cache=[no]ssi </span> from Server-Side Includes (SSI) documents
</ul>

<p> A good understanding of site requirements and dynamic content sources, 
along with considerable care in specifying cache path SETings, is required to
cache dynamic content effectively.  It is especially important to get the
content revalidation period appropriate to the content of the pages.  This is
specified using the following path SETings.

<ul class="list simple list0">
<li class="item"> <span class="high bold">cache=expires=0 </span> cancels any expiry
<li class="item"> <span class="high bold">cache=expires=DAY </span> expires when the day changes
<li class="item"> <span class="high bold">cache=expires=HOUR </span> when the hour changes
<li class="item"> <span class="high bold">cache=expires=MINUTE </span> when the minute changes
<li class="item"> <span class="high bold">cache=expires=&lt;hh:mm:ss&gt; </span> expires after the specified period in the cache
</ul>

<a id="1.4.0.0.2" href="#"></a>
<a id="1.4.examples" href="#"></a>
<a id="examples" href="#"></a>
<h5 class="head"><span class="text">Examples</span></h5>

<p> To cache the content of PHP-generated home pages that
contain a  time-of-day clock, resolving down to the minute, would require a
mapping rule similar to the following.

<div class="blockof code">set /**/index.php cache=cgi cache=expires=minute
</div>

<p> To prevent requests from flushing a particular scripts output (say the main
page of a site) using no-cache fields until the server determines that it needs
reloading use the cache <span class="high italic">guard</span> period.

<div class="blockof code">set /index.py cache=script cache=expires=hour cache=guard=01:00:00
</div>

<a id="1.5" href="#"></a>
<a id="1.5.enablingascript" href="#"></a>
<a id="enablingascript" href="#"></a>
<h2 class="head"><span class="numb">1.5</span><span class="text">Enabling A Script</span></h2>

<p> By default the server accesses scripts using the search list logical name
CGI-BIN, although this can be significantly changed using mapping rules. 
CGI-BIN is defined to first search WASD_ROOT:[CGI-BIN] and then
WASD_ROOT:[AXP-BIN], WASD_ROOT:[IA64-BIN], or WASD_ROOT:[X86_64-BIN] depending
on the platform.  [CGI-BIN] is intended for architecture-neutral script files
(.CLASS., COM, .PL, .PY, etc.) and the architecture specific directories for
executables (.EXE, .DLL, etc.)

<p> These directories are delivered empty and it is up to the site to populate
them with the desired scripts. A script is made available by copying its
file(s) into the appropriate directory.  By default ACLs will be propagated to
allow access by the default scripting account.  Scripts can be made unavailable
by deleting them from these directories.

<div class="note">
<a id="1.5.0.0.1" href="#"></a>
<a id="1.5.minimiseavailablescripts" href="#"></a>
<a id="minimiseavailablescripts" href="#"></a>
<h5 class="head center"><span class="text">Minimise available scripts</span></h5>
<hr class="note_hr">
It is good security practice to deploy only those scripts a site is actually
using.  This minimises vulnerability by simply reducing the number of possibly
problematic scripts.  A periodic audit of script directories is a good policy.
<hr class="note_hr">
</div>

<p> WASD script executables are built into the WASD_ROOT:[AXP], WASD_ROOT:[IA64]
or WASD_ROOT:[X86_64] directories depending on the architecture.  Other script
files, such as DCL procedures, Perl examples, Java class examples, etc. are
located in other directories in the WASD_ROOT:[SRC] tree.  The procedure
<a class="link blank" target="_blank" href="/wasd_root/install/scripts.com">WASD_ROOT:[INSTALL]SCRIPTS.COM</a> assists
in the installation or deinstallation of groups of WASD scripts.

<a id="1.6" href="#"></a>
<a id="1.6.scriptmapping" href="#"></a>
<a id="scriptmapping" href="#"></a>
<h2 class="head"><span class="numb">1.6</span><span class="text">Script Mapping</span></h2>

<p> Scripts are enabled using the <span class="high italic">exec</span>/<span class="high italic">uxec</span> or <span class="high italic">script</span> rules in the
mapping file (also see
<a class="link blank" target="_blank" href="../config/#requestprocessingconfiguration">Request Processing Configuration</a> of <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>).
The script portion of the <span class="high italic">result</span> must be a URL equivalent of the physical
VMS procedure or executable specification.

<p> All files in a directory may be mapped as scripts using the
<span class="high italic">exec</span> rule.  For instance, in the WASD_CONFIG_MAP configuration file can
be found a rule

<div class="blockof code">exec /cgi-bin/* /cgi-bin/*
</div>

which results in request paths beginning &quot;/cgi-bin/&quot; having the following path
component mapped as a script.  Hence a path &quot;/cgi-bin/cgi_symbols.com&quot; will
result in the server attempting to execute a file named
CGI-BIN:[000000]CGI_SYMBOLS.COM.

<p> Multiple such paths may be designated as <span class="high italic">exec</span>utable, with their
contents expected to be scripts, either directly executable by VMS (e.g. .EXEs
and .COMs) or processable by a designated interpreter, etc., (e.g. .PLs,
.CLASSes) (<a class="link" href="#4.runtimeenvironments">4. Run-Time Environments</a>).

<p> In addition individual files may be specified as scripts.  This is done
using the <span class="high italic">script</span> rule.  In the following example the request path
&quot;/help&quot; activates the &quot;Conan The Librarian&quot; script.

<div class="blockof code">script /help* /cgi-bin/conan*
</div>

<p> Of course, multiple such rules may be used to map such abbreviated or
self-explanatory script paths to the actual script providing the application.

<a id="1.6.0.0.1" href="#"></a>
<a id="1.6.mappinglocalorthirdpartyscripts" href="#"></a>
<a id="mappinglocalorthirdpartyscripts" href="#"></a>
<h5 class="head"><span class="text">Mapping Local or Third-Party Scripts</span></h5>

<p> It is not necessary to move/copy scripts into the server directory
structure to make them accessible.  In fact there are probably good reasons
for not doing so!  For instance, it keeps a package together so that at the
next upgrade there is no possibility of the &quot;server-instance&quot; of that
application being overlooked.

<p> To make scripts provided by third party packages available for server
activation three requirements must be met.

<ol class="list">

<li class="item"> The <span class="high bold">server</span> account (HTTP&dollar;SERVER by default) must have
read and execute access to the directory containing the scripts.  Script files
are searched for by the server before activation is attempted.  This can be
enabled using the SECHAN utility
(see <a class="link blank" target="_blank" href="../features/#sechanutility">Sechan Utility</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>).

<div class="blockof code">&dollar; SECHAN /ASIF=CGI-BIN device:[directory]script-directory.DIR
</div>

<li class="item"> The <span class="high bold">scripting</span> account (HTTP&dollar;NOBODY by default) must have
read and execute access  to any and all images and other resources required to
use the application.  There may be some consideration of file protections
required when multiple accessors need to be accomodated (e.g. scripting and
application accounts) so a specific solution may be required.  If only the
scripting account requires read access then the SECHAN utility could again be
used to provide that to the directory (or directories) and contained files.

<div class="blockof code">&dollar; SECHAN /ASIF=CGI-BIN device:[000000]directory.DIR
&dollar; SECHAN /ASIF=CGI-BIN device:[directory]*.*
</div>

<li class="item"> Mapping rules must exist to make the script and any required resources
accessible.

</ol>

<p> Most packages having such an interface for Web server access would
provide details on mapping into the package directory.  For illustration the
following mapping rules provide access to a package's scripts (assuming it
provides more than one) and also into a documentation area.

<p> The hypothetical &quot;Application X&quot; directory locations are

<div class="blockof code">APPLICATIONX_ROOT:[DOC]
APPLICATIONX_ROOT:[CGI-BIN]
</div>

<p> The required mapping rules would be

<div class="blockof code">pass /applicationX/* /applicationX_root/docs/*
exec /appX-bin/* /applicationX_root/cgi-bin/*
</div>

<p> Access to X's scripts would be using a path such as

<div class="blockof code">http://the.host.name/appx-bin/main_script?plus=some&amp;query=string
</div>

<div class="note">
<a id="1.6.0.0.2" href="#"></a>
<a id="1.6.carefulofthirdpartyscriptlocations" href="#"></a>
<a id="carefulofthirdpartyscriptlocations" href="#"></a>
<h5 class="head center"><span class="text">Careful of third-party script locations</span></h5>
<hr class="note_hr">
When allowing the server and scripting account access into parts of the file
system outside of the WASD package it is recommended to control the environment
very carefully.  Third-party scripting areas in particular should be modelled
on those present in the package itself
(see <a class="link blank" target="_blank" href="../features/#sechanutility">Sechan Utility</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>)
<hr class="note_hr">
</div>

<a id="1.6.0.0.3" href="#"></a>
<a id="1.6.quotwrappingquotlocalorthirdpartyscripts" href="#"></a>
<a id="quotwrappingquotlocalorthirdpartyscripts" href="#"></a>
<h5 class="head"><span class="text">&quot;Wrapping&quot; Local or Third-Party Scripts</span></h5>

<p> Sometimes it may be necessary to provide a particular non-WASD, local, or
third-party script with a particular environment in which to execute.  This can
be provided by <span class="high italic">wrapping</span> the script executable or interpreted script
in a DCL procedure (of course, if the local or third-party script is already
activated by a DCL procedure, then that may need to be directly modified). 
Simply create a DCL procedure, in the same directory as the script executable,
containing the required environmental commands.

<p> For example, the following DCL procedure defines a scratch directory and
provides the location of the configuration file.  It is assumed the script
executable is APPLICATIONX_ROOT:[CGI-BIN]APPX.EXE and the script wrapper
APPLICATIONX_ROOT:[CGI-BIN]APPX.COM.

<div class="blockof code">&dollar;! wrapper for APPX CGI executable
&dollar; SET DEFAULT APPLICATIONX_ROOT:[000000]
&dollar; DEFINE /USER SYS&dollar;SCRATCH APPLICATIONX_ROOT:[SCRATCH]
&dollar; APPX == &quot;&dollar;APPLICATIONX_ROOT:[CGI-BIN]APPX&quot;
&dollar; APPX /CONFIG=APPLICATIONX_ROOT:[CONFIG]APPX.CONF
</div>

<a id="1.7" href="#"></a>
<a id="1.7.scriptruntime" href="#"></a>
<a id="scriptruntime" href="#"></a>
<h2 class="head"><span class="numb">1.7</span><span class="text">Script Run-Time</span></h2>

<p> A script is merely an executed or interpreted file. Although by default VMS
executables and DCL procedures can be used as scripts, other environments may
also be configured. For example, scripts written for the Perl language may be
transparently given to the Perl interpreter in a script process. This type of
script activation is based on a unique file type (extension following the file
name), for the Perl example this is most commonly &quot;.PL&quot;, or sometimes &quot;.CGI&quot;.
Both of these may be configured to automatically invoke the site's Perl
interpreter, or any other for that matter. 

<p> This configuration is performed using the WASD_CONFIG_GLOBAL
[DclScriptRunTime]  directive, where a file type is associated with a run-time
interpreter. This parameter takes two components, the file extension and the
run-time verb. The verb may be  specified as a simple, globally-accessible verb
(e.g. one embedded in the CLI tables), or in the format to construct a
<span class="high italic">foreign-verb</span>, providing reasonable versatility. Run-time parameters may
also be appended to the verb if desired. The server ensures the verb is
foreign-assigned if necessary, then used on a command line with the script file
name as the final parameter to it.

<p> The following is an example showing a Perl interpreter being specified.  The
first line assumes the &quot;Perl&quot; verb is globally accessible on the system (e.g.
perhaps provided by the DCL&dollar;PATH logical) while the second (for the sake of
illustration) shows the same Perl interpreter being configured for a different
file type using the foreign verb syntax.

<div class="blockof code">[DclScriptRunTime]
.PL PERL
.CGI &dollar;PERL_EXE:PERL
</div>

<p> A file contain a Perl script then may be activated merely by specifying a
path such as the following

<div class="blockof code">/cgi-bin/example.pl
</div>

<p> To add any required parameters just append them to the verb specified.

<div class="blockof code">[DclScriptRunTime]
.XYZ XYZ_INTERPRETER -vms -verbose -etc
.XYZ &dollar;XYZ_EXE:XYZ_INTERPRETER /vms /verbose /etc
</div>

<p> If a more complex run-time interpreter is required it may be necessary to
<span class="high italic">wrap</span> the script's execution in a DCL procedure.

<a id="1.7.0.0.1" href="#"></a>
<a id="1.7.scriptfileextensions" href="#"></a>
<a id="scriptfileextensions" href="#"></a>
<h5 class="head"><span class="text">Script File Extensions</span></h5>

<p> The WASD server does not require a file type (extension) to be explicitly
provided when activating a script. This can help hide the implementation detail
of any script. If the script path does not contain a file type the server
searches the script location for a file with one of the known file types, first
&quot;.COM&quot; for a DCL procedure, then &quot;.EXE&quot; for an executable, then any file types
specified using script run-time configuration directive, in the order
specified.

<p> For instance, the script activated in the Perl example above could have been
specified as below and (provided there was no &quot;EXAMPLE.COM&quot; or &quot;EXAMPLE.EXE&quot; in
the search) the same script would have been executed.

<div class="blockof code">/cgi-bin/example
</div>

<a id="1.8" href="#"></a>
<a id="1.8.unixsyntax" href="#"></a>
<a id="unixsyntax" href="#"></a>
<h2 class="head"><span class="numb">1.8</span><span class="text">Unix Syntax</span></h2>

<p> CGI environment variables SCRIPT_FILENAME and PATH_TRANSLATED can be
provided to any script (CGI, CGIplus, RTE) in Unix file-system syntax should
that script require or prefer it using this format.

<p> The path mapping rule &quot;SET script=syntax=unix&quot; changes the default syntax
from VMS to Unix file-system.  For example; by default using the URL

<div class="blockof code">/cgi-bin/cgi_symbols/wasd_root/src/
</div>

would provide the request CGI data

<div class="blockof code">WWW_PATH_INFO == &quot;/wasd_root/src/&quot;
WWW_PATH_TRANSLATED == &quot;WASD_ROOT:[SRC]&quot;
WWW_REQUEST_URI == &quot;/cgi-bin/cgi_symbols/wasd_root/src/&quot;
WWW_SCRIPT_FILENAME == &quot;CGI-BIN:[000000]CGI_SYMBOLS.COM&quot;
WWW_SCRIPT_NAME == &quot;/cgi-bin/cgi_symbols&quot;
</div>

<p> If the script path had been specifically mapped using

<div class="blockof code">set /cgi-bin/cgi_symbols* script=syntax=unix
</div>

the same CGI data would be provided as

<div class="blockof code">WWW_PATH_INFO == &quot;/wasd_root/src/&quot;
WWW_PATH_TRANSLATED == &quot;/wasd_root/SRC/&quot;
WWW_REQUEST_URI == &quot;/cgi-bin/cgi_symbols/wasd_root/src/&quot;
WWW_SCRIPT_FILENAME == &quot;/CGI-BIN/000000/CGI_SYMBOLS.COM&quot;
WWW_SCRIPT_NAME == &quot;/cgi-bin/cgi_symbols&quot;
</div>

<p> Note that the CGI or CGIplus script file is still activated using VMS
file-system syntax, it is just the CGI representation that is changed.  This
can be particularly useful for environments ported from Unix expecting to
manipulate paths using Unix syntax.  This would most commonly occur with RTE
engines such as PHP, Perl, etc.

<a id="1.9" href="#"></a>
<a id="1.9.scriptinglogicals" href="#"></a>
<a id="scriptinglogicals" href="#"></a>
<h2 class="head"><span class="numb">1.9</span><span class="text">Scripting Logicals</span></h2>

<p> Two logicals provide some control of and input to the DCL process
scripting environment (which includes standard CGI, CGIplus and ISAPI,
DECnet-based CGI, but excludes DECnet-based OSU).

<ul class="list">

<li class="item"> <span class="high bold">HTTPD&dollar;LOGIN &ndash; </span> Specifies the location of a command procedure that
can be executed <span class="high under">immediately</span> before the script procedure/image/script-file is
activated.  This is intended for the provision of a common per-site
environment, etc., but could be used for any purpose. Activate using a
system-wide logical as in the following example.

<div class="blockof code">&dollar; DEFINE /SYSTEM HTTPD&dollar;LOGIN WASD_ROOT:[HTTP&dollar;NOBODY]HTTPD&dollar;LOGIN.COM
</div>

<p> Note that each layer of execution added to the scripting environment
increases both system overhead and response latency.

<li class="item"> <span class="high bold">HTTPD&dollar;VERIFY &ndash; </span> Activates DCL verify for the DCL process scripting
environment.  This shows the DCL commands used to support script activation. 
Intended for problem investigation.

<div class="blockof code">&dollar; DEFINE /SYSTEM HTTPD&dollar;VERIFY 1
</div>

<p> If the logical name value is a dotted-decimal specified IP address the
verify is only applied to scripts associated with requests originating from
that address.  This is useful when trying to trouble-shoot scripts on a live
server.

<div class="blockof code">&dollar; DEFINE /SYSTEM HTTPD&dollar;VERIFY 192.168.0.2
</div>

</ul>

<p> Note that most WASD scripts also contain logical names that can be set for
debugging purposes.  These are generally in the format <span class="high italic">script_name</span>&dollar;DBUG and
if exist activate debugging statements throughout the script.

<a id="1.10" href="#"></a>
<a id="1.10.scriptingscratchspace" href="#"></a>
<a id="scriptingscratchspace" href="#"></a>
<h2 class="head"><span class="numb">1.10</span><span class="text">Scripting Scratch Space</span></h2>

<p> Scripts often require temporary file space during execution.  Of course
this can be located anywhere the scripting account (most often HTTP&dollar;SERVER) has
appropriate access.  The WASD package does provide a default area for such
purposes with permissions set during startup to allow the server account full
access.  The default area is located in

<div class="blockof code">WASD_ROOT:[SCRATCH]
</div>

as is accessed by the server and scripts using the logical name

<div class="blockof code">WASD_SCRATCH:
</div>

<p> The server provides for the routine clean-up of old files in WASD_SCRATCH:
left behind by aborted or misbehaving scripts (although as a matter of design
all scripts should attempt to clean up after themselves).  The
WASD_CONFIG_GLOBAL directives

<div class="blockof code">[DclCleanupScratchMinutesMax]
[DclCleanupScratchMinutesOld]
</div>

control how frequently the clean-up scan occurs, and how old files need to be
before being deleted.  Whenever script processes are active the scratch area is
scanned at the maximum period specified, or whenever the last script process is
purged from the system by the server.

<p> Of course there is always the potential for interaction between scripts
using a common area for such purposes.  At the most elemetary, care must be
taken to ensure unique file name are generated.  At worst there is the
potential for malicious interaction and information leakage.  Use such common
areas with discretion.

<div class="note center">
<a id="1.10.0.0.1" href="#"></a>
<a id="1.10.sharedscratchareas" href="#"></a>
<a id="sharedscratchareas" href="#"></a>
<h5 class="head center"><span class="text">Shared scratch areas</span></h5>
<hr class="note_hr">
<span class="high bold">Beware!</span>  They rely on cooperation between scripts for minimising potential
interactions.
<br> They alo can be a source of unintended or malicious information leakage.
<hr class="note_hr">
</div>

<a id="1.10.0.0.2" href="#"></a>
<a id="1.10.uniquefilenamesndashdcl" href="#"></a>
<a id="uniquefilenamesndashdcl" href="#"></a>
<h5 class="head"><span class="text">Unique File Names &ndash; DCL</span></h5>

<p> The &quot;UNIQUE_ID&quot; CGI variable provides a <span class="high under">unique</span> 19 character alpha-numeric
string (<a class="link" href="#2.1.uniqueidnote">&lsquo;UNIQUE_ID Note&rsquo; in 2.1 CGI Environment Variables</a>) suitable for many uses including the type
extension of temporary files.  The following DCL illustrates the essentials of
generating a script-unqiue file name.  For mutliple file names add further text
to the type, as shown below.

<div class="blockof code">&dollar; SCRATCH_DIR = &quot;WASD_SCRATCH:&quot;
&dollar; PROC_NAME = F&dollar;PARSE(F&dollar;ENVIRONMENT(&quot;PROCEDURE&quot;),,,&quot;NAME&quot;)
&dollar; INFILE_NAME = SCRATCH_DIR + PROC_NAME + &quot;.&quot; + WWW_UNIQUE_ID + &quot;_IN&quot;
&dollar; OUTFILE_NAME = SCRATCH_DIR + PROC_NAME + &quot;.&quot; + WWW_UNIQUE_ID + &quot;_OUT&quot;
</div>

<a id="1.10.0.0.3" href="#"></a>
<a id="1.10.uniquefilenamesndashclanguage" href="#"></a>
<a id="uniquefilenamesndashclanguage" href="#"></a>
<h5 class="head"><span class="text">Unique File Names &ndash; C Language</span></h5>

<p> A similar approach can be used for script coded using the C language, with
the useful capacity to mark the file for delete-on-close (of course this is
only really useful if it is, say, only to be written, rewound and then re-read
without closing first &ndash; but I'm sure you get the idea).

<div class="blockof code">#define WASD_SCRATCH &quot;WASD_SCRATCH:&quot;
#define SCRIPT_NAME &quot;EXAMPLE&quot;

char  *unqiueId;
char  tmpFileName [256];
FILE  *tmpFile;

if ((uniqueId = getenv(&quot;WWW_UNIQUE_ID&quot;)) == NULL)
{
   printf (&quot;Error: WWW_UNIQUE_ID absent!\n&quot;);
   exit (1);
}
sprintf (tmpFileName, WASD_SCRATCH SCRIPT_NAME &quot;.%s&quot;, uniqueId);

if ((tmpFile = fopen (tmpFileName, &quot;w+&quot;, &quot;fop=dlt&quot;)) == NULL)
   exit (vaxc&dollar;errno); 
</div>

<a id="1.11" href="#"></a>
<a id="1.11.dclprocessingofrequests" href="#"></a>
<a id="dclprocessingofrequests" href="#"></a>
<h2 class="head"><span class="numb">1.11</span><span class="text">DCL Processing of Requests</span></h2>

<p> DCL is the native scripting environment for VMS and provides a rich set of
constructs and capabilities for <span class="high italic">ad hoc</span> and low usage scripting, and as a
<span class="high italic">glue</span> when several processing steps need to be undertaken for a particular
script.  In common with many interpreted environments care must be taken with
effective exception handling and data validation.  To assist with the
processing of request content and response generation from within DCL
procedures the CGIUTL utility is available in
<a class="link blank" target="_blank" href="/wasd_root/src/misc/*cgiutl*.*">WASD_ROOT:[SRC.MISC]</a>

<p> Functionality includes

<ul class="list list0">
<li class="item"> decode a POSTed request body into DCL symbols
<li class="item"> write a POSTed request body to a file
<li class="item"> <span class="high italic">massage</span> DCL symbol quotation characters
<li class="item"> generate HTTP response headers
<li class="item"> <span class="high italic">binary</span> transfer of file contents
</ul>

<p> Most usefully it can read the request body, decoding form-URL-encoded
contents into DCL symbols and/or a scratch file, allowing a DCL procedure to
easily and effectively process this form of request.

<div class="note">
<a id="1.11.0.0.1" href="#"></a>
<a id="1.11.neversubstitute" href="#"></a>
<a id="neversubstitute" href="#"></a>
<h5 class="head center"><span class="text">NEVER substitute...</span></h5>
<hr class="note_hr">
...the content of CGI variables directly into the code stream using
interpreters that will allows this (e.g. DCL, Perl).  You run a very real risk
of having unintended content maliciously change the intended function of the
code.  For example, never use comma substitution of a CGI variable at the DCL
command line as in
<div class="blockof code">&dollar; COPY 'WWW_FORM_SRC' 'WWW_FORM_DST'
</div>
Always pre-process the content of the variable first, ensuring there has
been nothing inserted that could subvert the intended purpose.  The CGIUTL
assists complying with this rule by providing an explicit, non-DCL substitution
character for use on the command-line (see source code descriptive prologue).
<hr class="note_hr">
</div>

<a id="1.12" href="#"></a>
<a id="1.12.scriptingfunctionlibrary" href="#"></a>
<a id="scriptingfunctionlibrary" href="#"></a>
<h2 class="head"><span class="numb">1.12</span><span class="text">Scripting Function Library</span></h2>

<p> A source code collection of C language functions useful for processing the
more vexing aspects of CGI and general script programming is available in
CGILIB.  This and an example implementation is available in
<a class="link blank" target="_blank" href="/wasd_root/src/misc/*cgilib*.*">WASD_ROOT:[SRC.MISC]</a>

<p> Functionality includes

<ul class="list list0">

<li class="item"> detection and appropriate initialization of the scripting environment,
including WASD, CGIplus, VMS Apache, OSU, Purveyor, and possibly other CGI
(e.g. Cern, Netscape FastTrack)

<li class="item"> transparent access to CGI variables

<li class="item"> transparent access to the body of a POSTed request, both URL-encoded and
MIME multipart/form-data (from &lt;input type=&quot;file&quot;&gt; upload tags)

<li class="item"> placing the contents of a form-URL-encoded or multipart/form-data body
into CGI-like environment variables

<li class="item"> URL-decoding, URL-encoding and HTML-escaping a string

<li class="item"> CGIplus-specific functionality (including callouts)

</ul>

<p> The WASD scripts use this library extensively and may serve as example
applications.

<a id="1.13" href="#"></a>
<a id="1.13.scriptrequestedservergeneratederrorresponses" href="#"></a>
<a id="scriptrequestedservergeneratederrorresponses" href="#"></a>
<h2 class="head"><span class="numb">1.13</span><span class="text">Script-Requested, Server-Generated Error Responses</span></h2>

<p> Of course a script can generate any output it requires including
non-success (non-200) pages (e.g. 400, 401, 302, etc.)  For error pages a
certain consistency results from making these substantially the same layout and
content as those generated by the server itself.  To this end, script response
header output can contain one or more of several extension fields to indicate
to the server that instead of sending the script response to the client it
should internally generate an error response using the script-supplied
information.  These fields are listed in <a class="link" href="#2.2.1.scriptcontrol">&lsquo;Script-Control:&rsquo; in 2.2.1 CGI Compliant Output</a> section of
<a class="link" href="#2.2.1.cgicompliantoutput">2.2.1 CGI Compliant Output</a> and are available in any scripting environment.

<p> If a &quot;Script-Control: X-error-text=&quot;<span class="high italic">text of error message</span>&quot;&quot; field occurs
in the script response header the server stops processing further output and
generates an error message.  Other <span class="high italic">error</span> fields can be used to provide
additional or message-modifying information.  A significant example is the
&quot;Script-Control: X-error-vms-status=<span class="high italic">integer</span>&quot; field which supplies a VMS
status value for a more detailed, status-related error message explanation.

<p> Essentially the script just generates a standard CGI &quot;Status: <span class="high italic">nnn</span>&quot;
response and includes at least the &quot;X-error-text=&quot; field before the
header-terminating empty record (blank line).  Some variations are shown in the
following DCL examples.

<div class="blockof code">&dollar;! vanilla error message
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar; say &quot;Status: 400&quot;
&dollar; say &quot;Script-Control: X-error-text=&quot;&quot;Confusing URL components!&quot;&quot;&quot;
&dollar; say &quot;&quot;

&dollar;! VMS status error message 
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar;! &quot;status: 000&quot; allows the server to select the HTTP status code
&dollar; say &quot;Status: 000&quot;
&dollar; say &quot;Script-Control: X-error-text=&quot;&quot;/a/file/name.txt&quot;&quot;&quot;
&dollar; say &quot;Script-Control: X-error-vms-status=%X00000910&quot;
&dollar; say &quot;Script-Control: X-error-vms-text=&quot;&quot;A:[FILE]NAME.TXT&quot;&quot;&quot;
&dollar; say &quot;&quot;

&dollar;! add META source module name and line generating message
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar; say &quot;Status: 500&quot;
&dollar; say &quot;Script-Control: X-error-text=&quot;&quot;Don't know what to do now...&quot;&quot;&quot;
&dollar; say &quot;Script-Control: X-error-module=EXAMPLE; X-error-line=999&quot;
&dollar; say &quot;&quot;
</div>

<p> Interestingly, because CGI environments should ignore response fields
unknown to them, for scripts deployed across multiple server platforms it
should be possible to have these WASD-specific elements in every header for
WASD uses followed by other explicitly error page content for use in those
other environments.

<div class="blockof code">&dollar;! WASD error content, plus other platform content
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar; say &quot;Status: 404&quot;
&dollar; say &quot;Script-Control: X-error-text=&quot;&quot;Requested object not found.&quot;&quot;&quot;
&dollar; say &quot;Content-Type: text/html&quot;
&dollar; say &quot;&quot;
&dollar; say &quot;&lt;B&gt;ERROR 404:&lt;/B&gt;&amp;nbsp; Requested object not found.&quot;
</div>

<p> An example implemented using DCL is available

<div class="blockof mono"><a class="link blank" target="_blank" href="/wasd_root/src/other/request_error_msg.com">WASD_ROOT:[SRC.OTHER]REQUEST_ERROR_MSG.COM</a>
</div>

and if currently enabled for scripting

<div class="blockof mono"><a class="link blank" target="_blank" href="/cgi-bin/request_error_msg">/cgi-bin/request_error_msg</a>
</div>

<!-- source:0200_CGI.WASDOC -->
<hr class="page">
<a id="2." href="#"></a>
<a id="2.cgi" href="#"></a>
<a id="cgi" href="#"></a>
<h1 class="head"><span class="numb">2.</span><span class="text">CGI</span></h1>

<div class="TOC2cols2">
<table class="TOC2table">
<tr><td><a href="#2.1.cgienvironmentvariables"><span class="numb">2.1</span><span class="text">CGI Environment Variables</span></a>
<tr><td><a href="#2.2.scriptoutput"><span class="numb">2.2</span><span class="text">Script Output</span></a>
<tr><td><a href="#2.2.1.cgicompliantoutput"><span class="numb">2.2.1</span><span class="text">CGI Compliant Output</span></a>
<tr><td><a href="#2.2.2.nonparsedheaderoutput"><span class="numb">2.2.2</span><span class="text">Non-Parsed-Header Output</span></a>
<tr><td><a href="#2.2.3.bulkcontentoutput"><span class="numb">2.2.3</span><span class="text">Bulk Content Output</span></a>
<tr><td><a href="#2.3.rawhttpinputpostprocessing"><span class="numb">2.3</span><span class="text">Raw HTTP Input (POST Processing)</span></a>
<tr><td><a href="#2.4.cgifunctionlibrary"><span class="numb">2.4</span><span class="text">CGI Function Library</span></a>
<tr><td><a href="#2.5.cgiutlutility"><span class="numb">2.5</span><span class="text">CGIUTL Utility</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#1.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#3.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> The information in this chapter merely outlines the WASD implementation
details, which are in general very much vanilla CGI and NCSA CGI (Common
Gateway Interface) compliant, originally based the INTERNET-DRAFT authored by
D.Robinson (drtr@ast.cam.ac.uk), 8 January 1996, confirmed against the final
RFC 3875, authored by David Robinson (drtr@apache.org) and Ken A.L.Coar
(coar@apache.org), October 2004.

<a id="2.1" href="#"></a>
<a id="2.1.cgienvironmentvariables" href="#"></a>
<a id="cgienvironmentvariables" href="#"></a>
<h2 class="head"><span class="numb">2.1</span><span class="text">CGI Environment Variables</span></h2>

<p> With the standard CGI environment variables are provided to the script via
DCL global symbols. Each CGI variable symbol name is prefixed with &quot;WWW_&quot; (by
default, although this can be changed using the &quot;/CGI_PREFIX&quot; qualifier and the
SET CGIPREFIX mapping rule, see &quot;Features and Facilities&quot;, this is not
recommended if the WASD VMS scripts are to be used, as they expect CGI variable
symbols to be prefixed in this manner).

<p> There are a number of non-&quot;standard&quot; CGI variables to assist in tailoring
scripts for the WASD environment.  Do not make your scripts dependent on any of
these if portability is a goal.

<div class="note">
<a id="2.1.0.0.1" href="#"></a>
<a id="2.1.nevereversubstitute" href="#"></a>
<a id="nevereversubstitute" href="#"></a>
<h5 class="head center"><span class="text">NEVER, EVER substitute...</span></h5>
<hr class="note_hr">
...the content of CGI variables directly into the code stream using
interpreters that will allows this (e.g. DCL, Perl).  You run a very real risk
of having unintended content maliciously change the intended function of the
code.  For example, never use comma substitution of a CGI variable at the DCL
command line as in
<div class="blockof code">&dollar; COPY 'WWW_FORM_SRC' 'WWW_FORM_DST'
</div>
Always pre-process the content of the variable first, ensuring there has
been nothing inserted that could subvert the intended purpose (repeated here to
emphasize the significance of this rule).
<hr class="note_hr">
</div>

<p> CGI variable capacity now varies significantly with VMS version.

<p> The total size of all CGI variable names and values is determined by the
value of [BufferSizeDclCommand] configuration directive, which determines the
total buffer space of a mailbox providing the script's SYS&dollar;COMMAND.  The
default value of 4096 bytes will be ample for the typical CGI script request,
however if it contains very large individual variables or a large number of
form fields, etc., it may be possible to exhaust this quantity.

<a id="2.1.0.0.2" href="#"></a>
<a id="2.1.vmsv732andlaterhellip" href="#"></a>
<a id="vmsv732andlaterhellip" href="#"></a>
<h5 class="head"><span class="text">VMS V7.3-2 and later &hellip;</span></h5>

<p> CGI variables may contain values in excess of 8000 characters (the full
8192 symbol capacity cannot be realized due to the way the symbols are created
via the CLI).  This is a significant increase on earlier capacities.  Mailbox
buffer [BufferSizeDclCommand] may need to be increased if this capacity is to
be fully utilized.

<a id="2.1.0.0.3" href="#"></a>
<a id="2.1.vmsv731andearlierhellip" href="#"></a>
<a id="vmsv731andearlierhellip" href="#"></a>
<h5 class="head"><span class="text">VMS V7.3-1 and earlier &hellip;</span></h5>

<p> Values may contain approximately 1000 characters minus the size of the
variable name.  This should still be sufficient for  most circumstances (if not
consider using CGIplus or ISAPI, extensions to CGI programming which remove
this limitation).  Why such an odd number and why a little rubbery?  A DCL
command line with these versions is limited to 255 characters so the symbols
for larger variables are built up over successive DCL commands with the limit
determined by CLI behaviour.

<a id="2.1.0.0.4" href="#"></a>
<a id="2.1.symboltruncation" href="#"></a>
<a id="symboltruncation" href="#"></a>
<h5 class="head"><span class="text">Symbol Truncation</span></h5>

<p> On VMS V7.3-2 and later symbol capacity should never be an issue (well,
perhaps only with the most extraordinarily poorly designed script).  With VMS
V7.3-1 and earlier, with a symbol value that is too large, the server by
default aborts the request, generating and returning a 500 HTTP status. 
Experience has shown that this occurs <span class="high under">very</span> rarely.  If it does occur it is
possible to instruct the server to instead truncate the CGI variable value and
continue processing.  Any CGI variable that is truncated in such a manner has
its name placed in CGI variable SERVER_TRUNCATE, so that a script can check
for, and take appropriate action on, any such truncation. To have the server
truncate such variables instead of aborting processing SET the path using the
<span class="high italic">script=symbol=truncate</span> mapping rule.  For example

<div class="blockof code">set /cgi-bin/script-name* script=symbol=truncate
</div>

<a id="2.1.0.0.5" href="#"></a>
<a id="2.1.cgivariables" href="#"></a>
<a id="cgivariables" href="#"></a>
<h5 class="head"><span class="text">CGI Variables</span></h5>

<p> Remember, by default all variables are prefixed by &quot;WWW_&quot; (though this may
be modified using the <span class="high italic">set CGIprefix=</span> mapping rule), and not all variables
will be present for all requests.  These CGI environment variables reflect a
combination of HTTP/1.1 and HTTP/1.0 request parameters.

<a id="2.1.0.0.6" href="#"></a>
<a id="2.1.cgienvironmentvariables" href="#"></a>
<a id="cgienvironmentvariables" href="#"></a>
<h5 class="head"><span class="text">CGI Environment Variables</span></h5>
<table class="tabl">
<tr class="tabr under">
<th class="tabh">Name
<th class="tabh">Description
<th class="tabh">Origin
<tr class="tabr">
<tr class="tabr backlight">
<td class="tabd">AUTH_ACCESS
<td class="tabd">&quot;READ&quot; or &quot;READ+WRITE&quot;
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">AUTH_AGENT
<td class="tabd">used by an authorization agent (specialized use)
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">AUTH_GROUP
<td class="tabd">authentication group
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">AUTH_PASSWORD
<td class="tabd">plain-text password, only if EXTERNAL realm
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">AUTH_REALM
<td class="tabd">authentication realm
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">AUTH_REALM_DESCRIPTION
<td class="tabd">browser displayed string
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">AUTH_TYPE
<td class="tabd">authentication type (BASIC or DIGEST)
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">AUTH_USER
<td class="tabd">details of authenticated user
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">CONTENT_LENGTH
<td class="tabd">&quot;Content-Length:&quot; from request header
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">CONTENT_TYPE
<td class="tabd">&quot;Content-Type:&quot; from request header
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">DOCUMENT_ROOT
<td class="tabd">generally empty, configurable path setting
<td class="tabd">Apache
<tr class="tabr">
<td class="tabd">FORM_<span class="high italic">field-name</span>
<td class="tabd">query string &quot;&amp;&quot; separated form elements
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">GATEWAY_BG
<td class="tabd">device name of raw client socket (specialized use)
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">GATEWAY_EOF
<td class="tabd">End of request sentinal (specialized use)
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">GATEWAY_EOT
<td class="tabd">End of callout sentinal (specialized use)
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">GATEWAY_ESC
<td class="tabd">Callout escape sentinal (specialized use)
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">GATEWAY_INTERFACE
<td class="tabd">&quot;CGI/1.1&quot;
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">GATEWAY_MRS
<td class="tabd">maximum record size of script SYS&dollar;OUTPUT
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">HTTP2_PING
<td class="tabd">HTTP/2 server-client RTT ping in (real number) milliseconds
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">HTTP_ACCEPT
<td class="tabd">any list of browser-accepted content types
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_ACCEPT_CHARSET
<td class="tabd">any list of browser-accepted character sets
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_ACCEPT_LANGUAGE
<td class="tabd">any list of browser-accepted languages
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_AUTHORIZATION
<td class="tabd">any from request header (specialized use)
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_CACHE_CONTROL
<td class="tabd">cache control directive
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_COOKIE
<td class="tabd">any cookie sent by the client
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_CONNECTION
<td class="tabd">connection persistence request field
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_FORWARDED
<td class="tabd">any proxy/gateway hosts that forwarded the request
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_HOST
<td class="tabd">host and port request was sent to
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_IF_MATCH
<td class="tabd">if-match request field
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_IF_NONE_MATCH
<td class="tabd">if-none-match request field
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_IF_MODIFIED_SINCE
<td class="tabd">any last modified GMT time string
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_IF_UNMODIFIED_SINCE
<td class="tabd">request field
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_IF_RANGE
<td class="tabd">if-range request field
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_KEEP_ALIVE
<td class="tabd">connection persistence request field
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_PRAGMA
<td class="tabd">any pragma directive of request header
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_REFERER
<td class="tabd">any source document URL for this request
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">HTTP_USER_AGENT
<td class="tabd">client/browser identification string
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">HTTP_X_FORWARDED_FOR
<td class="tabd">proxied client host name or address
<td class="tabd">Squid
<tr class="tabr backlight">
<td class="tabd">HTTP_<span class="high italic">field-name</span>
<td class="tabd">any other request header field
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">KEY_<span class="high italic">n</span>
<td class="tabd">query string &quot;+&quot; separated elements
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">KEY_COUNT
<td class="tabd">number of &quot;+&quot; separated elements
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">PATH_INFO
<td class="tabd">virtual path of data requested in URL
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">PATH_TRANSLATED
<td class="tabd">VMS file path of data requested in URL
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">QUERY_STRING
<td class="tabd">un-URL-decoded string following &quot;?&quot; in URL
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">REMOTE_ADDR
<td class="tabd">IP host address of HTTP client
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">REMOTE_HOST
<td class="tabd">IP host name of HTTP client
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">REMOTE_USER
<td class="tabd">authenticated remote user name (or empty)
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">REQUEST_CHARSET
<td class="tabd">any server-determined request character set
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">REQUEST_METHOD
<td class="tabd">&quot;GET&quot;, &quot;PUT&quot;, etc.
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">REQUEST_PROTOCOL
<td class="tabd">&quot;HTTP/2&quot;, &quot;HTTP/1.1&quot; or &quot;HTTP/1.0&quot;
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">REQUEST_SCHEME
<td class="tabd">&quot;http:&quot; or &quot;https:&quot;
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">REQUEST_TIME_GMT
<td class="tabd">GMT time request received
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">REQUEST_TIME_LOCAL
<td class="tabd">Local time request received
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">REQUEST_URI
<td class="tabd">full, unescaped request string
<td class="tabd">Apache
<tr class="tabr backlight">
<td class="tabd">SCRIPT_DEFAULT
<td class="tabd">mapped default directory for script
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">SCRIPT_FILENAME
<td class="tabd">script file name
(e.g. CGI-BIN:[000000]QUERY.COM)
<td class="tabd">Apache
<tr class="tabr backlight">
<td class="tabd">SCRIPT_NAME
<td class="tabd">script being executed (e.g. &quot;/query&quot;)
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">SERVER_ADDR
<td class="tabd">IP host name of server system
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">SERVER_ADMIN
<td class="tabd">email address for server administration
<td class="tabd">Apache
<tr class="tabr">
<td class="tabd">SERVER_CHARSET
<td class="tabd">server default character set
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">SERVER_GMT
<td class="tabd">offset from GMT (e.g. &quot;+09:30&quot;)
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">SERVER_NAME
<td class="tabd">IP host name of server
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">SERVER_PROTOCOL
<td class="tabd">HTTP protocol version (generally &quot;HTTP/1.1&quot;)
<td class="tabd">CGI
<tr class="tabr">
<td class="tabd">SERVER_PORT
<td class="tabd">IP port request was received on
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">SERVER_SIGNATURE
<td class="tabd">server ID, host name and port
<td class="tabd">Apache
<tr class="tabr">
<td class="tabd">SERVER_SOFTWARE
<td class="tabd">software ID of HTTP server
<td class="tabd">CGI
<tr class="tabr backlight">
<td class="tabd">SERVER_TRUNCATE
<td class="tabd">CGI variable value the server was forced to truncate
<td class="tabd">WASD
<tr class="tabr">
<td class="tabd">UPSTREAM_ADDR
<td class="tabd">address of transparent proxy when client mapped
<td class="tabd">WASD
<tr class="tabr backlight">
<td class="tabd">UNIQUE_ID
<td class="tabd">unique 19 character string
<td class="tabd">Apache
<tr class="tabr">
<td class="tabd">WATCH_SCRIPT
<td class="tabd">only present when script being WATCHed
<td class="tabd">WASD
</table>

<p> If the request path is set to provide them, there are also be variables
providing information about a Secure Sockets Layer transported request's SSL
environment.

<a id="2.1.0.0.7" href="#"></a>
<a id="2.1.querystringvariables" href="#"></a>
<a id="querystringvariables" href="#"></a>
<h5 class="head"><span class="text">Query String Variables</span></h5>

<p> In line with other CGI implementations, additional, non-compliant variables
are provided to ease CGI interfacing.  These provide the various components of
any query string.  A <span class="high italic">keyword</span> query string and a <span class="high italic">form</span> query string are
parsed into

<div class="blockof code">WWW_KEY_<span class="high italic">number</span> 
WWW_KEY_COUNT
WWW_FORM_<span class="high italic">form-element-name</span>
</div>

<p> Variables named WWW_KEY_<span class="high italic">number</span> will be generated if the query
string contains one or more plus (&quot;+&quot;) and no equate symbols
(&quot;=&quot;).

<p> Variables named WWW_FORM_<span class="high italic">form-element-name</span> will be generated if the query
string contains one or more equate symbols.  Generally such a query string is
used to encode form-URL-encoded (MIME type <span class="high italic">x-www-form-urlencoded</span>) requests. 
By default the server will report an incorrect encoding with a 400 error
response.  However some scripts use malformed encodings and so this behaviour
may be suppressed using the <span class="high italic">set script=query=relaxed</span> mapping rule.

<div class="blockof code">set /cgi-bin/script-name* script=query=relaxed
</div>

<p> To suppress this decoding completely (and save a few CPU cycles) use the
following rule.

<div class="blockof code">set /cgi-bin/script-name* script=query=none
</div>

<a id="2.1.0.0.8" href="#"></a>
<a id="2.1.uniqueidnote" href="#"></a>
<a id="uniqueidnote" href="#"></a>
<h5 class="head"><span class="text">UNIQUE_ID Note</span></h5>

<p> The UNIQUE_ID variable is a mostly Apache-compliant implementation (the &quot;_&quot;
has been substituted for the &quot;@&quot; to allow its use in file names), for each
request generating a globally and temporally unique 19 character string that
can be used where such a identifier might be needed.  This string contains only
&quot;A&quot;-&quot;Z&quot;, &quot;a&quot;-&quot;z&quot;, &quot;0&quot;-&quot;9&quot;, &quot;_&quot; and &quot;-&quot; characters and is generated using a
combination of time-stamp, host IP address, server system process identifier
and counter, and is &quot;guaranteed&quot; to be unique in (Internet) space and time. 

<a id="2.1.0.0.9" href="#"></a>
<a id="2.1.vmsapachecswscompliance" href="#"></a>
<a id="vmsapachecswscompliance" href="#"></a>
<h5 class="head"><span class="text">VMS Apache (CSWS) Compliance</span></h5>

<p> WASD v7.0 had its CGI environment tailored slightly to ease portability
between VMS Apache (Compaq Secure Web Server) and WASD.  This included the
provision of an APACHE&dollar;INPUT: stream and several Apache-specific CGI variables
(see the table below). The CGILIB C function library (<a class="link" href="#1.12.scriptingfunctionlibrary">1.12 Scripting Function Library</a>) has also been made CSWS V1.0-1 and later (Apache  1.3.12 and higher)
compliant.

<a id="2.1.0.0.10" href="#"></a>
<a id="2.1.cgivariabledemonstration" href="#"></a>
<a id="cgivariabledemonstration" href="#"></a>
<h5 class="head"><span class="text">CGI Variable Demonstration</span></h5>

<p> The basic CGI symbol names are demonstrated here with a call to a script 
that simply executes the following DCL code:

<div class="blockof code">&dollar; SHOW SYMBOL WWW_*
&dollar; SHOW SYMBOL *
</div>

Note how the request components are represented for &quot;ISINDEX&quot;-style searching
(third item) and a forms-based query (fourth item). 

<table class="tabl">
<tr class="tabr">
<td class="tabd"><a class="link blank monosp" target="_blank" href="/cgi-bin/cgi_symbols">/cgi-bin/cgi_symbols</a>
<tr class="tabr">
<td class="tabd"><a class="link blank monosp" target="_blank" href="/cgi-bin/cgi_symbols/wasd_root/wasdoc/">/cgi-bin/cgi_symbols/wasd_root/wasdoc/</a>
<tr class="tabr">
<td class="tabd"><a class="link blank monosp" target="_blank" href="/cgi-bin/cgi_symbols/wasd_root/wasdoc/*.*?string1+string2">/cgi-bin/cgi_symbols/wasd_root/wasdoc/*.*?string1+string2</a>
<tr class="tabr">
<td class="tabd"><a class="link blank monosp" target="_blank" href="/cgi-bin/cgi_symbols/wasd_root/wasdoc/?FirstField=for&amp;SecondField=this">/cgi-bin/cgi_symbols/wasd_root/wasdoc/?FirstField=for&SecondField=this</a>
</table>

<p> The source code for this simple script is:

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/other/cgi_symbols.com">WASD_ROOT:[SRC.OTHER]CGI_SYMBOLS.COM</a>

<a id="2.2" href="#"></a>
<a id="2.2.scriptoutput" href="#"></a>
<a id="scriptoutput" href="#"></a>
<h2 class="head"><span class="numb">2.2</span><span class="text">Script Output</span></h2>

<p> This information applies to all non-DECnet based scripting, CGI, CGIplus,
RTE, ISAPI.  WASD uses mailboxes for script inter-process communication (IPC). 
These are efficient, versatile and allow direct output from all VMS
environments and utilities.  Like many VMS record-oriented devices however
there are some things to consider when using them (also see <a class="link" href="#2.2.1.ipctickler">&lsquo;IPC Tickler&rsquo; in 2.2.1 CGI Compliant Output</a>).

<ul class="list">

<li class="item"> <span class="high bold">Record-Oriented</span>

<p> The mailboxes are created record, not stream oriented.  This means records
output by standard VMS means (e.g. DCL, utilities, programming languages) are
discretely identified and may be processed appropriately by the server as text
or binary depending on the content-type.

<li class="item"> <span class="high bold">Maximum Record Size</span>

<p> Being record oriented there is a maximum record size (MRS) that can be
output.  Records larger than this result in SYSTEM-F-MBTOOSML errors.  The WASD
default is 4096 bytes.  This may be changed using the [BufferSizeDclOutput]
configuration directive.  This allocation consumes process BYTLM with each
mailbox created so the account must be dimensioned sufficiently to supply
demands for this quota.  The maximum possible size for this is a VMS-limit of
60,000 bytes.

<li class="item"> <span class="high bold">Buffer Space</span>

<p> When created the mailbox has its buffer space set.  With WASD IPC
mailboxes this is the same as the MRS.  The total data buffered may not exceed
this without the script entering a wait state (for the mailbox contents to be
cleared by the server).  As mailboxes use a little of the buffer space to
delimit records stored in it the amount of data is actually less than the total
buffer space.

</ul>

<p> To determine the maximum record size and total capacity of the mailbox
buffer between server and script WASD provides a CGI environment variable,
GATEWAY_MRS, containing an integer with this value.

<a id="2.2.1" href="#"></a>
<a id="2.2.1.cgicompliantoutput" href="#"></a>
<a id="cgicompliantoutput" href="#"></a>
<h3 class="head"><span class="numb">2.2.1</span><span class="text">CGI Compliant Output</span></h3>

<p> Script response may be CGI or NPH compliant (<a class="link" href="#2.2.2.nonparsedheaderoutput">2.2.2 Non-Parsed-Header Output</a>).  CGI compliance means the script's response must begin with a line
containing one of the following fields.

<ul class="list list0">
<li class="item"> <span class="high bold">Status: </span> an HTTP status code and associated explanation string
<li class="item"> <span class="high bold">Content-Type: </span> the script body's MIME content-type
<li class="item"> <span class="high bold">Location: </span> a redirection URL (absolute or relative)
</ul>

<p> Other HTTP-compliant response fields may follow, with the response header
terminated and the response body begun by a single empty line.  The following 
are examples of CGI-compliant responses.

<div class="blockof code">Content-Type: text/html
Content-Length: 35

&lt;HTML&gt;
&lt;B&gt;Hello world!&lt;/B&gt;
&lt;/HTML&gt;
</div>
 And using the status field.

<div class="blockof code">Status: 404 Not Found
Content-Type: text/plain

Huh?
</div>

<p> Strict CGI output compliance can be enabled and disabled using the
[CgiStrictOutput] configuration directive.  With it disabled the server will
accept any output from the script, if not CGI or NPH compliant then it
automatically generates plain-text header.  When enabled, if not a CGI or NPH
header the server returns a &quot;502 Bad Gateway&quot; error.  For debugging
scripts generating this error introduce a <span class="high italic">plain-text</span> debug mode and
header, or use the WATCH facility's CGI item (see Features and Facilities).

<a id="2.2.1.0.1" href="#"></a>
<a id="2.2.1.outputandhttp11" href="#"></a>
<a id="outputandhttp11" href="#"></a>
<h5 class="head"><span class="text">Output and HTTP/1.1</span></h5>

<p> With HTTP/1.1 it is generally better to use CGI than NPH responses.  A CGI
response allows the server to parse the response header and  from that make
decisions about connection persistence and content-encoding.  These can
contribute significantly to reducing response latency and content transfer
efficiency.  It allows any policy established by server configuration for such
characteristics to be employed.

<a id="2.2.1.0.2" href="#"></a>
<a id="2.2.1.wasdspecifics" href="#"></a>
<a id="wasdspecifics" href="#"></a>
<h5 class="head"><span class="text">WASD Specifics</span></h5>

<p> This section describes how WASD deals with some particular output issues
(also see <a class="link" href="#2.2.1.ipctickler">&lsquo;IPC Tickler&rsquo; in 2.2.1 CGI Compliant Output</a>).

<ul class="list">

<li class="item"> <span class="high bold">Content-Type: text/&hellip;</span>

<p> If the script response content-type is &quot;text/&hellip;&quot; (text
document) WASD assumes that output will be line-oriented and requiring HTTP
carriage-control (each record/line terminated by a line-feed), and will ensure
each record it receives is correctly terminated before passing it to the
client.  In this way DCL procedure output (and the VMS environment in general)
is supported transparently.  Any other content-type is assumed to be
<span class="high italic">binary</span> and no carriage-control is enforced.  This default behaviour
may be modified as described below.

<li class="item"> <span class="high bold">Carriage-Control</span>

<p> Carriage-control behaviour for <span class="high under">any</span> content-type may be
explicitly set using either of two additional response header fields.  The term
<span class="high italic">stream</span> is used to describe the server just transfering records,
without  additional processing, as they were received from the script.  This is
obviously necessary for binary/raw content such as images, octet-streams, etc.
The term <span class="high italic">record</span> describes the server ensuring each record it
receives has correct carriage-control - a trailing newline.  If not present one
is added.  This mode is useful for VMS textual streams (e.g. output from DCL
and VMS utilities).

<p> Using the Apache Group's proposed CGI/1.2 &quot;Script-Control:&quot; field.  The WASD
extension-directives <span class="high italic">X-record-mode</span> and <span class="high italic">X-stream-mode</span> sets the script
output into each of the respective modes (<a class="link" href="#2.2.1.scriptcontrol">&lsquo;Script-Control:&rsquo; in 2.2.1 CGI Compliant Output</a>).

<p> Examples of usage this field:

<div class="blockof code">Script-Control: X-stream-mode
Script-Control: X-record-mode
</div>

<li class="item"> <span class="high bold">Script Output Buffering</span>

<p> By default WASD writes each record received from the script to the
client as it is received.  This can range from a single byte to a complete
mailbox buffer full.  WASD leaves it up to the script to determine the rate at
which output flows back to the client.

<p> While this allows a certain flexibility it can be inefficient.  There will
be many instances where a script will be providing just a body of data to the
client, and wish to do it as quickly and efficiently as possible.  Using the
proposed CGI/1.2 &quot;Script-Control:&quot; field with the WASD extension
directive <span class="high italic">X-buffer-records</span> a script can direct the server to buffer
as many script output records as possible before transfering it to the client. 
The following should be added to the CGI response header.

<div class="blockof code">Script-Control: X-buffer-records
</div>

<p> While the above offers some significant improvements to efficiency and
perceived throughput the best approach is for the script to provide records the
same size as the mailbox (<a class="link" href="#2.2.scriptoutput">2.2 Script Output</a>) for detail on
determining this size if required).  The can be done explicitly by the script
programming or if using the C language simply by changing <span class="high italic">stdout</span>
to a binary stream.  With this environment the C-RTL will control output,
automatically buffering as much as possible before writing it to the server.

<div class="blockof code">if ((stdout = freopen (&quot;SYS&dollar;OUTPUT&quot;, &quot;w&quot;, stdout, &quot;ctx=bin&quot;)) == NULL)
   exit (vaxc&dollar;errno);
</div>

<p> Also see the section describing <a class="link" href="#2.2.2.nphcscript">&lsquo;NPH C Script&rsquo; in 2.2.2 Non-Parsed-Header Output</a>.

</ul>

<a id="2.2.1.0.3" href="#"></a>
<a id="2.2.1.crtlfeatures" href="#"></a>
<a id="crtlfeatures" href="#"></a>
<h5 class="head"><span class="text">C-RTL Features</span></h5>

<p> Non-C Runtime Libraries (C-RTL) do not contend with records delimitted by
embedded characters (the newlines and nulls, etc., of the C environment).  They
use VMS' and RMS' default record-oriented I/O.  The C-RTL needs to accomodate
the C environment's <span class="high italic">bag-o'-bytes</span> paradigm for file content against
RMS' record structures, and it's embedded terminator, stream-oriented I/O with
unterminated, record-oriented I/O. Often this results in a number of issues
particularly with code ported from *x environments.

<p> The C-RTL behaviour can be modified in all sorts of ways, including some
file and other I/O characteristics.  The features available to such
modification are incrementally increasing with each release of the C-RTL and/or
C compiler.  It is well advised to consult the latest release (or as
appropriate for the local environment) of the Run-Time Library Reference Manual
for OpenVMS Systems for the current set.

<p> Behaviours are modified by setting various flags, either from within the
program itself using thef using the decc&dollar;feature_set() and allied group of
functions, or by defining an equivalent logical name, usually externally to and
before executing the image.  See C-RTL Reference Manual section Enabling C RTL
Features Using Feature Logical Names.  This is particularly useful if the
source is unavailable or just as a simpler approach to modifying code.

<p> An example of a useful feature and associated logical name is
<span class="high bold">DECC&dollar;STDIO_CTX_EOL</span> which when enabled &quot;writing to
stdout and stderr for stream access is deferred until a terminator is seen
or the buffer is full&quot; in contrast to the default behaviour of &quot;each
fwrite  generates a separate write, which for mailbox and record files
generates a separate record&quot;.  For an application performing write()s or
fwrite()s with a record-oriented &lt;stdio&gt; and generating
inappropriate record boundaries the application could be wrapped as follows (a
real-world example).

<div class="blockof code">&dollar; set noon
&dollar; define/user/nolog sys&dollar;input http&dollar;input
&dollar; define/user DECC&dollar;STDIO_CTX_EOL ENABLE
&dollar; calcserver
&dollar; exit(1)
</div>

<a id="2.2.1.0.4" href="#"></a>
<a id="2.2.1.ipctickler" href="#"></a>
<a id="ipctickler" href="#"></a>
<h5 class="head"><span class="text">IPC Tickler</span></h5>

<p> The interactions between VMS' record-oriented I/O, various run-time
libraries (in particular the C-RTL), the streaming character-oriented Web, and
of course WASD, can be quite complex and result in unintended output or
formatting.  The CGI script Inter-Process Communication (IPC) tickler
<a class="link blank" target="_blank" href="/wasd_root/src/misc/IPCtickler.c">WASD_ROOT:[SRC.MISC]IPCTICKLER.C</a> is
designed to allow a script programmer to gain an appreciation of how these
elements interact, how WASD attempts to accomodate them, what mechanisms a
script can use to explicitly convey exact requirements to WASD ... and finally,
how these affect output (in particular the carriage-control) delivered to the
client.  If installed use <a class="link blank" target="_blank" href="/cgi-bin/IPCtickler">/cgi-bin/IPCtickler</a> to obtain an HTML form
allowing control of several parameters into the script.

<a id="2.2.1.0.5" href="#"></a>
<a id="2.2.1.scriptcontrol" href="#"></a>
<a id="scriptcontrol" href="#"></a>
<h5 class="head"><span class="text">Script-Control:</span></h5>

<p> The <span class="high italic">Apache Group</span> has proposed a CGI/1.2 that includes a
<span class="high italic">Script-Control:</span> CGI response header field.  WASD implements the
one proposed directive, along with a number of WASD extensions (those
beginning with the &quot;X-&quot;).  Note that by convention extensions unknown by
an agent should be ignored, meaning that they can be freely included, only
being meaningful to WASD and not significant to other implementations.

<ul class="list">

<li class="item"> <span class="high bold">no-abort &ndash; </span>
The server must not terminate the script during processing for either
no output or no-progress timeouts.  The script is to be left completely alone
to control its own termination.  Caution, such scripts if problematic could
easily accumulate and &quot;clog up&quot; a server or system.

<li class="item"> <span class="high bold">X-buffer-records[=0&verbar;1] &ndash; </span>
Buffer records written by the script until there is [BufferSizeDclOutput] bytes
available then write it as a single block to the client.  The optional zero
returns the script to non-buffered records, a one enables record buffering.

<li class="item"> <span class="high bold">X-content-encoding-gzip[=0&verbar;1] &ndash; </span>
A script by specifying a zero can request that the server, by default encoding
the response using GZIP compression, leaves the response unencoded.  By
specifying a one a script can request the server to encode the response using
GZIP compression.

<li class="item"> <span class="high bold">X-content-handler=<span class="high italic">keyword</span>  &ndash; </span>
The output of the script is stripped of the CGI reponse header and the body is
given to the specified content handler.  Currently only the SSI engine is
supported using &quot;X-content-handler=SSI&quot;.

<li class="item"> <span class="high bold">X-crlf-mode[=0&verbar;1] &ndash; </span>
The server should always ensure each record has trailing carriage-return then
newline characters (0x0d, 0x0a).  This is generally what VMS requires for
carriage control on terminals, printers, etc.  The optional zero returns the
script to record mode, a one enables CR-LF mode.

<li class="item"> <span class="high bold">X-error-line=<span class="high italic">integer</span> &ndash; </span>
Source code module line number META in server generated error message
(optional).

<li class="item"> <span class="high bold">X-error-module=<span class="high italic">string</span> &ndash; </span>
Source code module name META in server generated error message (optional).

<li class="item"> <span class="high bold">X-error-text=&quot;<span class="high italic">string</span>&quot; &ndash; </span>
Text of error message (mandatory, to trigger server message generation).  If
without a VMS status value this is the entire error explanation.  If with a VMS
status it becomes the context of the status.

<li class="item"> <span class="high bold">X-error-vms-status=<span class="high italic">integer</span> &ndash; </span>
VMS status value in decimal or VMS hexadecimal (e.g. %X0000002C, optional).
Changes format of error message to detailed explanation of status.

<li class="item"> <span class="high bold">X-error-vms-text=&quot;<span class="high italic">string</span>&quot; &ndash; </span>
Context of a VMS status value (optional).  Usually a VMS file specification of
other text related to the status value (in commented content of error message).

<li class="item"> <span class="high bold">X-http-status=<span class="high italic">integer</span> &ndash; </span>
Forces the HTTP response line status to this value regardless of the status in
the CGI <span class="high italic">Status:</span> response or the server status if being used as an
error reporting script

<li class="item"> <span class="high bold">X-lifetime=<span class="high italic">value</span> &ndash; </span>
The number of minutes before the idle scripting process is deleted by the
server.  Zero sets it back to the default, &quot;none&quot; disables this
functionality. 

<li class="item"> <span class="high bold">X-record-mode[=0&verbar;1] &ndash; </span>
The server should always ensure each record has a trailing newline
character (0x0a), regardless of whether the response is a <span class="high italic">text/...</span>
content-type or not.  This is what is usually required by browsers for
carriage-control in text documents.  The optional zero changes the script to
stream mode, a one enables record mode.

<li class="item"> <span class="high bold">X-record0-mode[=0&verbar;1] &ndash; </span>
Some (C-RTL) carriage-control modes result in empty records being sent in lieu
of carriage control (newlines).  This (rather esoteric) mode only adds a
newline to empty records.

<li class="item"> <span class="high bold">X-stream-mode[=0&verbar;1] &ndash; </span>
The server is not to adjust the carriage-control of records regardless of
whether the response is a <span class="high italic">text/...</span> content-type or not.  What the
script writes is exactly what the client is sent.  The optional zero returns
the script to record mode, a one enables stream mode.

<li class="item"> <span class="high bold">X-timeout-noprogress=<span class="high italic">value</span> &ndash; </span>
The number of minutes allowed where the script does not transfer any data to
the server before the server deletes the process.  Zero sets it back to the
default, &quot;none&quot; disables this functionality. 

<li class="item"> <span class="high bold">X-timeout-output=<span class="high italic">value</span> &ndash; </span>
The number of minutes allowed before an active script is deleted by the server,
regardless of it still processing the request.  Zero sets it back to the
default, &quot;none&quot; disables this functionality. 

</ul>

<p> The following is a simple example response where the server is instructed
not to delete the script process under any circumstances, and that the body
does not require any carriage-control changes.

<div class="blockof code">Content-Type: text/plain
Script-Control: no-abort; X-stream-mode

<span class="high italic">long, slowww script-output &hellip;</span>
</div>

<a id="2.2.1.0.6" href="#"></a>
<a id="2.2.1.exampledclscripts" href="#"></a>
<a id="exampledclscripts" href="#"></a>
<h5 class="head"><span class="text">Example DCL Scripts</span></h5>

<p> A simple script to provide the system time might be:

<div class="blockof code">&dollar; say = &quot;write sys&dollar;output&quot;
&dollar;! the next two lines make it CGI-compliant
&dollar; say &quot;Content-Type: text/plain&quot;
&dollar; say &quot;&quot;
&dollar;! start of plain-text body
&dollar; show time
</div>

<p> A script to provide the system time more elaborately (using HTML):

<div class="blockof code">&dollar; say = &quot;write sys&dollar;output&quot;
&dollar;! the next two lines make it CGI-compliant
&dollar; say &quot;Content-Type: text/html&quot;
&dollar; say &quot;&quot;
&dollar;! start of HTML script output
&dollar; say &quot;&lt;HTML&gt;&quot;
&dollar; say &quot;Hello ''WWW_REMOTE_HOST'&quot;  !(CGI variable)
&dollar; say &quot;&lt;P&gt;&quot;
&dollar; say &quot;System time on node ''f&dollar;getsyi(&quot;nodename&quot;)' is:&quot;
&dollar; say &quot;&lt;H1&gt;''f&dollar;cvtime()'&lt;/H1&gt;&quot;
&dollar; say &quot;&lt;/HTML&gt;&quot;
</div>

<a id="2.2.2" href="#"></a>
<a id="2.2.2.nonparsedheaderoutput" href="#"></a>
<a id="nonparsedheaderoutput" href="#"></a>
<h3 class="head"><span class="numb">2.2.2</span><span class="text">Non-Parsed-Header Output</span></h3>

<p> A script does not have to output a CGI-compliant data stream.  If it begins
with a HTTP header status line WASD assumes it will supply a <span class="high bold">raw</span> HTTP data
stream, containing all the HTTP requirements.  This is the same as or
equivalent to the <span class="high italic">non-parsed-header</span>, or &quot;nph&hellip;&quot; scripts of many
environments.  This is an example of such a script response.

<div class="blockof code">HTTP/1.0 200 Success
Content-Type: text/html
Content-Length: 35

&lt;html&gt;
&lt;b&gt;Hello world!&lt;/b&gt;
&lt;/html&gt;
</div>

<p> Any such script must observe the HyperText Transfer Protocol, supplying a
<span class="high bold">full response header and body, including correct carriage-control</span>.  Once
the server detects the HTTP status header line it pays no more attention to any
response header fields or body records, just transfering everything directly to
the client.  This can be very efficient, the server just a conduit between
script and client, but does transfer the responsibility for a correct HTTP
response onto the script.

<a id="2.2.2.0.1" href="#"></a>
<a id="2.2.2.nphdclscript" href="#"></a>
<a id="nphdclscript" href="#"></a>
<h5 class="head"><span class="text">NPH DCL Script</span></h5>

<p> The following example shows a DCL script.  Note the full HTTP header and
each line explicitly terminated with a carriage-return and line-feed pair. 

<div class="blockof code">&dollar; lf[0,8] = %x0a
&dollar; crlf[0,16] = %x0d0a
&dollar; say = &quot;write sys&dollar;output&quot;
&dollar;! the next line determines that it is raw HTTP stream
&dollar; say &quot;HTTP/1.0 200 Success&quot; + crlf
&dollar; say &quot;Content-Type: text/html&quot; + crlf
&dollar;! response header separating blank line
&dollar; say crlf
&dollar;! start of HTML script output
&dollar; say &quot;&lt;html&gt;&quot; + lf 
&dollar; say &quot;Hello ''WWW_REMOTE_HOST'&quot; + lf 
&dollar; say &quot;&lt;p&gt;&quot; + lf 
&dollar; say &quot;Local time is ''WWW_REQUEST_TIME_LOCAL'&quot; + lf 
&dollar; say &quot;&lt;/html&gt;&quot; + lf 
</div>

<a id="2.2.2.0.2" href="#"></a>
<a id="2.2.2.nphcscript" href="#"></a>
<a id="nphcscript" href="#"></a>
<h5 class="head"><span class="text">NPH C Script</span></h5>

<p> When scripting using the C programming language there can be considerable
efficiencies to be gained by providing a binary output stream from the script. 
This results in the C Run-Time Library (C-RTL) buffering output up to the
maximum supported by the IPC mailbox.  This may be enabled using a code
construct similar to following to reopen <span class="high italic">stdout</span> in binary mode.

<div class="blockof code">if ((stdout = freopen (&quot;SYS&dollar;OUTPUT&quot;, &quot;w&quot;, stdout, &quot;ctx=bin&quot;)) == NULL)
   exit (vaxc&dollar;errno);
</div>

<p> This is used consistently in WASD scripts.  Carriage-control must be
supplied as part of the C standard output (no differently to any other C
program).  Output can be be explicitly sent to the client at any stage using
the <span class="high italic">fflush()</span> standard library function.  Note that if the
<span class="high italic">fwrite()</span> function is used the current contents of the C-RTL buffer
are automatically flushed along the the content of the fwrite().

<div class="blockof code">fprintf (stdout,
&quot;HTTP/1.0 200 Success\r\n\
Content-Type: text/html\r\n\
\r\n\
&lt;HTML&gt;\n\
Hello %s\n\
&lt;P&gt;\n\
System time is %s\n\
&lt;/HTML&gt;\n&quot;,
getenv(&quot;WWW_REMOTE_HOST&quot;),
getenv(&quot;WWW_REQUEST_TIME_LOCAL&quot;));
</div>

<a id="2.2.3" href="#"></a>
<a id="2.2.3.bulkcontentoutput" href="#"></a>
<a id="bulkcontentoutput" href="#"></a>
<h3 class="head"><span class="numb">2.2.3</span><span class="text">Bulk Content Output</span></h3>

<p> As described above, <a class="link" href="#2.2.scriptoutput">2.2 Script Output</a>, the default script<span class="high monosp">&lt;-&gt;</span>server
IPC uses a mailbox.  While versatile and sufficiently efficient for general
use, when megabytes, tens of megabytes, and hundreds of megabytes need to be
transferred, using a memory buffer shared between script and server can yield
transfer <span class="high bold">improvements of up to 500%</span>. 

<div class="note center">
<a id="2.2.3.0.1" href="#"></a>
<a id="2.2.3.ymmv" href="#"></a>
<a id="ymmv" href="#"></a>
<h5 class="head center"><span class="text">YMMV</span></h5>
<hr class="note_hr">
Of course, your mileage may vary with platform, O/S version and TCP/IP stack
(i.e. as the relative bottlenecks shuffle about).
<hr class="note_hr">
</div>

<p> The script requests a memory-buffer using a CGI callout (<a class="link" href="#6.cgicallouts">6. CGI Callouts</a>).  Buffer size is constrained by the usual VMS 32bit memory
considerations, along with available process and system resources.  The server
creates and maps a non-permanent global section.  If this is successful the
script is advised of the global section name using the callout response.  The
script uses this to map the section name and can then populate the buffer. 
When the buffer is full or otherwise ready, the script issues a callout with
the number of bytes to write, and then stalls.  The complete memory buffer may
be written at once or any subsection of that buffer. The write is accomplished
asynchronously and may comprise multiple network &dollar;QIOs or TLS/SSL blocks.  When
complete, a callout response to the script is issued and the script can
continue processing.  Standard script mailbox I/O (SYS&dollar;OUTPUT, &lt;stdout&gt;) and
memory-buffer I/O may be interleaved as required.

<p> The callouts are as follows:

<ul class="list">

<li class="item"> <span class="high bold">BUFFER-BEGIN:</span> <span class="high italic">&lt;integer&gt;[k&verbar;M]</span>

<p> Create a temporary global section to act as a memory buffer shared between a
script process and the server.  The default is <span class="high bold">M</span>egabytes.

<li class="item"> <span class="high bold">BUFFER-END:</span>

<p> Dispose of the shared memory buffer created by callout BUFFER-BEGIN.

<li class="item"> <span class="high bold">BUFFER-WRITE:</span> <span class="high italic">&lt;integer&gt;</span>

<p> Instruct the server to write &lt;integer&gt; bytes from the shared
memory buffer to the client.

</ul>

<p> See working examples in
<a class="link blank" target="_blank" href="/wasd_root/src/misc/*membuf*.*">WASD_ROOT:[SRC.MISC]</a>.

<p> Actual data comparing standard mailbox IPC with memory-buffer generated
using [SRC.MISC]MEMBUFDEMO.C on a HP rx2660 (1.40GHz/6.0MB) with 4 CPUs and
16383MB running VSI VMS V8.4-2L1 with Multinet UCX&dollar;IPC_SHR V55A-B147, OpenSSL
1.0.2k and WASD v11.2.0, with [BufferSizeDclOutput] 16384.  In each case 250MB
(&quot;?250&quot;) is transfered via a either a 16.4kB mailbox (default) or 16.4kB memory
buffer (&quot;+b&quot;).  Significantly larger memory buffer may well improve throughput
further.

<div class="blockof code">&dollar;  wget &quot;-O&quot; nl: http://127.0.0.1/cgi-bin/membufdemo?250
--2017-10-14 03:19:05--  http://127.0.0.1/cgi-bin/membufdemo?250
Connecting to 127.0.0.1:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M) [application/octet-stream]
Saving to: 'nl:'

nl:                 100%[=====================&gt;] 250.00M  25.6MB/s   in 12s

2017-10-14 03:19:17 (20.5 MB/s) - 'nl:' saved [262144000/262144000]

&dollar;  wget &quot;-O&quot; nl: http://127.0.0.1/cgi-bin/membufdemo?250+b
--2017-10-14 03:19:23--  http://127.0.0.1/cgi-bin/membufdemo?250+b
Connecting to 127.0.0.1:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M) [application/octet-stream]
Saving to: 'nl:'

nl:                 100%[=====================&gt;] 250.00M   105MB/s   in 2.4s

2017-10-14 03:19:26 (105 MB/s) - 'nl:' saved [262144000/262144000]

&dollar;  wget &quot;-O&quot; nl: https://127.0.0.1/cgi-bin/membufdemo?250
--2017-10-14 03:19:50--  https://127.0.0.1/cgi-bin/membufdemo?250
Connecting to 127.0.0.1:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M) [application/octet-stream]
Saving to: 'nl:'

nl:                 100%[=====================&gt;] 250.00M  14.5MB/s   in 17s

2017-10-14 03:20:07 (14.5 MB/s) - 'nl:' saved [262144000/262144000]

&dollar;  wget &quot;-O&quot; nl: https://127.0.0.1/cgi-bin/membufdemo?250+b
--2017-10-14 03:20:12--  https://127.0.0.1/cgi-bin/membufdemo?250+b
HTTP request sent, awaiting response... 200 OK
Length: 262144000 (250M) [application/octet-stream]
Saving to: 'nl:'

nl:                 100%[=====================&gt;] 250.00M  16.6MB/s   in 15s

2017-10-14 03:20:27 (16.6 MB/s) - 'nl:' saved [262144000/262144000]
</div>

<p> It is obvious that memory-buffer provides significantly greater throughput
than mailbox (from the http:// test) and that with TLS/SSL network transport
the encryption becomes a significant overhead and choke-point.  Nevertheless,
there is still an approximate 15% dividend, plus the more efficient interface
the script-&gt;memory-buffer-&gt;server provides.  The VMS TLS/SSL implementation may
improve with time, especially if TLS/SSL hardware engines become available with
the port to x86_64.

<div class="note">
<a id="2.2.3.0.2" href="#"></a>
<a id="2.2.3.postscript" href="#"></a>
<a id="postscript" href="#"></a>
<h5 class="head center"><span class="text">Postscript</span></h5>
<hr class="note_hr">
The comparison also illustrates that the WASD environment can deliver
significant bandwidth through its script<span class="high monosp">-&gt;</span>server<span class="high monosp">-&gt;</span>network pathways. On
the demonstration class of system; ~200Mbps unencrypted and  ~120Mbps encrypted
using the standard mailbox IPC; with ~850Mbps unencrypted and ~130Mbps
encrypted using the memory-buffer IPC.
<hr class="note_hr">
</div>

<a id="2.3" href="#"></a>
<a id="2.3.rawhttpinputpostprocessing" href="#"></a>
<a id="rawhttpinputpostprocessing" href="#"></a>
<h2 class="head"><span class="numb">2.3</span><span class="text">Raw HTTP Input (POST Processing)</span></h2>

<p> For POST and PUT HTTP methods (e.g. a POSTed HTML form) the body of the
request may be read from the HTTP&dollar;INPUT stream.  For executable image scripts
requiring the body to be present on SYS&dollar;INPUT (the C language <span class="high italic">stdin</span> stream)
a user-mode logical may be defined immediately before invoking the image, as in
the example.

<div class="blockof code">&dollar; EGSCRIPT = &quot;&dollar;WASD_EXE:EGSCRIPT.EXE&quot;
&dollar; DEFINE /USER SYS&dollar;INPUT HTTP&dollar;INPUT
&dollar; EGSCRIPT
</div>

<p> The HTTP&dollar;INPUT stream may be explicitly opened and read.  Note that this is
a raw stream, and HTTP <span class="high italic">lines</span> (carriage-return/line-feed terminated sequences
of characters) may have been blocked  together for network transport.  These
would need to be explicity parsed by the program.

<div class="blockof code">if ((HttpInput = fopen (&quot;HTTP&dollar;INPUT&quot;, &quot;r&quot;, &quot;ctx=bin&quot;)) == NULL)
   exit (vaxc&dollar;errno);
</div>

<p> When scripting using the C programming language there is a tendency for the
C-RTL to check for and/or add newline (0x10, &lt;LF&gt;) carriage-control on receipt
of record (single write).  While this can be useful in converting from VMS to C
conventions it can also be counter-productive if the stream being received is
already using C carriage-control.  To prevent the C-RTL reinterpreting data
passed to it it often, perhaps invariably, necessary to reopen the input stream
as binary using a construct similar to following.

<p> This, and its &lt;stdin&gt; equivalent (below), are used consistently in WASD
scripts.

<div class="blockof code">if ((stdin = freopen (&quot;HTTP&dollar;INPUT&quot;, &quot;r&quot;, stdin, &quot;ctx=bin&quot;)) == NULL)
   exit (vaxc&dollar;errno);

if ((stdin = freopen (&quot;SYS&dollar;INPUT&quot;, &quot;r&quot;, stdin, &quot;ctx=bin&quot;)) == NULL)
   exit (vaxc&dollar;errno);
</div>

<p> <span class="high bold">The input stream should be read before generating any output.</span>  If an
error occurs during the body processing it should be reported via a CGI
response header indicating an error (i.e. non-200).  With HTTP/1.1 request
processing there is also a requirement (that CGILIB fulfills) to return a &quot;100
Continue&quot; interim response after receiving the client request header and before
the client sends the request body.  Output of anything before this &quot;100
Continue&quot; is delivered will cause it to be interleaved with the script response
body.

<a id="2.4" href="#"></a>
<a id="2.4.cgifunctionlibrary" href="#"></a>
<a id="cgifunctionlibrary" href="#"></a>
<h2 class="head"><span class="numb">2.4</span><span class="text">CGI Function Library</span></h2>

<p> A source code collection of C language functions useful for processing the
more vexing aspects of CGI/CGIplus programming
(<a class="link" href="#1.12.scriptingfunctionlibrary">1.12 Scripting Function Library</a>).

<a id="2.5" href="#"></a>
<a id="2.5.cgiutlutility" href="#"></a>
<a id="cgiutlutility" href="#"></a>
<h2 class="head"><span class="numb">2.5</span><span class="text">CGIUTL Utility</span></h2>

<p> This assists with the generation of HTTP responses, including the transfer
of binary content from files (copying a file back to the client as part of the
request), and the processing of the contents of POSTed requests from DCL
(<a class="link" href="#2.5.cgiutlutility">2.5 CGIUTL Utility</a>).
<!-- source:0300_CGIPLUS.WASDOC -->
<hr class="page">
<a id="3." href="#"></a>
<a id="3.cgiplus" href="#"></a>
<a id="cgiplus" href="#"></a>
<h1 class="head"><span class="numb">3.</span><span class="text">CGIplus</span></h1>

<table class="TOC2table">
<tr><td><a href="#3.1.cgiplusprogramming"><span class="numb">3.1</span><span class="text">CGIplus Programming</span></a>
<tr><td><a href="#3.2.codeexamples"><span class="numb">3.2</span><span class="text">Code Examples</span></a>
<tr><td><a href="#3.3.otherconsiderations"><span class="numb">3.3</span><span class="text">Other Considerations</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#2.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#4.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<style type="text/css">._cgipplus th { padding:0 0.3em 0 0.3em; font-size:1.1em; } </style>
<table class="tabl noindent _cgipplus">
<tr class="tabr">
<th class="tabh">Common Gateway Interface
<th class="tabh">&hellip;
<th class="tabh">plus lower latency,
<tr class="tabr">
<th class="tabh">
<th class="tabh">
<th class="tabh">plus greater throughput,
<tr class="tabr">
<th class="tabh">
<th class="tabh">
<th class="tabh">plus far less system impact!
</table>

<p> <span class="high" style="font-size:1.1em;">I know, I know!  The term <span class="high under">CGIplus</span> is a bit <span class="high under">too cute</span>
but I had to call it something!</span>

<p> CGIplus attempts to eliminate the overhead associated with creating the
script process and then executing the image of a CGI script.  It does this by
allowing the script process and any associated image/application to continue
executing between uses, eliminating startup overheads.  This reduces both the
load on the system and the request latency.  In this sense these advantages
parallel those offered by commercial HTTP server-integration APIs, such as
Netscape NSAPI and Microsoft ISAPI, without the disadvantages of such
proprietory interfaces, the API complexity, language dependency and server
process integration.

<p> Existing CGI scripts can rapidly and elegantly be modified to
additionally support CGIplus. The capability of scripts to easily
differentiate between and operate in both standard CGI and CGIplus
environments with a minimum of code revision offers great versatility.  Many
WASD scripts operate in both environments.

<a id="3.0.0.0.1" href="#"></a>
<a id="3.cgiplusperformance" href="#"></a>
<a id="cgiplusperformance" href="#"></a>
<h5 class="head"><span class="text">CGIplus Performance</span></h5>

<p> A simple performance evaluation indicates the advantage of CGIplus.  See
&quot;Techncial Overview, Performance&quot; for some test results comparing the
CGI and CGIplus environments.

<p> Without a doubt, the subjective difference in activating the same script
within the standard CGI and CGIplus environments is quite startling!

<a id="3.1" href="#"></a>
<a id="3.1.cgiplusprogramming" href="#"></a>
<a id="cgiplusprogramming" href="#"></a>
<h2 class="head"><span class="numb">3.1</span><span class="text">CGIplus Programming</span></h2>

<p> <span class="high bold">The script interface is still CGI</span>, with all the usual
environment variables and input/output streams available, which means a new API
does not need to be learned and existing CGI scripts are simple to modify.

<p> See examples in
<a class="link blank" target="_blank" href="/wasd_root/src/CGIplus/*.*">WASD_ROOT:[SRC.CGIPLUS]</a>

<p> Instead of having the CGI variables available from the environment
(generally accessed via the C Language <span class="high italic">getenv()</span> standard library
call, or via DCL symbols) a CGIplus script must read the CGI variables from an
I/O stream named CGIPLUSIN.  The variables can be supplied in one of two modes.

<ul class="list">

<li class="item"> <span class="high bold">Record Mode &ndash; </span> Each CGI variable is supplied as an individual
record (line).  This is the default, and simplest method.  Each contains a CGI
variable name (in upper-case), an equate symbol and then the variable value.
The format may be easily parsed and as the value contains no encoded characters
may be directly used.  The quantity of characters in each record depends on the
size of the variable name and the length of the associated value.  The value
can vary from zero, to tens, hundreds, even thousands of characters.  It is
limited by the size of the CGIPLUSIN mailbox, which is in turn set by the
[BufferSizeDclCgiPlusIn] configuration directive.

<li class="item"> <span class="high bold">Struct Mode &ndash; </span> All variables are supplied in a binary structure
which must be parsed by the receiving script.  This is the most efficient
method for providing the CGIplus script with its CGI environment.  Performance
improvements in the order of 50-100% have been measured.  This size of this
structure is limited by the size of the CGIPLUSIN mailbox, which is in turn set
as described above.

</ul>

<a id="3.1.0.0.1" href="#"></a>
<a id="3.1.recordmodecgiplus" href="#"></a>
<a id="recordmodecgiplus" href="#"></a>
<h5 class="head"><span class="text">Record-Mode CGIplus</span></h5>

<p> This default and simple record-oriented mode allows any environment that
can read records from an input source to process CGIplus variables.  This of
course includes DCL (examples referenced below).

<ul class="list">

<li class="item"> The read will block between subsequent requests and so may be used to
coordinate the application.

<li class="item"> The first record read in any request can always be discarded.  This is
provided so that a script may be synchronized outside of the general CGIplus
variable read loop.  Record-mode can always be recognised by the single
exclamation symbol comprising this record.

<li class="item"> The CGIplus variable stream <span class="high bold">must always be completely
read</span>, record-by-record up until the the first empty record (blank line,
see below) before beginning any request processing. 

<li class="item"> An empty record (blank line) indicates the end of a single request's
CGIplus variable stream. Reading MUST be halted at this stage.  Request
processing may then commence.

</ul>

<a id="3.1.0.0.2" href="#"></a>
<a id="3.1.structmodecgiplus" href="#"></a>
<a id="structmodecgiplus" href="#"></a>
<h5 class="head"><span class="text">Struct-Mode CGIplus</span></h5>

<p> This mode offers significantly lower system overheads and improves latency
and performance at the cost of the additional complexity of recovering the
variables from a binary structure.  Code examples and CGILIB functions make
this relatively trivial at the application level.

<ul class="list">

<li class="item"> The read will block between subsequent requests and so may be used to
coordinate the application.

<li class="item"> The first record read in any request contains the size of the following
binary record.  It is also provided so that a script may be synchronized outside
of the general CGIplus variable read loop.  Struct-mode can always be
recognised by the two, successive, leading exclamation marks preceding the
variable structure record size integer.

<li class="item"> The CGIplus variables are read as a single, binary I/O.

<li class="item"> The contents of the binary structure must be parsed to obtain the
individual CGI variables. Request processing may then commence.

</ul>

<a id="3.1.0.0.3" href="#"></a>
<a id="3.1.requirementswhenusingcgiplus" href="#"></a>
<a id="requirementswhenusingcgiplus" href="#"></a>
<h5 class="head"><span class="text">Requirements when using CGIplus</span></h5>

<p> After processing, the CGIplus script can loop, waiting to read the details
of the next request from CGIPLUSIN.

<p> Request output (to the client) is written to SYS&dollar;OUTPUT (&lt;stdout&gt;) as per
normal CGI behaviour. <span class="high bold">End of output MUST be indicated by writing a special
EOF record to the output stream.</span>  A unique EOF sequence is  generated for each
use of DCL via a zombie or CGIplus script process. A non-repeating series of
bits most unlikely to occur in normal output is employed &hellip; but there is
still a very, very, very small chance of premature termination of output (one
in 2^<sup>224</sup> I think!)
See <a class="link blank" target="_blank" href="/wasd_root/src/httpd/cgi.c">WASD_ROOT:[SRC.HTTPD]CGI.C</a> for how the
value is generated.

<p> The CGIplus EOF string is obtained by the script from the logical name
CGIPLUSEOF, defined in the script process' process table, using the scripting
language's equivalent of F&dollar;TRNLNM(), SYS&dollar;TRNLNM(), or a getenv() call (in the C
standard library). This string will always contain less than 64 characters and
comprise only printable characters. It must be written at the conclusion of a
request's output to the output stream as a single record (line) but may also
contain a &lt;CR&gt;&lt;LF&gt; or just &lt;LF&gt; trailing carriage-control (to allow for
programming language  requirements). It only has to be evaluated once, as the
processing begins, remaining the same for all requests over the life-time of
that instance of the script.

<p> HTTP input (raw request body stream) is still available to a CGIplus script.

<a id="3.1.0.0.4" href="#"></a>
<a id="3.1.cgifunctionlibrary" href="#"></a>
<a id="cgifunctionlibrary" href="#"></a>
<h5 class="head"><span class="text">CGI Function Library</span></h5>

<p> A source code collection of C language functions useful for processing the
more vexing aspects of CGI/CGIplus/RTE programming (<a class="link" href="#1.12.scriptingfunctionlibrary">1.12 Scripting Function Library</a>).

<a id="3.2" href="#"></a>
<a id="3.2.codeexamples" href="#"></a>
<a id="codeexamples" href="#"></a>
<h2 class="head"><span class="numb">3.2</span><span class="text">Code Examples</span></h2>

<p> Of course a CGIplus script should only have a single exit point and should
explicitly close files, free allocated memory, etc., after processing a request
(i.e. not rely on image run-down to clean-up after itself). It is particularly
important when modifying existing scripts to work in the CGIplus environment to
ensure this requirement is met (who of us hasn't thought &quot;well, this file will
close when the image exits anyway&quot;?)

<p> It is a simple task to design a script to modify its behaviour according to
the environment it is executing in. Detecting the presence or absence of the
CGIPLUSEOF logical is sufficient indication. The following C code fragment
shows simultaneously determining whether it is a standard or CGIplus
environment (and setting an appropriate boolean), and getting the CGIplus EOF
sequence (if it exists).

<div class="blockof code">int  IsCgiPlus;
char  *CgiPlusEofPtr;

IsCgiPlus = ((CgiPlusEofPtr = getenv(&quot;CGIPLUSEOF&quot;)) != NULL);
</div>

<a id="3.2.0.0.1" href="#"></a>
<a id="3.2.recordmodecode" href="#"></a>
<a id="recordmodecode" href="#"></a>
<h5 class="head"><span class="text">Record-Mode Code</span></h5>

<p> The following C code fragment shows a basic CGIplus record-mode request
loop, reading lines from CGIPLUSIN, and some basic processing to select
required CGI variables for request processing.  Generally this level of coding
is not required as it is recommended to employ the functionality of something
like the CGILIB functiona library.

<div class="blockof code">if (IsCgiPlus)
{
   char  *cptr;
   char  Line [1024],
         RemoteHost [128];
   FILE  *CgiPlusIn;

   if ((CgiPlusIn = fopen (getenv(&quot;CGIPLUSIN&quot;), &quot;r&quot;)) == NULL)
   {
      perror (&quot;CGIplus: fopen&quot;);
      exit (0);
   }

   for (;;)
   {
      /* will block waiting for subsequent requests */
      for (;;)
      {
         /* should never have a problem reading CGIPLUSIN, but */
         if (fgets (Line, sizeof(Line), CgiPlusIn) == NULL)
         {
            perror (&quot;CGIplus: fgets&quot;);
            exit (0);
         }
         /* first empty line signals the end of CGIplus variables */
         if (Line[0] == '\n') break;
         /* remove the trailing newline */
         if ((cptr = strchr(Line, '\n')) != NULL) *cptr = '\0';

         /* process the CGI variable(s) we are interested in */
         if (!strncmp (Line, &quot;WWW_REMOTE_HOST=&quot;, 16))
            strcpy (RemoteHost, Line+16);
      }

      <span class="high italic">process request, signal end-of-output)</span>
   }
}
</div>

<a id="3.2.0.0.2" href="#"></a>
<a id="3.2.structmodecode" href="#"></a>
<a id="structmodecode" href="#"></a>
<h5 class="head"><span class="text">Struct-Mode Code</span></h5>

<p> This mode requires significantly more code than record-mode.  A
self-contained C language function, allowing CGI variable processing in
standard CGI, CGIplus record-mode and CGIplus struct-mode, is available for
inclusion in user applications.  It automatically detects the environment and
changes behaviour to suit.  This or CGILIB is strongly recommended.

<p> See source in
<a class="link blank" target="_blank" href="/wasd_root/src/CGIplus/CGIplus_cgivar.c">WASD_ROOT:[SRC.CGIPLUS]CGIPLUS_CGIVAR.C</a>

<a id="3.2.0.0.3" href="#"></a>
<a id="3.2.cgiplusoutput" href="#"></a>
<a id="cgiplusoutput" href="#"></a>
<h5 class="head"><span class="text">CGIplus Output</span></h5>

<p> CGI scripts can write output in record (line-by-line) or binary mode (more
efficient because of buffering by the C RTL).  When in binary mode the output
stream must be flushed immediately before and after writing the CGIplus EOF
sequence (note that in binary a full HTTP stream must also be used). This code
fragment shows placing a script output stream into binary mode and the flushing
steps.

<div class="blockof code">/* reopen output stream so that the '\r' and '\n' are not filtered */
if ((stdout = freopen (&quot;SYS&dollar;OUTPUT&quot;, &quot;w&quot;, stdout, &quot;ctx=bin&quot;)) == NULL)
   exit (vaxc&dollar;errno);

do {

   <span class="high italic">read request ...)</span>

   /* CGI response header */
   fprintf (stdout, &quot;Content-Type: text/html\n\n&quot;);

   <span class="high italic">other output ...)</span>

   if (IsCgiPlus)
   {
      /* the CGIplus EOF must be an independant I/O record */
      fflush (stdout);
      fprintf (stdout, &quot;%s&quot;, CgiPlusEofPtr);
      fflush (stdout);
   }

} while (IsCgiPlus);
</div>

If the script output is not binary (using default &lt;stdout&gt;) it is only
necessary to ensure the EOF string has a record-delimiting new-line.

<div class="blockof code">fprintf (stdout, &quot;%s\n&quot;, CgiPlusEofPtr);
</div>

Other languages may not have this same requirement.  DCL procedures are quite
capable of being used as CGIplus scripts.

<p> See examples in
<a class="link blank" target="_blank" href="/wasd_root/src/CGIplus/*.*">WASD_ROOT:[SRC.CGIPLUS]</a>

<div class="note">
<a id="3.2.0.0.4" href="#"></a>
<a id="3.2.hint" href="#"></a>
<a id="hint" href="#"></a>
<h5 class="head center"><span class="text">Hint!</span></h5>
<hr class="note_hr">
Whenever developing CGIplus scripts/applications (unlike standard CGI) don't
forget that after compiling, the old image must be purged from the server
before trying out the new!!!  (I've been caught a number of times <span class="high monosp">:^)</span>  <p>
Scripting processes may be purged or deleted using (see
<a class="link blank" target="_blank" href="../features/#httpdcommandline">HTTPd Command Line</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>).

<div class="blockof code">&dollar; HTTPD /DO=DCL=DELETE
&dollar; HTTPD /DO=DCL=PURGE
</div>
<hr class="note_hr">
</div>

<a id="3.3" href="#"></a>
<a id="3.3.otherconsiderations" href="#"></a>
<a id="otherconsiderations" href="#"></a>
<h2 class="head"><span class="numb">3.3</span><span class="text">Other Considerations</span></h2>

<p> Multiple CGIplus scripts may be executing in multiple processes at any one
time.  This includes multiple instances of any particular script.  It is the
server's task to track these, distributing appropriate requests to idle
processes, monitoring those currently processing requests, creating new
instances if and when necessary, and deleting the least-used, idle CGIplus
processes when configurable thresholds are reached.  Of course it is the
script's job to maintain coherency if multiple instances may result in resource
conflicts or race conditions, etc., between the scripts.

<p> The CGIplus script process can be given a finite life-time set by
configuration parameter (see &quot;Features and Facilities, Server Configuration&quot;). 
If this life-time is not set then  the CGIplus will persist indefinitely (i.e.
until purged due to soft-limits being reached, or explicitly purged/deleted). 
When a life-time has been set the CGIplus process is automatically deleted
after being idle for the specified period (i.e. not having processed a
request).  This can be useful in preventing sporadically used scripts from
cluttering up the system indefinitely.

<p> In addition, an idle CGIplus script can be run-down by the server at any
time the script process soft-limit is reached, so resources should be largely
quiescent when not actually processing (<a class="link" href="#1.2.6.scriptprocessrundown">1.2.6 Script Process Run-Down</a>).  Of
course, in extreme situations, a CGIplus process may also be manually
terminated from the command line (e.g. STOP/ID=).

<p> Some CGIplus scripting information and management is available via the
server administration menu, see &quot;Features and Facilities, Server Reports&quot;.

<a id="3.3.0.0.1" href="#"></a>
<a id="3.3.cgiplusrulemapping" href="#"></a>
<a id="cgiplusrulemapping" href="#"></a>
<h5 class="head"><span class="text">CGIplus Rule Mapping</span></h5>

<p> CGIplus scripts are differentiated from standard CGI scripts in the mapping
rule configuration file using the &quot;script+&quot; and &quot;exec+&quot; directives (see
<a class="link blank" target="_blank" href="../config/#requestprocessingconfiguration">Request Processing Configuration</a> in <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>).

<p> Scripts capable of operating in both standard CGI and CGIplus environments
may simply be accessed in either via rules such as

<div class="blockof code">exec /cgi-bin/* /cgi-bin/*
exec+ /cgiplus-bin/* /cgi-bin/*
</div>

while specific scripts can be individually designated as CGIplus using

<div class="blockof code">script+ /cgiplus_example* /cgi-bin/cgiplus_example*
</div>

<div class="note">
<a id="3.3.0.0.2" href="#"></a>
<a id="3.3.hint" href="#"></a>
<a id="hint" href="#"></a>
<h5 class="head center"><span class="text">Hint!</span></h5>
<hr class="note_hr">
When changing CGIplus script mapping it is advised to purge execution of
existing scripts then reloading the mapping rules.  Some conflict is possible
when using new rules while existing CGIplus scripts are executing.
<div class="blockof code">&dollar; HTTPD /DO=DCL=PURGE
&dollar; HTTPD /DO=MAP
</div>
<hr class="note_hr">
</div>
<!-- source:0400_RTE.WASDOC -->
<hr class="page">
<a id="4." href="#"></a>
<a id="4.runtimeenvironments" href="#"></a>
<a id="runtimeenvironments" href="#"></a>
<h1 class="head"><span class="numb">4.</span><span class="text">Run-Time Environments</span></h1>

<table class="TOC2table">
<tr><td><a href="#4.1.rteprogramming"><span class="numb">4.1</span><span class="text">RTE Programming</span></a>
<tr><td><a href="#4.2.serverconfiguration"><span class="numb">4.2</span><span class="text">Server Configuration</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#3.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#5.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> A Run-Time Environment (RTE) is a persistant scripting environment with
similar objectives to CGIplus &hellip; reducing script response time, increasing
server throughput and reducing system impact.  In fact the RTE environment is
implemented using CGIplus!  There is very little difference in the behaviour of
CGIplus scripts and RTEs.  Both are activated by the server, process multiple
requests (reading the request CGI environment from a data stream supplied by
the server), persist between requests in a quiescent state, and may be removed
by the server if idle for a specified period or when it wishes to use the
process for some other purpose. <span class="high bold">Like CGIplus an RTE must be purpose-written
for the environment!</span>  What is the difference then?

<p> With CGIplus the script itself persists between uses, retaining all of its
state.  With an RTE the script does not persist or retain state, only the RTE
itself.

<p> A RTE is intended as an environment in which a script source is interpreted
or otherwise processed, that is for scripting engines, although it is not
limited to that.  The essential  difference between an RTE and a CGIplus script
is this script source.  In CGIplus the SCRIPT_NAME and SCRIPT_FILENAME CGI
variables reflect the script itself, and remain constant for each activation of
the script, with PATH_INFO and PATH_TRANSLATED providing the additional
&quot;location&quot; information for the script processing.  With an RTE the SCRIPT_NAME
and SCRIPT_FILENAME can vary with each activation.  This allows the RTE to
process multiple, successive different (or the same) scripts, each with its own
PATH_INFO and PATH_TRANSLATED.  Hence, it is not unreasonable to consider the
two environments to be the same, with a slight difference in the mapping of
resources passed to them.

<p> This might be best illustrated with examples.

<a id="4.0.0.0.1" href="#"></a>
<a id="4.cgiplusexample" href="#"></a>
<a id="cgiplusexample" href="#"></a>
<h5 class="head"><span class="text">CGIplus Example</span></h5>

<p> Consider the mapping rule

<div class="blockof code">exec+ /cgiplus-bin/* /cgi-bin/*
</div>
 applied to the following CGIplus request

<div class="blockof code">/cgiplus-bin/xyz/the/path/information?and=a&amp;query=string
</div>

<p> If the script was an executable it would be activated as

<div class="blockof code">CGI-BIN:[000000]XYZ.EXE
</div>

with script CGI information

<div class="blockof code">/cgiplus-bin/xyz
CGI-BIN:[000000]XYZ.EXE
</div>

and the request path information and query string supplied as

<div class="blockof code">/the/path/information
THE:[PATH]INFORMATION
and=a&amp;query=string
</div>

<a id="4.0.0.0.2" href="#"></a>
<a id="4.rteexample" href="#"></a>
<a id="rteexample" href="#"></a>
<h5 class="head"><span class="text">RTE Example</span></h5>

<p> By contrast with a request to activate an RTE the following mapping rule

<div class="blockof code">exec+ /xyz-bin/* (CGI-BIN:[000000]XYZ.EXE)/wasd_root/src/xyz/*
</div>

(note the RTE executable specified inside parentheses) and request

<div class="blockof code">/xyz-bin/an_example/the/path/information?and=a&amp;query=string
</div>

would activate the scripting environment (perhaps interpreter)

<div class="blockof code">CGI-BIN:[000000]XYZ.EXE
</div>

supplying it with per-request script name and file information 

<div class="blockof code">/xyz-bin/an_example.xyz
WASD_ROOT:[SRC.XYZ]AN_EXAMPLE.XYZ
</div>

and path and query string information

<div class="blockof code">/the/path/information
THE:[PATH]INFORMATION
and=a&amp;query=string
</div>

<a id="4.0.0.0.3" href="#"></a>
<a id="4.summary" href="#"></a>
<a id="summary" href="#"></a>
<h5 class="head"><span class="text">Summary</span></h5>

<p> As can be seen the script information is constant for each request to a
CGIplus script, while with RTE the script information could vary with each
request (although of course it would be the same if the same script is
requested).  In the case of CGIplus the <span class="high italic">process what?</span> request information is
provided only by path information, however with RTE both script and path
information are used.

<a id="4.1" href="#"></a>
<a id="4.1.rteprogramming" href="#"></a>
<a id="rteprogramming" href="#"></a>
<h2 class="head"><span class="numb">4.1</span><span class="text">RTE Programming</span></h2>

<p> <span class="high bold">The RTE interface is still CGI</span>, with all the usual environment variables
and input/output streams available, just in a CGIplus environment!  Hence when
coding a Run-Time Environment the same considerations involved in CGIplus
programming apply (<a class="link" href="#3.cgiplus">3. CGIplus</a>).

<p> In particular it is important a RTE should explicitly close files, free
allocated memory, etc., after processing a request (of course it cannot rely on
image  run-down to clean-up after itself). It is particularly important that
all traces of each script's processing are removed after it concludes.  This
does not mean for example that databases need to be completely closed, etc.,
which might defeat the purpose of using a persistant environment, just that
great care must be exercised by the programmer to prevent one script
interfering with another!

<p> An example RTE,
<a class="link blank monosp" target="_blank" href="/wasd_root/src/CGIplus/RTE_example.c">WASD_ROOT:[SRC.CGIPLUS]RTE_EXAMPLE.C</a>
provides the basics of the environment.

<p> A source code collection of C language functions useful for processing the
more vexing aspects of CGI/CGIplus/RTE programming ().  The example RTE implementation uses this library.

<a id="4.2" href="#"></a>
<a id="4.2.serverconfiguration" href="#"></a>
<a id="serverconfiguration" href="#"></a>
<h2 class="head"><span class="numb">4.2</span><span class="text">Server Configuration</span></h2>

<p> The following configuration information uses the supplied Perl RTE as the
example.  Note that RTE scripting engines must always be mapped using the EXEC+
rules.  The SCRIPT+ rule does not apply.

<p> The following rule in WASD_CONFIG_MAP maps the /pl-bin/ location to where the
site wishes to locate its CGI Perl scripts (not necessarily the same as in the
example).

<div class="blockof code">exec+ /pl-bin/* (CGI-BIN:[000000]PERLRTE.EXE)/wasd_root/src/perl/*
</div>

<p> With this rule Perl scripts may be accessed using 

<div class="blockof code">http://host.name.domain/pl-bin/an_example
</div>

<p> This WASD_CONFIG_GLOBAL rule ensures Perl scripts could be activated via
the Perl RTE even if the WASD_CONFIG_MAP rule did not exist (<a class="link" href="#1.7.scriptruntime">1.7 Script Run-Time</a>).

<div class="blockof code">[DclScriptRunTime]
.PL  (CGI-BIN:[000000]PERLRTE.EXE)
</div>

<div class="note"><a id="4.2.0.0.0.1" href="#"></a>
<a id="4.2.note" href="#"></a>
<a id="note" href="#"></a>
<h5 class="head center"><span class="text">Note</span></h5>
<hr class="note_hr">

The server makes no check of the RTE executable (or procedure) before
attempting to activate  it using DCL for processing the script.  If it does not
exist or is not accessible due to incorrent file protections the DCL of the
scripting process will report the problem.
<hr class="note_hr">
</div>

<p> It does by default however, check that the file used as the script source
exists as with other scripting environments.  If it does not this is reported
as a &quot;script not found&quot;.  For RTEs that wish to report on this themselves, or
that possibly construct their own script specification via some internal
processing, this server behaviour may be suppressed for the script activation
path using the WASD_CONFIG_MAP path SETting &quot;script=nofind&quot; as in the following
example.

<div class="blockof code">set /xyz-bin/* script=nofind
exec+ /xyz-bin/* (CGI-BIN:[000000]XYZ.EXE)/wasd_root/src/xyz/*
</div>

<p> CGI environment variables SCRIPT_FILENAME and PATH_TRANSLATED can be
provided to any RTE script in Unix file-system syntax should that script
require or prefer it using this format.  See <a class="link" href="#1.8.unixsyntax">1.8 Unix Syntax</a>.

<a id="4.2.0.0.1" href="#"></a>
<a id="4.2.dclprocedure" href="#"></a>
<a id="dclprocedure" href="#"></a>
<h5 class="head"><span class="text">DCL procedure</span></h5>

<p> If the RTE executable requires <span class="high italic">wrapping</span> in a DCL procedure (perhaps to
provide some command-line specific parameter or define a C-RTL logical name)
this can be specified in place of an executable.  Merely prefix the
specification with a &quot;@&quot;.  The default is to run an executable (this can
explicitly be specified using a leading &quot;&dollar;&quot;) while the leading &quot;@&quot; provides a
DCL procedure activation.
<!-- source:0500_WEBSOCKET.WASDOC -->
<hr class="page">
<a id="5." href="#"></a>
<a id="5.websocket" href="#"></a>
<a id="websocket" href="#"></a>
<h1 class="head"><span class="numb">5.</span><span class="text">WebSocket</span></h1>

<div class="TOC2cols2">
<table class="TOC2table">
<tr><td><a href="#5.1.multiclientwebsocketapplications"><span class="numb">5.1</span><span class="text">Multi-Client WebSocket Applications</span></a>
<tr><td><a href="#5.2.websocketapplication"><span class="numb">5.2</span><span class="text">WebSocket Application</span></a>
<tr><td><a href="#5.3.websocketlibrary"><span class="numb">5.3</span><span class="text">WebSocket Library</span></a>
<tr><td><a href="#5.4.websocketapplicationexamples"><span class="numb">5.4</span><span class="text">WebSocket Application Examples</span></a>
<tr><td><a href="#5.4.1.chat"><span class="numb">5.4.1</span><span class="text">Chat</span></a>
<tr><td><a href="#5.4.2.echo"><span class="numb">5.4.2</span><span class="text">Echo</span></a>
<tr><td><a href="#5.4.3.mouse"><span class="numb">5.4.3</span><span class="text">Mouse</span></a>
<tr><td><a href="#5.5.websocketconfiguration"><span class="numb">5.5</span><span class="text">WebSocket Configuration</span></a>
<tr><td><a href="#5.5.1.websocketthrottle"><span class="numb">5.5.1</span><span class="text">WebSocket Throttle</span></a>
<tr><td><a href="#5.5.2.websocketcommandline"><span class="numb">5.5.2</span><span class="text">WebSocket Command-Line</span></a>
<tr><td><a href="#5.5.3.websocketversion"><span class="numb">5.5.3</span><span class="text">WebSocket Version</span></a>
<tr><td><a href="#5.6.websocketthroughput"><span class="numb">5.6</span><span class="text">WebSocket Throughput</span></a>
<tr><td><a href="#5.7.websocketreferences"><span class="numb">5.7</span><span class="text">WebSocket References</span></a>
<tr><td><a href="#5.8.wasdquotrawquotsocket"><span class="numb">5.8</span><span class="text">WASD &quot;Raw&quot;Socket</span></a>
<tr><td><a href="#5.8.1.rawsocketapplication"><span class="numb">5.8.1</span><span class="text">RawSocket Application</span></a>
<tr><td><a href="#5.8.2.rawsocketlibrary"><span class="numb">5.8.2</span><span class="text">RawSocket Library</span></a>
<tr><td><a href="#5.8.3.rawsocketapplicationexamples"><span class="numb">5.8.3</span><span class="text">RawSocket Application Examples</span></a>
<tr><td><a href="#5.8.3.1.chat"><span class="numb">5.8.3.1</span><span class="text">Chat</span></a>
<tr><td><a href="#5.8.3.2.echo"><span class="numb">5.8.3.2</span><span class="text">Echo</span></a>
<tr><td><a href="#5.8.3.3.terminalserver"><span class="numb">5.8.3.3</span><span class="text">Terminal Server</span></a>
<tr><td><a href="#5.8.4.rawsocketconfiguration"><span class="numb">5.8.4</span><span class="text">RawSocket Configuration</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#4.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#6.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> WebSocket is a capability introduced with HTML5, providing an asynchronous,
bidirectional, full-duplex connection over which messages can be sent between
agents, commonly a browser client and a server application.  Compatible
browsers provide a JavaScript interface that allows connections to be set up,
maintained, messages exchanged, and connections closed down, using a callable
and event-based interface.

<p> WASD provides a WebSocket compatible scripting environment, one that is
activated in the same fashion as an equivalent CGI/CGIplus/RTE and has an
identical CGI environment (variables, streams, etc.) but which uses a unique
HTTP response and communicates with its client using the WebSocket protocol.

<p> Client supplied data is available to the script via the WEBSOCKET_INPUT
mailbox and data from the script supplied via the WEBSOCKET_OUTPUT mailbox
(indicated via CGI variables). Communication using a WebSocket requires the use
of a framing protocol while WEBSOCKET_INPUT and WEBSOCKET_OUTPUT are opaque
octet-streams providing communication to and from the WebSocket application. 
CGI variables WEBSOCKET_INPUT_MRS and WEBSOCKET_OUTPUT_MRS indicate the
respective mailbox capacity.

<p> The WASD server largely acts as a conduit for the WebSocket octet-stream. 
It provides the upgrade from HTTP to WebSocket protocol handshake and then
connects the bidirectional data stream to the WebSocket application activated
in WASD's scripting environment which then is required to perform all of the
protocol requirements, etc.  The baseline WASD implementation is via the
<span class="high bold">wsLIB</span> library (see below).  The complexity and potential extensibility of
the WebSocket protocol means this decoupling of server infrastructure and
protocol implementation offers a number of advantages, including more
straight-forward updates and bug fixing (just the library), and alternate,
concurrent implementations.

<p> Long-lived WebSocket scripts by default have timeouts and other limits set
to infinite.  If control is required it must be exercised using the appropriate
mapping SETings or DCL callouts.

<p> A WASD <span class="high italic">RawSocket</span> is an analogue to the WebSocket, providing a
bidirectional, asynchronous, opaque data stream input and output on a
per-service basis.  See <a class="link" href="#5.8.wasdquotrawquotsocket">5.8 WASD &quot;Raw&quot;Socket</a>. 

<a id="5.1" href="#"></a>
<a id="5.1.multiclientwebsocketapplications" href="#"></a>
<a id="multiclientwebsocketapplications" href="#"></a>
<h2 class="head"><span class="numb">5.1</span><span class="text">Multi-Client WebSocket Applications</span></h2>

<p> A single WASD WebSocket server application (script) can support multiple
clients by using some form of multi-threading such as AST-based I/O, POSIX
Threads, multi-thread interpreter environment, etc.  The WASD wsLIB library
(<a class="link" href="#5.3.websocketlibrary">5.3 WebSocket Library</a>) supports native AST concurrency.

<p> A WebSocket connection to a script is maintained by the WEBSOCKET_INPUT and
WEBSOCKET_OUTPUT channels remaining connected to the script.  If the script
closes them (or the image or process exits, etc.) the WebSocket connection is
closed.  WebSocket requests are maintained as long as the script maintains
them, for a CGIplus script, until it exits.  If a CGIplus script requires to
disconnect from a WebSocket client without exiting it must do so explicitly (by
using the wsLIB <span class="high italic">close</span> function (and associated WebSocket protocol close
handshake), closing C streams, deassigning channels, etc.)

<p> Of course this is the underlying mechanism allowing a single CGIplus script
to maintain connections with multiple WebSocket clients.  Provided the script
remains connected to the WebSocket IPC mailboxes and processes that I/O
asynchronously a single script can concurrently handle multiple clients.  The
script just processes each request it is given, adding the new client to the
existing group (and removing them as the IPC indicates they disconnect).

<p> Obviously the script must remain resident via CGIplus or RTE.

<div class="note">
<a id="5.1.0.0.1" href="#"></a>
<a id="5.1.bytlm" href="#"></a>
<a id="bytlm" href="#"></a>
<h5 class="head center"><span class="text">BYTLM</span></h5>
<hr class="note_hr">
WebSocket scripting environments have the potential to consume significantly
more BYTLM than those for HTTP scripting.  The potentially large number of
mailboxes associated with each scripting process (two per WebSocket connection)
means that server and scripting account(s)  BYTLM and associated quotas will
need to be increased appropriately. 
<hr class="note_hr">
</div>

<p> The server will continue to provide requests to the script for as long as it
appears idle (i.e. the CGIplus sentinal EOF is returned even though concurrent
processing may continue).  Obviously a single scripting process cannot accept
an unlimited number of concurrent WebSockets.  When a script decides it can
process no more it should not return the sentinal EOF from the most recent
request until it is in a position to process more, when it then provides the
EOF and the server again will supply another request.

<p> The original request is access logged at request run-down (when the
WebSocket is finally closed either because the client disconnected or the
script closed its connection to the WEBSOCKET_.. mailboxes).  The access log
status is 101 (Switching Protocols) and the bytes rx and tx reflect the total
for the duration.

<a id="5.2" href="#"></a>
<a id="5.2.websocketapplication" href="#"></a>
<a id="websocketapplication" href="#"></a>
<h2 class="head"><span class="numb">5.2</span><span class="text">WebSocket Application</span></h2>

<p> WebSocket server applications are essentially CGIplus scripts and so have
similar programming considerations (see <a class="link" href="#3.cgiplus">3. CGIplus</a>).

<p> A WebSocket application however is typically long-lived and involves
significant interaction between the participants.  Either party can initiate
independent communication with the other according to the required business
logic.

<p> A WASD WebSocket application relies on asynchronous I/O and other events to
provide the communication granularity required for application interaction. 
The following pseudo-code shows the structure of one such hypothetical
application.  It accepts multiple, concurrent requests in it's main loop,
creates the required WebSocket protocol supporting data structure, and then
services application requirements in two event loops.

<p> The first reads from the remote client and processes according to the
business logic of client-initiated processing, asynchronously and/or
synchronously writing data to the client.  The second loop pushes data
asynchronously to the client based on the application business logic providing
those events.  The close event occurs when the client or application close the
WebSocket, or are otherwise disconnected, and finalises the request.

<div class="blockof code">begin
{
   initialise
   loop
   {
      wait for next client request
      open the WebSocket
      begin asynchronous read from client
      signal ready for another request
   }
}
read event from client
{
   business logic
   asynchronous write to client
   next asynchronous read from client
}
push event to client
{
   business logic
   asynchronous write to client
}
close event
{
   business logic
   close the WebSocket
}
</div>

<p> A second model for request synchronisation allows the initialisation to
specify a routine to be called when another request is available, making all
processing event-driven.  In all other respects the processing is the same as
above.

<div class="blockof code">begin
{
   initialise
   set routine for request acceptance
   hibernate (or otherwise not exit)
}
request acceptance
{
   open the WebSocket
   business logic
   begin asynchronous read from client
   signal ready for another request
}
read event from client
{
   business logic
   asynchronous write to client
   next asynchronous read from client
}
push event to client
{
   business logic
   asynchronous write to client
}
close event
{
   business logic
   close the WebSocket
}
</div>

<p> These basic structures are seen in all the WebSocket example applications.

<a id="5.3" href="#"></a>
<a id="5.3.websocketlibrary" href="#"></a>
<a id="websocketlibrary" href="#"></a>
<h2 class="head"><span class="numb">5.3</span><span class="text">WebSocket Library</span></h2>

<p> <span class="high bold">wsLIB</span> is a C code module that provides the basic infrastructure for
building WebSocket applications to run as WASD scripting under both the models
decribed above.

<p> It abstracts much of the required functionality into a few callable
functions using optional string descriptors so as to minimise dependency on the
C language and on knowing the internals of the library data structure.   The
list of functions and associated parameters would unnecessarily clutter this
document and so WebSocket application designers and programmers are referred to
the descriptive prologue in the library code module itself (see below).  While
wsLIB usage is <span class="high italic">relatively</span> straight-forward, the detail of any
multi-threaded, asynchronous application can be daunting and so the example
WebSocket applications (scripts) should be used as a wsLIB reference and
tutorial.
 
<p> <span class="high bold">wsLIB</span> also contains routines for synchronising request acceptance and
accessing CGI variables associated with that request.  These variables are
available for the period from request acceptance to the issuing of the CGIplus
sentinal EOF indicating to the server the script is ready to accept another
request.  Any CGI variable values required during ongoing processing must be
copied to request-specific storage. Again, the example WebSocket applications
(scripts) should be used as a CGI variable processing reference and tutorial.
 
<p> The library contains WATCH points.  Network [x]Data and [x]Script provide a
useful combination of traffic data.  The library function WsLibWatchScript()
allows WebSocket applications (scripts) to provide additional WATCHable
information via the [x]Script item.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/wslib.c">WASD_ROOT:[SRC.WEBSOCKET]WSLIB.C</a>

<a id="5.4" href="#"></a>
<a id="5.4.websocketapplicationexamples" href="#"></a>
<a id="websocketapplicationexamples" href="#"></a>
<h2 class="head"><span class="numb">5.4</span><span class="text">WebSocket Application Examples</span></h2>

<p> The WASD WebSocket implementation provides a number of scripting examples
illustrating WebSocket programming basics and the use of the WASD wsLIB
library.  All of these illustrate multi-client support using asynchonous I/O. 
Each has a server component (the C code) and a client component (the HTML file
containing the JavaScript code).

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/*.*">WASD_ROOT:[SRC.WEBSOCKET]</a>

<p> The following examples concentrate on the server C code as this is
WASD-specific.  Any WebSocket reference can adequitely cover the essentials of
the client JavaScript implementation.

<style type="text/css">._doesws { width:70%; font-size:120%; margin-bottom:0.2em; }</style>
<a id="5.4.0.0.0.1" href="#"></a>
<a id="5.4.websocketdoesthisbrowsersupport" href="#"></a>
<a id="websocketdoesthisbrowsersupport" href="#"></a>
<h6 class="head display0"><span class="text">WebSocket - does this browser support?</span></h6>
<div class="note center">
<a id="5.4.0.0.1" href="#"></a>
<a id="5.4.doesthisbrowsersupportwebsocket" href="#"></a>
<a id="doesthisbrowsersupportwebsocket" href="#"></a>
<h5 class="head center"><span class="text">Does this browser support WebSocket?</span></h5>
<hr class="note_hr">
<div id="websocket_yes" class="_doesws"
style="background-color:#00ff00;display:none;">Y E S</div>
<div id="websocket_yes_but" class="_doesws"
style="background-color:#ffff00;display:none;">
Y E S ... but not a recent enough version</div>
<div id="websocket_no" class="_doesws"
style="background-color:#ff0000;display:inline-block;">N O !</div>
</b>
<br /><script language="JavaScript">
document.write('<i>' + navigator.userAgent + '</i>');
function testWebSocketSupport()
{
   try {
      var ws = new WebSocket("wss://localhost/");
      if (typeof ws.protocol == "undefined")
         return -1;
      else
         return +1;
   }
   catch (err) {
      return 0;
   }
}
function reportWebSocketSupport()
{
   var level = testWebSocketSupport();
   if (level != 0)
      document.getElementById("websocket_no").style.display = "none";
   if (level == +1)
      document.getElementById("websocket_yes").style.display = "inline-block";
   else
   if (level == -1)
      document.getElementById("websocket_yes_but").style.display = "inline-block";
}
if (window.addEventListener)
   window.addEventListener("load", reportWebSocketSupport, false);
else
if (window.attachEvent)
   window.attachEvent("onload", reportWebSocketSupport);
</script>)<hr class="note_hr">
</div>

<a id="5.4.1" href="#"></a>
<a id="5.4.1.chat" href="#"></a>
<a id="chat" href="#"></a>
<h3 class="head"><span class="numb">5.4.1</span><span class="text">Chat</span></h3>

<p> This almost has to be <span class="high bold">the</span> classic example of asynchronous, bidirectional
communications without HTTP kludges.  Each connected client can enter a message
and it is distributed to all connected clients.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/ws_chat.c">WASD_ROOT:[SRC.WEBSOCKET]WS_CHAT.C</a>

<a id="5.4.2" href="#"></a>
<a id="5.4.2.echo" href="#"></a>
<a id="echo" href="#"></a>
<h3 class="head"><span class="numb">5.4.2</span><span class="text">Echo</span></h3>

<p> Each connected client can enter a message which is then returned to them.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/ws_echo.c">WASD_ROOT:[SRC.WEBSOCKET]WS_ECHO.C</a>

<a id="5.4.3" href="#"></a>
<a id="5.4.3.mouse" href="#"></a>
<a id="mouse" href="#"></a>
<h3 class="head"><span class="numb">5.4.3</span><span class="text">Mouse</span></h3>

<p> The HTML/JavaScript/WebSocket client end connects to the script.  Each
mouse movement is then reported to the script.  These data are distributed to
all connected clients.  This provides an asynchronous update facility from all
clients to all clients.

<p> The script is implemented using VMS I/O-driven ASTs.  The code is also
interesting because it implements all required functionality explicitly; no
WebSocket library functions are employed.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/ws_mouse.c">WASD_ROOT:[SRC.WEBSOCKET]WS_MOUSE.C</a>

<a id="5.5" href="#"></a>
<a id="5.5.websocketconfiguration" href="#"></a>
<a id="websocketconfiguration" href="#"></a>
<h2 class="head"><span class="numb">5.5</span><span class="text">WebSocket Configuration</span></h2>

<p> WebSocket server applications are essentially CGIplus scripts and so are
mapped and activated in the same fashion as any other CGIplus script
(<a class="link" href="#3.3.otherconsiderations">3.3 Other Considerations</a>).

<a id="5.5.1" href="#"></a>
<a id="5.5.1.websocketthrottle" href="#"></a>
<a id="websocketthrottle" href="#"></a>
<h3 class="head"><span class="numb">5.5.1</span><span class="text">WebSocket Throttle</span></h3>

<p> Throttle mapping rules may be applied to WebSocket requests.  There is
however, a <span class="high bold">fundamental difference</span> between request throttling and WebSocket
throttling though.  HTTP request throttling applies control to the entire life
of the response.  WebSocket throttling applies only to establishing connection
to the underlying server application.  Once the script responds to accept the
connection or reject it throttling is concluded.

<p> Long-lived WebSocket connections are considered less suitable to full
life-cycle throttling and should use internal mechanisms to control resource
utilisation (i.e. using the delayed sentinal EOF mechanism described in
<a class="link" href="#5.1.multiclientwebsocketapplications">5.1 Multi-Client WebSocket Applications</a>).  Essentially it is used to limit
the impact concurrent requests have on the number of supporting script
processes allowed to be instantiated to support the application.

<p> For example, the rule

<div class="blockof code">set /cgi-bin/ws_application throttle=1
</div>

will only allow one new request at a time attempt to connect to and/or
create a WebSocket application script.  This will effectively limit the number
of supporting processes to one however many clients wish to connect.

<p> To support concurrent requests distributed across multiple application
scripts specify the throttle value as the number of separate scripts

<div class="blockof code">set /cgi-bin/ws_application throttle=5
</div>

and if each script is to support a maximum number of individual connections
then have it delay the EOF sentinal (described above) to block the server
selecting it for the next request.  Requests will be allocated until all
processes have blocked after which they will be queued.

<p> To return a &quot;too busy&quot; 503 to clients (almost) immediately upon all
processes  become full and blocking (maximum application concurrency has been
reached) then set the &quot;t/o-busy&quot; value to 1 second. 

<div class="blockof code">set /cgi-bin/ws_application throttle=5,,,,,1
</div>

<a id="5.5.2" href="#"></a>
<a id="5.5.2.websocketcommandline" href="#"></a>
<a id="websocketcommandline" href="#"></a>
<h3 class="head"><span class="numb">5.5.2</span><span class="text">WebSocket Command-Line</span></h3>

<p> Unconditionally disconnects all WebSocket applications.

<div class="blockof code">&dollar; HTTPD /DO=WEBSOCKET=DISCONNECT
</div>

<p> For VMS V8.2 and later, more selective disconnects are possible. 
Disconnects WebSocket applications with connect number, with matching script
names, and with matching scripting account usernames, respectively.

<div class="blockof code">&dollar; HTTPD /DO=WEBSOCKET=DISCONNECT=<span class="high italic">number</span>
&dollar; HTTPD /DO=WEBSOCKET=DISCONNECT=SCRIPT=<span class="high italic">pattern</span>
&dollar; HTTPD /DO=WEBSOCKET=DISCONNECT=USER=<span class="high italic">pattern</span>
</div>

<a id="5.5.3" href="#"></a>
<a id="5.5.3.websocketversion" href="#"></a>
<a id="websocketversion" href="#"></a>
<h3 class="head"><span class="numb">5.5.3</span><span class="text">WebSocket Version</span></h3>

<p> CGI variable WEBSOCKET_VERSION provides the WebSocket protocol version
number negotiated by the server at connection establishment.

<p> At the time of writing the WebSocket protocol has just gone to IETF Draft
RFC and has during development been very volatile and may continue to be so as
it evolves.  WASD supports the current base protocol number and any higher.  At 
some time in the future it may be necessary to constrain that to a supported
version number or set of numbers.  Defining the logical name
WASD_WEBSOCKET_VERSION to be one or more comma-separated numbers will limit the
supported protocol versions.  For example

<div class="blockof code">&dollar; DEFINE /TABLE=WASD_TABLE WASD_WEBSOCKET_VERSION &quot;10, 9, 8&quot;
</div>

limits requests to protocol version 10 (current), 9 (earlier) and 8 (earliest). 
Logical name is only tested once for each server startup (the first WebSocket
request received).  This logical name only controls server handshake support
and behaviour.  The underlying WebSocket library used by the application (e.g.
wsLIB.c) supports version idiosyncracies for other aspects.

<p> This string is also used as the list of versions reported in a 426 (upgrade
required) response when a client makes a request using an unsupported version.

<a id="5.6" href="#"></a>
<a id="5.6.websocketthroughput" href="#"></a>
<a id="websocketthroughput" href="#"></a>
<h2 class="head"><span class="numb">5.6</span><span class="text">WebSocket Throughput</span></h2>

<p> The raw WebSocket throughput of a platform (hardware plus VMS plus TCP/IP
stack plus WASD and optionally network infrastructure) can be measured using
the WSB utility.  Measures of raw message and byte throughput for a series of
messages of various sizes can provide useful information on the underlying
maximum messaging characteristics of that platform.

<p> The following example shows usage on an Alpha XP1000:

<div class="blockof code">&dollar; WSB == &quot;&dollar;WASD_EXE:WSB&quot;
&dollar; WSB /DO=ECHO /THROUGHPUT /REPEAT=1000 /SIZE=0
%WSB-I-STATS, 1 total connections
Duration: 0.303 seconds
Tx: 1000 msgs at 3303/S, 0 bytes at 0 B/S
Rx: 1000 msgs at 3303/S, 0 bytes at 0 B/S
Total: 2000 msgs at 6607/S, 0 bytes at 0 B/S
&dollar; WSB /DO=ECHO /THROUGHPUT /REPEAT=1000 /SIZE=16
%WSB-I-STATS, 1 total connections
Duration: 0.349 seconds
Tx: 1000 msgs at 2869/S, 16.0 kbytes at 45.9 kB/S
Rx: 1000 msgs at 2869/S, 16.0 kbytes at 45.9 kB/S
Total: 2000 msgs at 5737/S, 32.0 kbytes at 91.8 kB/S
&dollar; WSB /DO=ECHO /THROUGHPUT /REPEAT=1000 /SIZE=64
%WSB-I-STATS, 1 total connections
Duration: 0.359 seconds
Tx: 1000 msgs at 2783/S, 64.0 kbytes at 178.1 kB/S
Rx: 1000 msgs at 2783/S, 64.0 kbytes at 178.1 kB/S
Total: 2000 msgs at 5566/S, 128.0 kbytes at 356.2 kB/S
&dollar; WSB /DO=ECHO /THROUGHPUT /REPEAT=1000 /SIZE=256
%WSB-I-STATS, 1 total connections
Duration: 0.607 seconds
Tx: 1000 msgs at 1646/S, 256.0 kbytes at 421.5 kB/S
Rx: 1000 msgs at 1646/S, 256.0 kbytes at 421.5 kB/S
Total: 2000 msgs at 3293/S, 512.0 kbytes at 843.0 kB/S
&dollar; WSB /DO=ECHO /THROUGHPUT /REPEAT=1000 /SIZE=1024
%WSB-I-STATS, 1 total connections
Duration: 0.659 seconds
Tx: 1000 msgs at 1517/S, 1.0 Mbytes at 1.6 MB/S
Rx: 1000 msgs at 1517/S, 1.0 Mbytes at 1.6 MB/S
Total: 2000 msgs at 3034/S, 2.0 Mbytes at 3.1 MB/S
&dollar; WSB /DO=ECHO /THROUGHPUT /REPEAT=1000 /SIZE=65k
%WSB-I-STATS, 1 total connections
Duration: 10.279 seconds
Tx: 1000 msgs at 97/S, 65.0 Mbytes at 6.3 MB/S
Rx: 1000 msgs at 97/S, 65.0 Mbytes at 6.3 MB/S
Total: 2000 msgs at 195/S, 130.0 Mbytes at 12.6 MB/S
</div>

<p> For more information see the description in the prologue of the program. 
(A zero-size message is legitimate with the WebSocket protocol.)

<a id="5.7" href="#"></a>
<a id="5.7.websocketreferences" href="#"></a>
<a id="websocketreferences" href="#"></a>
<h2 class="head"><span class="numb">5.7</span><span class="text">WebSocket References</span></h2>

<ul class="list">

<li class="item"> <a class="link blank" target="_blank" href="http://en.wikipedia.org/wiki/WebSockets">http://en.wikipedia.org/wiki/WebSockets</a>
<br> Wikipedia overview of WebSockets

<li class="item"> <a class="link blank" target="_blank" href="https://html.spec.whatwg.org/multipage/comms.html#network">https://html.spec.whatwg.org/multipage/comms.html#network</a>
<br> The WebSocket API (JavaScript)

<li class="item"> <a class="link blank" target="_blank" href="http://tools.ietf.org/html/rfc6455">http://tools.ietf.org/html/rfc6455</a>
<br> The WebSocket protocol

<li class="item"> <a class="link blank" target="_blank" href="https://trac.tools.ietf.org/wg/hybi/trac/wiki/FAQ">https://trac.tools.ietf.org/wg/hybi/trac/wiki/FAQ</a>
<br> The IETF WebSocket FAQ

<li class="item"> <a class="link blank" target="_blank" href="http://websocketstest.com/">http://websocketstest.com/</a>
<br> Real-Time Web[socket] Test

</ul>

<a id="5.8" href="#"></a>
<a id="5.8.wasdquotrawquotsocket" href="#"></a>
<a id="wasdquotrawquotsocket" href="#"></a>
<h2 class="head"><span class="numb">5.8</span><span class="text">WASD &quot;Raw&quot;Socket</span></h2>

<p> The WASD <span class="high italic">RawSocket</span> is a variant of, and is heavily based on, the WASD
WebSocket infrastructure.  It allows a service (listening host and port) to
accept a connection and <span class="high italic">immediately</span> activate a configured WASD CGIplus
script to service that connection. Full-duplex, asynchronous, bidirectional
input/output is supported.  While being referred to as a &quot;socket&quot;, of course it
is not network socket communication (BSD or any other abstraction), but a
read/write abstraction via mailbox I/O.  Input is a stream of octets; output a
stream of octets.  The streams are opaque in this context and depend entirely
on the abstraction (protocol) being implemented by the script.  The &quot;RawSocket&quot;
is just WASD nomenclature for WebSocket-style scripting without the WebSocket
protocol.

<div class="note"><a id="5.8.0.0.0.1" href="#"></a>
<a id="5.8.note" href="#"></a>
<a id="note" href="#"></a>
<h5 class="head center"><span class="text">Note</span></h5>
<hr class="note_hr">

A RawSocket application is not intended to use a (standard web) browser as a
client.  Of course the application could (perhaps, also) behave as a web server
if at activation it (also) expected to receive, parse and respond to an HTTP
request, and therefore (also) be used by a web browser client.
<hr class="note_hr">
</div>

<p> The script when activated enters a CGIplus wait-service-wait loop using the
standard CGIplus mechanism.  When a request activates the script it issues a
&quot;100 Continue&quot; CGI/HTTP header to signal the server that the request is
accepted and now being processed.  This header is NOT relayed to the client. 
The activation parameters (normally referred to as <span class="high italic">request</span> parameters) are
available via the usual CGI variables.  The script can then read from and write
to the RAWSOCKET_INPUT and RAWSOCKET_OUTPUT devices respectively.  As with
WebSocket applications, a single RawSocket application (script) can
concurrently support multiple clients.  The end-of-script is indicated by
issuing an EOF to the mailbox.  The script activation can be as long-lived as
required and  the server will not run a request down for any timeout reason.

<a id="5.8.1" href="#"></a>
<a id="5.8.1.rawsocketapplication" href="#"></a>
<a id="rawsocketapplication" href="#"></a>
<h3 class="head"><span class="numb">5.8.1</span><span class="text">RawSocket Application</span></h3>

<p> RawSocket applications share the same lifecycle as described for WebSockets
in <a class="link" href="#5.2.websocketapplication">5.2 WebSocket Application</a>.

<a id="5.8.2" href="#"></a>
<a id="5.8.2.rawsocketlibrary" href="#"></a>
<a id="rawsocketlibrary" href="#"></a>
<h3 class="head"><span class="numb">5.8.2</span><span class="text">RawSocket Library</span></h3>

<p> <span class="high bold">rawLIB</span> is a C code module that provides a similar API and functionality
to the wsLIB library described in <a class="link" href="#5.3.websocketlibrary">5.3 WebSocket Library</a>.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/rawlib.c">WASD_ROOT:[SRC.WEBSOCKET]RAWLIB.C</a>

<a id="5.8.3" href="#"></a>
<a id="5.8.3.rawsocketapplicationexamples" href="#"></a>
<a id="rawsocketapplicationexamples" href="#"></a>
<h3 class="head"><span class="numb">5.8.3</span><span class="text">RawSocket Application Examples</span></h3>

<p> The WASD RawSocket implementation provides a number of scripting examples
illustrating programming basics and the use of the WASD rawLIB library.  All of
these illustrate multi-client support using asynchonouse I/O.  All use
<span class="high italic">telnet</span> as a client interface although this is only for convenience. 
RawSocket is completely protocol agnostic.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/*.*">WASD_ROOT:[SRC.WEBSOCKET]</a>

<a id="5.8.3.1" href="#"></a>
<a id="5.8.3.1.chat" href="#"></a>
<a id="chat" href="#"></a>
<h4 class="head"><span class="numb">5.8.3.1</span><span class="text">Chat</span></h4>

<p> This almost has to be <span class="high bold">the</span> classic example of asynchronous, bidirectional
communications.  Each connected client can enter a message and it is
distributed to all connected clients.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/raw_char.c">WASD_ROOT:[SRC.WEBSOCKET]RAW_CHAT.C</a>

<a id="5.8.3.2" href="#"></a>
<a id="5.8.3.2.echo" href="#"></a>
<a id="echo" href="#"></a>
<h4 class="head"><span class="numb">5.8.3.2</span><span class="text">Echo</span></h4>

<p> Each connected client can enter a message which is then returned to them.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/raw_echo.c">WASD_ROOT:[SRC.WEBSOCKET]RAW_ECHO.C</a>

<a id="5.8.3.3" href="#"></a>
<a id="5.8.3.3.terminalserver" href="#"></a>
<a id="terminalserver" href="#"></a>
<h4 class="head"><span class="numb">5.8.3.3</span><span class="text">Terminal Server</span></h4>

<p> This example implements a simple-minded telnet server.  Definitely not
intended for production.

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/websocket/raw_ptd.c">WASD_ROOT:[SRC.WEBSOCKET]RAW_PTD.C</a>

<a id="5.8.4" href="#"></a>
<a id="5.8.4.rawsocketconfiguration" href="#"></a>
<a id="rawsocketconfiguration" href="#"></a>
<h3 class="head"><span class="numb">5.8.4</span><span class="text">RawSocket Configuration</span></h3>

<p> RawSocket server applications are essentially CGIplus scripts and so are
mapped and activated in the same fashion as any other CGIplus script
(<a class="link" href="#3.3.otherconsiderations">3.3 Other Considerations</a>).  They are a little unique in that there is
generally a one-to-one relationship between a script and a service.  The
service is flagged as implementing a <span class="high italic">RawSocket</span> and that service is mapped
directly to a script.

<div class="blockof code"># WASD_CONFIG_SERVICE
[[http:*:1234]]
[ServiceRawSocket]  enabled

# WASD_CONFIG_MAP
[[*:1234]]
map * /cgiplus-bin/raw_script
</div>

<p> It is possible to have conditional mapping based on the (rather limited)
&quot;request&quot; parameters (WATCH is useful for understanding what request data is
available).  For example, the script activated may be varied on the client
address.

<div class="blockof code"># WASD_CONFIG_MAP
[[*:1234]]
if (remote-addr:131.185.10.0/24)
   map * /cgiplus-bin/raw_one
else
   map * /cgiplus-bin/raw_two
endif
</div>
<!-- source:0600_CALLOUTS.WASDOC -->
<hr class="page">
<a id="6." href="#"></a>
<a id="6.cgicallouts" href="#"></a>
<a id="cgicallouts" href="#"></a>
<h1 class="head"><span class="numb">6.</span><span class="text">CGI Callouts</span></h1>

<table class="TOC2table">
<tr><td><a href="#6.1.requestsandresponses"><span class="numb">6.1</span><span class="text">Requests and Responses</span></a>
<tr><td><a href="#6.2.codeexamples"><span class="numb">6.2</span><span class="text">Code Examples</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#5.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#7.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> During CGI or CGIplus processing (though not DECnet-based CGI) it is
possible to suspend  normal script  output to the client and for the script to
interact directly with the server, then resume output to the client.  This may
done more than once during processing.  During the <span class="high italic">callout</span> the script makes
a request of the server and receives a response.  These requests are to perform
some server function, such as the mapping of a path to a file specification, on
behalf of the script.  Naturally, this makes the script no longer portable, but
may be extrememly useful in some circumstances.

<p> It is this general callout mechanism that allows specific authentication agents
(<a class="link blank" target="_blank" href="../features/#authenticationandauthorization">Authentication and Authorization</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>)
to be  implemented as standard CGIplus scripts.

<p> The mechanism is quite simple.

<ol class="list">

<li class="item"> The script suspends normal output by writing a record containing a
unique <span class="high italic">escape</span> sequence.

<li class="item"> It then writes a record containing a formatted request.  The server
interprets the request, performs the action and returns a success or error
response.

<li class="item"> The script concludes the callout by writing a record containing a
unique <span class="high italic">end-of-text</span> sequence.

<li class="item"> The script reads the server's response and continues processing.  In
reality the response read could occur immediately after the request write (i.e.
before the concluding end-of-text sequence).

</ol>

<p> This is a basic callout.  Between the callout escape and end-of-text
sequences multiple request/responses transactions may be undertaken.

<a id="6.1" href="#"></a>
<a id="6.1.requestsandresponses" href="#"></a>
<a id="requestsandresponses" href="#"></a>
<h2 class="head"><span class="numb">6.1</span><span class="text">Requests and Responses</span></h2>

<p> The request record is plain text, comprising a request key-word
(case-insensitive), full-colon, and following optional white-space and
parameter(s).  It is designed not to be implementation language specific.

<p> The response record is also plain-text.  It begins with a three-digit
response code, with similar meanings and used for the same purpose as HTTP
response codes.  That is 200 is a success status, 500 a server error, 400 a
request error, etc.  Following the response code is white-space and the plain
text result or error message.  A response to any given callout request may be
suppressed by providing a request record with a leading <span class="high monosp">!</span> (exclamation
point) or <span class="high monosp">#</span> (hash symbol).

<ul class="list">

<li class="item"> <span class="high bold">AGENT-BEGIN:</span> <span class="high italic">&lt;string&gt;</span>

<p> WASD v12.0 and later agents require the agent to declare its role and
typically provide some information about itself.  An example callout is shown
below. 

<div class="blockof code">CgiLibCgiPlusCallout (&quot;!AGENT-BEGIN: %s (%s) usage:%d&quot;,
                      SoftwareId, CgiLibEnvironmentVersion(),
                      CgiPlusUsageCount);
</div>

<li class="item"> <span class="high bold">AGENT-END:</span> <span class="high italic">&lt;string&gt;</span>

<p> WASD v12.0 and later agents are required to declare process concluded, and
optionally to return any results to the calling code.

<div class="blockof code">CgiLibCgiPlusCallout (&quot;!AGENT-END:&quot;);
</div>

<div class="blockof code">CgiLibCgiPlusCallout (&quot;!AGENT-END: 418 %s&quot;, cptr);
</div>

<li class="item"> <span class="high bold">AUTH-FILE:</span> <span class="high italic">&lt;file specification&gt;</span>

<p> If the specialized /PROFILE capability is enabled 
(<a class="link blank" target="_blank" href="../features/#sysuafsecurityprofile">SYSUAF Security Profile</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>)
this can determine whether the specified file name is allowed access by the
request's username.

<li class="item"> <span class="high bold">BUFFER-BEGIN:</span> <span class="high italic">&lt;integer&gt;[k&verbar;M]</span>

<p> Create a temporary global section to act as a memory buffer shared between a
script process and the server.  The default is <span class="high bold">M</span>egabytes.  See
<a class="link" href="#2.2.3.bulkcontentoutput">2.2.3 Bulk Content Output</a> for a description of the purpose and use of all the
BUFFER-.. callouts.

<li class="item"> <span class="high bold">BUFFER-END:</span>

<p> Dispose of the shared memory buffer created by callout BUFFER-BEGIN.

<li class="item"> <span class="high bold">BUFFER-WRITE:</span> <span class="high italic">&lt;integer&gt;</span>

<p> Instruct the server to write &lt;integer&gt; bytes from the shared
memory buffer to the client.

<li class="item"> <span class="high bold">CGI:</span> <span class="high italic">string</span>

<p> Specialised callout allowing an access agent, lookup agent or meta agent to
insert, modify or delete a CGI variable for a request.  These agents are
currently only <span class="high bold">proof-of-concept</span>.  See sources in

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/agent/*.*">WASD_ROOT:[SRC.AGENT]</a>

<li class="item"> <span class="high bold">CGIPLUS:</span> <span class="high italic">string</span>

<p> This callout is used to indicate to the server that a CGIplus script can
process the CGI variables in &quot;struct&quot; mode.  By default each CGI variable is
transfered to a CGIplus script one &quot;record&quot; at a time.  In &quot;struct&quot; mode all
variables are transfered in a single, binary I/O which must the be parsed by
the the script.  It is of course a much more efficient method for CGIplus
(<a class="link" href="#3.1.structmodecgiplus">&lsquo;Struct-Mode CGIplus&rsquo; in 3.1 CGIplus Programming</a>).

<li class="item"> <span class="high bold">CSP:</span> <span class="high italic">&lt;string&gt;</span> <br>
<span class="high bold">CSPRO:</span> <span class="high italic">&lt;string&gt;</span> 

<p> Provide Content Security Policy (CSP) configuration(s) from a script.

<p> See <a class="link blank" target="_blank" href="../config/#contentsecuritypolicycsp">Content Security Policy (CSP)</a> in <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>.

<li class="item"> <span class="high bold">DICT:</span> <span class="high italic">string</span>

<p> Specialised callout allowing an access agent, lookup agent or meta agent to
insert, modify or delete a dictionary entry.  These agents are currently only
<span class="high bold">proof-of-concept</span>.  See sources in

<p class="indent"> <a class="link blank monosp" target="_blank" href="/wasd_root/src/agent/*.*">WASD_ROOT:[SRC.AGENT]</a>

<li class="item"> <span class="high bold">GATEWAY-BEGIN:</span> <span class="high italic">&lt;integer&gt;</span>

<p> When using the raw TCP/IP socket for output (<a class="link" href="#11.rawtcpipsocket">11. Raw TCP/IP Socket</a>)
this callout is used to notify the server that  the script will be using the
gateway device and the HTTP status code (e.g. 200, 302, 404, etc.)

<li class="item"> <span class="high bold">GATEWAY-CCL:</span> <span class="high italic">&lt;integer&gt;</span>

<p> When using the raw TCP/IP socket for output (<a class="link" href="#11.rawtcpipsocket">11. Raw TCP/IP Socket</a>)
this can be used to change the BG: device carriage-control.  A value of 1
enables a &lt;CR&gt;&lt;LF&gt; with each record (the default), while 0 disables
it.  This is analagous to the APACHE&dollar;SET_CCL utility.

<li class="item"> <span class="high bold">GATEWAY-END:</span> <span class="high italic">&lt;integer&gt;</span>

<p> When using the raw TCP/IP socket for output (<a class="link" href="#11.rawtcpipsocket">11. Raw TCP/IP Socket</a>)
this callout is used to notify the server of  the quantity of data transfered
directly to the client by the script.

<li class="item"> <span class="high bold">LIFETIME:</span> <span class="high italic">&lt;integer&gt;</span>

<p> Sets/resets a scripting process' lifetime which may be expressed as an
integer number of minutes or in the format <span class="high italic">hh:mm:ss</span>.  For instance, use to
give frequently used  CGIplus scripts an extended lifetime before being rundown
by the server (override the [DclCgiPlusLifeTime] configuration parameter). 
Specifying &quot;none&quot; (or -1) gives it an <span class="high italic">infinite</span> lifetime, zero resets to
default.

<li class="item"> <span class="high bold">MAP-FILE:</span> <span class="high italic">&lt;file specification&gt;</span>

<p> Map the supplied file specification to its URL-style path equivalent, and
against the server's mapping rule.  This does not check the file name is legal
RMS syntax.

<li class="item"> <span class="high bold">MAP-PATH:</span> <span class="high italic">&lt;URL-style path&gt;</span>

<p> Map the supplied URL-style path against the server's rule database into a
VMS file specification.  Note that this does not verify the file name legaility
or that the file actually exists.

<li class="item"> <span class="high bold">NOOP:</span>

<p> No operation.  Just return a success response.

<li class="item"> <span class="high bold">NOTICED:</span> <span class="high italic">&lt;string&gt;</span>

<p> Place the supplied string into the server process log.  Used to report
incidental processing or other errors.

<li class="item"> <span class="high bold">OPCOM:</span> <span class="high italic">&lt;string&gt;</span>

<p> Send the supplied string to OPCOM.

<li class="item"> <span class="high bold">REDACT:</span>

<p> See <a class="link" href="#10.requestredaction">10. Request Redaction</a>.

<li class="item"> <span class="high bold">REDACT-SIZE:</span>

<p> See <a class="link" href="#10.requestredaction">10. Request Redaction</a>.

<li class="item"> <span class="high bold">SCRIPT-CONTROL:</span>

<p> Equivalent to the script issuing a &quot;Script-Control:&quot; response header field
(although of course some script control directives will not apply after header
generation).

<li class="item"> <span class="high bold">TIMEOUT-BIT-BUCKET:</span> <span class="high italic">&lt;integer&gt;</span>

<p> Specifies the period for which a script continues to execute if the client
disconnects.  Overrides the WASD_CONFIG_GLOBAL [DclBitBucketTimeout] confiuration
directive.

<li class="item"> <span class="high bold">TIMEOUT-OUTPUT:</span> <span class="high italic">&lt;integer&gt;</span>

<p> Sets/resets a script request lifetime (in minutes, overrides the
[TimeoutOutput] configuration parameter).  Specifying &quot;none&quot; (or -1) gives it
an <span class="high italic">infinite</span> lifetime, zero resets to default.

<li class="item"> <span class="high bold">TIMEOUT-NOPROGRESS:</span> <span class="high italic">&lt;integer&gt;</span>

<p> Sets/resets a script request no-progress (in minutes, overrides the
[TimeoutNoProgress] configuration parameter).  The <span class="high italic">no-progress</span> period is the
maximum number of seconds that there may be no output from the script before it
is aborted.  Specifying &quot;none&quot; (or -1) gives it an <span class="high italic">infinite</span> lifetime, zero
resets to default.

</ul>

<a id="6.2" href="#"></a>
<a id="6.2.codeexamples" href="#"></a>
<a id="codeexamples" href="#"></a>
<h2 class="head"><span class="numb">6.2</span><span class="text">Code Examples</span></h2>

<p> The record-oriented callout sequences and request/response makes
implementation quite straight-forward.  The following C language and DCL
procedure code fragments illustrate the basics.

<div class="blockof code">/* C language */
CgiPlusIn = fopen (&quot;CGIPLUSIN:&quot;, &quot;r&quot;);
printf (&quot;%s\nMAP-FILE: %s\n%s\n&quot;,
        getenv(&quot;CGIPLUSESC&quot;), FileNamePtr, getenv(&quot;CGIPLUSEOT&quot;));
fgets (CalloutResponse, sizeof(CalloutResponse), CgiPlusIn);

&dollar;! DCL procedure
&dollar; open /read CgiPlusIn CGIPLUSIN
&dollar; write sys&dollar;output f&dollar;trnlnm(&quot;CGIPLUSESC&quot;)
&dollar; write sys&dollar;output &quot;MAP-PATH: &quot; + PathPtr
&dollar; read CgiPlusIn Response
&dollar;!(no need to read a response for this next request, it's suppressed)
&dollar; write sys&dollar;output &quot;#TIMEOUT-OUTPUT:10&quot;
&dollar; write sys&dollar;output f&dollar;trnlnm(&quot;CGIPLUSEOT&quot;)
</div>

<p> Also see working examples in
<a class="link blank monosp" target="_blank" href="/wasd_root/src/CGIplus/*callout*.*">WASD_ROOT:[SRC.CGIPLUS]</a>
<!-- source:0700_ISAPI.WASDOC -->
<hr class="page">
<a id="7." href="#"></a>
<a id="7.isapi" href="#"></a>
<a id="isapi" href="#"></a>
<h1 class="head"><span class="numb">7.</span><span class="text">ISAPI</span></h1>

<table class="TOC2table">
<tr><td><a href="#7.1.cgisapi"><span class="numb">7.1</span><span class="text">CGIsapi</span></a>
<tr><td><a href="#7.2.writingisapiscripts"><span class="numb">7.2</span><span class="text">Writing ISAPI Scripts</span></a>
<tr><td><a href="#7.3.serverconfiguration"><span class="numb">7.3</span><span class="text">Server Configuration</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#6.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#8.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> ISAPI (procounced <span class="high italic">eye-sap-ee</span>) was developed by Process Software
Corporation (the developer of Purveyor Encrypt Web Server available under VMS),
Microsoft Corporation and a small number of other vendors.  It has an software
infrastructure similar to CGI but a different architecture.  It is designed to
eliminate the expensive process creation overheads of CGI (under Unix, let
alone VMS), reduce latency for expensive-to-activate resources, and generally
improve server throughput, particularly on busy sites.

<p> Unlike standard CGI, which creates a child process to service each request,
ISAPI is designed to load additional sharable code (DLLs, or Dynamic Link
Libraries in MSWindows, shareable images under VMS) into the Web server's
process space. These are known as server <span class="high italic">extensions</span>. This radically reduces
the overheads of subsequent request processing and makes possible server
functionality that can maintain resources between requests (for instance keep
open a large database), again contributing to reduced latency and increased
throughput.

<p> Of course there is a down-side!  Loading foreign executable code into the
server compromises its integrity.  Poorly written extensions can seriously
impact server performance and in the worst-case even crash a server process.
The other significant concern is the multi-threaded environment of most
servers.  Extensions must be carefully constructed so as not to impact the
granularity of processing in a server and to be <span class="high italic">thread-safe</span>, not creating
circumstances where processing corruption or deadlock occurs.

<a id="7.1" href="#"></a>
<a id="7.1.cgisapi" href="#"></a>
<a id="cgisapi" href="#"></a>
<h2 class="head"><span class="numb">7.1</span><span class="text">CGIsapi</span></h2>

<p> WASD provides an environment for executing ISAPI based extensions.  Unlike
classic ISAPI the DLLs are not loaded into server space but into autonomous
processes, in much the same way as CGIplus scripts are handled
(<a class="link" href="#3.cgiplus">3. CGIplus</a>).  This still offers significantly improved performance
through the persistance of the ISAPI extension between requests.  Measurements
show a potential five-fold, to in excess of ten-fold increase in throughput 
compared to an equivalent CGI script!  This is comparable to reported
performance differences between the two environments in the Microsoft IIS
environment.

<p> While the script process context does add more overhead than if the DLL was  
loaded directly into the server process space, it does have two significant
advantages.

<ol class="list">

<li class="item"> Buggy DLL code will generally not directly affect the integrity of the
server process.  At worst the script process may terminate.

<li class="item"> Each process services only the one request at a time.  This eliminates
the threading issues.

</ol>

<p> WASD implements the ISAPI environment as an instance of its CGIplus
environment.  CGIplus shares two significant characteristics with ISAPI,
persistance and a CGI-like environment.  This allows a simple CGIplus
<span class="high italic">wrapper</span> script to be used to load and interface with the ISAPI DLL. After
being loaded the ISAPI-compliant code cannot tell the difference between the
WASD environment and any other vanilla ISAPI one!

<p> This wrapper is known as <span class="high bold">CGIsapi</span> (pronounced <span class="high italic">see-gee-eye-sap-ee</span>).

<p> Wrapping another layer does introduce overhead not present in
the native CGIplus itself, however measurements indicate in <span class="high italic">the real
world</span> (tm) performance of the two is quite comparable. See
<a class="link blank" target="_blank" href="../features/#serverperformance">Server Performance</a> in <a class="link blank" target="_blank" href="../features/#0.">WASD Features</a>
for further information.  The advantage of ISAPI over CGIplus is not
performance but the fact it's a well documented interface.  Writing a script to
that specification may be an easier option, particularly for sites with a
mixture or history of different Web servers, than learning the CGIplus
interface (simple as CGIplus is).

<a id="7.2" href="#"></a>
<a id="7.2.writingisapiscripts" href="#"></a>
<a id="writingisapiscripts" href="#"></a>
<h2 class="head"><span class="numb">7.2</span><span class="text">Writing ISAPI Scripts</span></h2>

<p> This section is by-no-means a tutorial on how to write for ISAPI.

<p> First, get a book on ISAPI.  Second, ignore most of it!  Generally these
tomes concentrate on the Microsoft environment.  Still, information on the
basic behaviour of ISAPI extensions and the Internet Server API is valuable. 
Other resources are available at no cost from the Microsoft and Process
Software Corporation sites.

<p> Have a look at the WASD example DLL and its build procedure in
<a class="link blank monosp" target="_blank" href="/wasd_root/src/cgiplus/*isapi*.*?httpd=index&amp;readme=no">WASD_ROOT:[SRC.CGIPLUS]</a>

<p> The CGIsapi wrapper,
<a class="link blank monosp" target="_blank" href="/wasd_root/src/cgiplus/cgisapi.c">WASD_ROOT:[SRC.CGIPLUS]CGISAPI.C</a>,
is relatively straight-forward, relying on CGIplus for IPC with the parent
server process.  A brief description of the detail of the implementation is
provided in the source code.

<p> CGIsapi has a simple facility to assist with debugging DLLs. When enabled,
information on passed parameters is output whenever a call is made to an ISAPI
function.  This debugging can be toggled on and off whenever desired.  Once
enabled DLL debugging remains active through multiple uses of a CGISAPI
instance, or until disabled, or until the particular CGISAPI process' lifetime
expires.  Check detail in the CGIsapi source code description.

<a id="7.2.0.0.1" href="#"></a>
<a id="7.2.cgisapiconsiderations" href="#"></a>
<a id="cgisapiconsiderations" href="#"></a>
<h5 class="head"><span class="text">CGIsapi Considerations</span></h5>

<p> The wrapper is designed to be ISAPI 1.0 compliant.  It should also be
vanilla ISAPI 2.0 compliant (not the Microsoft WIN32 variety, so don't think
you'll necessarily be able to grab all those IIS extensions and just recompile
and use ;^)

<p> With CGIsapi multiple instances of any one extension may be active on the
one  server (each in an autonomous process, unlike a server-process-space
loaded extension where only one would ever be active at any one time).  Be
aware this could present different concurrency issues than one multiple or
single threaded instance.

<p> When CGIplus processes are idle they can be run-down at any time by the
server at expiry of lifetime or to free up required server resources.  For this
reason ISAPI extensions (scripts) should finalize the processing of
transactions when finished, not leave anything in a state where its unexpected
demise might corrupt resources or otherwise cause problems (which is fairly
good general advice anyway <span class="high monosp">;^)</span>  That is, when finished tidy up as much as
is necessary.

<p> CGIsapi loaded extensions can exit at any time they wish.  The process
context allows this.  Of course, normally a server-process-space loaded
instance would not be able to do so!

<p> For other technical detail refer to the description with the source code.

<div class="note">
<a id="7.2.0.0.2" href="#"></a>
<a id="7.2.hint" href="#"></a>
<a id="hint" href="#"></a>
<h5 class="head center"><span class="text">Hint!</span></h5>
<hr class="note_hr">
Whenever developing ISAPI extensions don't forget that after compiling,
the old version must be purged from the server before trying out the new!!!
<p> Scripting processes may be purged or deleted using (
&quot;Techncial Overview, Server Command Line Control&quot;):
<div class="blockof code">&dollar; HTTPD /DO=DCL=DELETE
&dollar; HTTPD /DO=DCL=PURGE
</div>
<hr class="note_hr">
</div>

<a id="7.3" href="#"></a>
<a id="7.3.serverconfiguration" href="#"></a>
<a id="serverconfiguration" href="#"></a>
<h2 class="head"><span class="numb">7.3</span><span class="text">Server Configuration</span></h2>

<p> Ensure the following are in the appropriate sections of WASD_CONFIG_GLOBAL.

<div class="blockof code">[DclScriptRunTime]
.DLL  &dollar;CGI-BIN:[000000]CGISAPI.EXE

[AddType]
.DLL  application/octet-stream  -  ISAPI extension DLL
</div>

<p> Ensure this rule exists in the scripting section of WASD_CONFIG_MAP.

<div class="blockof code">exec+ /isapi/* /cgi-bin/*
</div>

<p> With this rule DLLs may be accessed using something like

<div class="blockof code">http://host.name.domain/isapi/isapiexample.dll
</div>
<!-- source:0800_DECNET.WASDOC -->
<hr class="page">
<a id="8." href="#"></a>
<a id="8.decnetamposu" href="#"></a>
<a id="decnetamposu" href="#"></a>
<h1 class="head"><span class="numb">8.</span><span class="text">DECnet &amp; OSU</span></h1>

<div class="TOC2cols2">
<table class="TOC2table">
<tr><td><a href="#8.1.scriptsystemenvironment"><span class="numb">8.1</span><span class="text">Script System Environment</span></a>
<tr><td><a href="#8.1.1.proxyaccess"><span class="numb">8.1.1</span><span class="text">Proxy Access</span></a>
<tr><td><a href="#8.1.2.decnetobjects"><span class="numb">8.1.2</span><span class="text">DECnet Objects</span></a>
<tr><td><a href="#8.1.3.reducingscriptlatency"><span class="numb">8.1.3</span><span class="text">Reducing Script Latency</span></a>
<tr><td><a href="#8.1.4.decnetosustartup"><span class="numb">8.1.4</span><span class="text">DECnet/OSU Startup</span></a>
<tr><td><a href="#8.2.cgi"><span class="numb">8.2</span><span class="text">CGI</span></a>
<tr><td><a href="#8.3.osudecthreadsemulation"><span class="numb">8.3</span><span class="text">OSU (DECthreads) Emulation</span></a>
<tr><td><a href="#8.4.userscripts"><span class="numb">8.4</span><span class="text">User Scripts</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#7.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#9.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> <span class="high italic" style="font-size:1.1em;">&quot;Imitation is the sincerest form of flattery&quot;</span> &ndash; proverb

<div class="note center"><a id="8.0.0.0.0.1" href="#"></a>
<a id="8.note" href="#"></a>
<a id="note" href="#"></a>
<h5 class="head center"><span class="text">Note</span></h5>
<hr class="note_hr">

WASD requires no additional configuration to support detached process-based
scripting.
<br> The following information applies only if DECnet-based scripting is desired.
<hr class="note_hr">
</div>

<p> By default WASD executes scripts within detached processes, but can also
provide scripting using DECnet for the process management. DECnet scripting is
not provided to generally supplant the detached process-based scripting but
augment it for certain circumstances:

<ul class="list">

<li class="item"> To provide an environment within WASD where OSU-based scripts (both CGI
and OSU-specific) may be employed without modification.

<li class="item"> To allow nodes without a full HTTP service to participate in providing
resources via a well-known server, possibly resources that only they have
access to.

<li class="item"> Load-sharing amongst cluster members for <span class="high italic">high-impact</span> scripts
or particularly busy sites.

<li class="item"> Provide user-account scripting.

</ul>

<a id="8.0.0.0.1" href="#"></a>
<a id="8.decnetperformance" href="#"></a>
<a id="decnetperformance" href="#"></a>
<h5 class="head"><span class="text">DECnet Performance</span></h5>

<p> Any DECnet based processing incurs some overheads:

<ul class="list simple list0">
<li class="item"> connection establishment
<li class="item"> NETSERVER image activation
<li class="item"> NETSERVER maintenance (such as logs, etc.)
<li class="item"> activation of DECnet object image or procedure
<li class="item"> DECnet object processing
<li class="item"> activation by object of image or procedure
<li class="item"> DECnet object run-down
<li class="item"> NETSERVER image reactivation
</ul>

<p> As of version 5.2 WASD provides reuse of DECnet connections for both CGI and
OSU scripting, in-line with OSU v3.3 which provided reuse for OSU scripts. This
means multiple script requests can be made for the cost of a single DECnet
connection establishment and task object activation. Note that the OSU task
procedure requires the definition of the logical name WWW_SCRIPT_MAX_REUSE
representing the number of times a script may be reused. The WASD startup
procedures can provide this.

<p> In practice both the WASD CGI and OSU scripts seem to provide acceptable
responsiveness.

<a id="8.0.0.0.2" href="#"></a>
<a id="8.rulemapping" href="#"></a>
<a id="rulemapping" href="#"></a>
<h5 class="head"><span class="text">Rule Mapping</span></h5>

<p> DECnet-based scripts are mapped using the same rules as process-based
scripts, using the SCRIPT and EXEC rules
(<a class="link blank" target="_blank" href="../config/#mappinguserdirectories">Mapping User Directories</a> in <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>)
for general information on mapping rules). DECnet scripts have a DECnet node
and <span class="high italic">task specification string</span> as part of the mapping rule. There are minor
variations within these to further identify it as a WASD or an OSU script
(<a class="link" href="#8.4.userscripts">8.4 User Scripts</a>).

<p> The specification string follows basic VMS file system syntax (RMS),
preceding the file components of the specification.  The following example
illustrates declaring that paths beginning with FRODO will allow the execution
of scripts from the CGI-BIN:[000000] directory on DECnet node FRODO.

<div class="blockof code">exec /FRODO/* /FRODO::/cgi-bin/*
</div>

<p> In similar fashion the following example illustrates a script &quot;frodo_show&quot;
that might do a &quot;SHOW SYSTEM&quot; on node FRODO.  Note that these rules are
case-insensitive.

<div class="blockof code">script /frodo-showsys /frodo::/cgi-bin/showsys.com
</div>

<p> Both of the above examples would use the WASD CGI DECnet environment (the
default if no task specification string is provided). By including task
information other environments, in particular the OSU scripting enviroment, can
be specified for the script to be executed within. The default task is named
CGIWASD and can also be explicitly specified (although this behaviour would be
the same as that in the first example)

<div class="blockof code">exec /frodo/* /frodo::&quot;task=cgiwasd&quot;/cgi-bin/*
</div>

<p> All task specification strings may also use zero as the task abbreviation.

<div class="blockof code">exec /frodo/* /frodo::&quot;0=cgiwasd&quot;/cgi-bin/*
</div>

<p> To execute a script within the OSU environment specify the standard OSU
task executive WWWEXEC, as in the following example:

<div class="blockof code">exec /osu/* /FRODO::&quot;task=wwwexec&quot;/htbin/*
</div>

<p> This would allow any URL beginning with &quot;/osu/&quot; to execute a script
in the OSU environment.

<a id="8.0.0.0.3" href="#"></a>
<a id="8.scriptingaccount" href="#"></a>
<a id="scriptingaccount" href="#"></a>
<h5 class="head"><span class="text">Scripting Account</span></h5>

<p> By default the script process is created using the HTTPd scripting account
(usually HTTP&dollar;NOBODY, although versions prior to 8.1 have used HTTP&dollar;SERVER). 
It is possible to specify alternate accounts for the scripts to be executed
within.

<p> The first examples are explicitly specifying an account in the script rule.

<div class="blockof code">exec /frodo/* /FRODO&quot;ACCOUNT&quot;::&quot;0=cgiwasd&quot;/cgi-bin/*
script /frodo-whatever /FRODO&quot;ACCOUNT&quot;::/cgi-bin/whatever.com
</div>

<p> It is also possible to have scripts that have been subject to SYSUAF
authorization executed within the authenticated account.  The dollar symbol in
the following examples directs the server to substitute the authenticated
username into the access string.

<div class="blockof code">exec /frodo/* /FRODO&quot;&dollar;&quot;::&quot;0=cgiwasd&quot;/cgi-bin/*
script /frodo-whatever /FRODO&quot;&dollar;&quot;::/cgi-bin/whatever.com
</div>

<p> The <span class="high italic">set script=as=</span> rule used for PERSONA controlled process scripting can
also be applied to DECnet scripts.  This includes explicitly specified
usernames as well as SYSUAF authenticated usernames.  The server creates an
appropriate access string when the script is activated.

<div class="blockof code">set /frodo* script=as=&dollar;
exec /frodo/* /FRODO::&quot;0=cgiwasd&quot;/cgi-bin/*
script /frodo-whatever /FRODO::/cgi-bin/whatever.com
</div>

<p> User scripts can also be activated using these rules, either explicitly
specifying the &quot;~&quot; in an access string or using the <span class="high italic">set script=as=</span> mapping
rule.

<div class="blockof code">exec /~*/cgi-bin/* /0&quot;~&quot;::/www_user/*/www/cgi-bin/*
exec /~*/htbin/* /0&quot;~&quot;::&quot;0=wwwexec&quot;/www_user/*/www/htbin/*
</div>

<p> See <a class="link" href="#8.4.userscripts">8.4 User Scripts</a> for more detail.

<a id="8.0.0.0.4" href="#"></a>
<a id="8.localsystem" href="#"></a>
<a id="localsystem" href="#"></a>
<h5 class="head"><span class="text">Local System</span></h5>

<p> To specify any script to execute on the same system as the HTTP server
specify the node name as zero or SYS&dollar;NODE.

<div class="blockof code">exec /decnet/* /0::&quot;task=cgiwasd&quot;/cgi-bin/*
exec /osu/* /sys&dollar;node::&quot;task=wwwexec&quot;/cgi-bin/*
</div>

<p> Mapping rules are included in the examples
<a class="link blank monosp" target="_blank" href="/wasd_root/example/">WASD_ROOT:[EXAMPLE]</a>
providing this. After the DECnet environment has been started any CGI script
may be executed on the local system via DECnet by substituting &quot;/decnet/&quot; for
&quot;/cgi-bin/&quot; as the script path, and any OSU script available by using &quot;/osu/&quot;.
Behaviour is indeterminate, though it shouldn't be catastrophic, if one is
invoked using the incorrect path (i.e. an OSU script using /decnet/ or a CGI
script using /osu/).

<a id="8.1" href="#"></a>
<a id="8.1.scriptsystemenvironment" href="#"></a>
<a id="scriptsystemenvironment" href="#"></a>
<h2 class="head"><span class="numb">8.1</span><span class="text">Script System Environment</span></h2>

<p> The target system must have sufficient of the WASD server environment to
support the required CGI script activation and activity. If the target system
is actually the same system as the HTTP server then it already exists, or if
part of the local system's cluster, then providing this should be relatively
straight-forward. If the target system has none of the server environment then
at a minimum it must have the logical name CGI-BIN defined representing the
directory containing the required DECnet object procedure and scripts. The
following fragment illustrates this:

<div class="blockof code">&dollar; DEFINE /SYSTEM /TRANSLATION=(CONCEALED) CGI-BIN device:[dir.]
</div>

In this directory must be located the WASDCGI.COM and WWWEXEC.COM procedures
required by the network task.  Of course other parts of the environment may
need to be provided depending on script requirements.

<a id="8.1.1" href="#"></a>
<a id="8.1.1.proxyaccess" href="#"></a>
<a id="proxyaccess" href="#"></a>
<h3 class="head"><span class="numb">8.1.1</span><span class="text">Proxy Access</span></h3>

<p> The local system must have <span class="high italic">proxy access</span> to each target scripting system
(even if that &quot;target&quot; system is the same system as the HTTP server). This
involves creating a proxy entry in each target hosts's authorization database.
The following example assumes the existance of a local HTTP&dollar;NOBODY account. If
it does not exist on the target node then one must be created with the same
security profile as the HTTP server's.

<div class="note">
<a id="8.1.1.0.1" href="#"></a>
<a id="8.1.1.caution" href="#"></a>
<a id="caution" href="#"></a>
<h5 class="head center"><span class="text">Caution!</span></h5>
<hr class="note_hr">
If unsure of the security implications of this action consult the relevant
VMS system management security documentation.
<hr class="note_hr">
</div>

<p> The zero represents the system the server is currently executing on.

<div class="blockof code">&dollar; SET DEFAULT SYS&dollar;SYSTEM
&dollar; MCR AUTHORIZE
UAF&gt; ADD /PROXY 0::HTTP&dollar;SERVER HTTP&dollar;NOBODY /DEFAULT
</div>

<p> It is necessary to ensure the account has permission to write into
its home directory.  A network process creates a NETSERVER.LOG (Phase-IV) or
NET&dollar;SERVER.LOG (DECnet-Plus) file in the home directory, and will fail to start
if it cannot!

<a id="8.1.2" href="#"></a>
<a id="8.1.2.decnetobjects" href="#"></a>
<a id="decnetobjects" href="#"></a>
<h3 class="head"><span class="numb">8.1.2</span><span class="text">DECnet Objects</span></h3>

<p> To provide DECnet scripting DECnet <span class="high italic">object(s)</span> must be specified
for any system on which the scripts will be executed. The DECnet object is the
program or procedure that is activated at the target system inside of a
network-mode process to interact with the HTTP server.

<a id="8.1.2.0.1" href="#"></a>
<a id="8.1.2.decnetplusosiphasev" href="#"></a>
<a id="decnetplusosiphasev" href="#"></a>
<h5 class="head"><span class="text">DECnet-Plus (OSI/Phase-V)</span></h5>

<p> DECnet-Plus uses the NCL utility to administer the network environment. The
following NCL scripting shows the creation of a network application for the
WASD CGI object:

<div class="blockof code">&dollar; MCR NCL
CREATE NODE 0 SESSION CONTROL APPLICATION CGIWASD
SET NODE 0 SESSION CONTROL APPLICATION CGIWASD ADDRESSES = {NAME=CGIWASD} -
,CLIENT =  -
,INCOMING ALIAS = TRUE -
,INCOMING PROXY = TRUE -
,OUTGOING ALIAS = FALSE -
,OUTGOING PROXY = TRUE -
,NODE SYNONYM = TRUE -
,IMAGE NAME = CGI-BIN:[000000]CGIWASD.COM -
,INCOMING OSI TSEL =
</div>

<p> To create a DECnet-Plus OSU WWWEXEC object:

<div class="blockof code">&dollar; MCR NCL
SET NODE 0 SESSION CONTROL APPLICATION WWWEXEC ADDRESSES = {NAME=WWWEXEC} -
,CLIENT =  -
,INCOMING ALIAS = TRUE -
,INCOMING PROXY = TRUE -
,OUTGOING ALIAS = FALSE -
,OUTGOING PROXY = TRUE -
,NODE SYNONYM = TRUE -
,IMAGE NAME = CGI-BIN:[000000]WWWEXEC.COM -
,INCOMING OSI TSEL =
</div>

<p> These must be executed at each system (or server) startup, and may be
executed standalone, as illustrated, or incorporated in the NCL script
SYS&dollar;STARTUP:NET&dollar;APPLICATION_STARTUP.NCL for automatic creation at each system
startup. Examples may be found in
<a class="link blank monosp" target="_blank" href="/wasd_root/example/">WASD_ROOT:[EXAMPLE]</a>

<a id="8.1.2.0.2" href="#"></a>
<a id="8.1.2.phaseiv" href="#"></a>
<a id="phaseiv" href="#"></a>
<h5 class="head"><span class="text">Phase-IV</span></h5>

<p> DECnet Phase-IV uses the NCP utility to administer the network
environment. The following NCP commands may be used each time during server
startup to create the required DECnet objects. With Phase-IV the SET verb may
be replaced with a DEFINE verb and the commands issued just once to
permanently create the objects (a SET must also be done that first time to
create working instances of the DEFINEd objects).

<p> To create a DECnet CGI object:

<div class="blockof code">&dollar; MCR NCP
SET OBJECT CGIWASD NUMBER 0 FILE CGI-BIN:[000000]CGIWASD.COM
</div>

<p> To create a DECnet OSU WWWEXEC object:

<div class="blockof code">&dollar; MCR NCP
SET OBJECT WWWEXEC NUMBER 0 FILE CGI-BIN:[000000]WWWEXEC.COM
</div>

<p> Examples may be found in
<a class="link blank monosp" target="_blank" href="/wasd_root/example/">WASD_ROOT:[EXAMPLE]</a>

<a id="8.1.3" href="#"></a>
<a id="8.1.3.reducingscriptlatency" href="#"></a>
<a id="reducingscriptlatency" href="#"></a>
<h3 class="head"><span class="numb">8.1.3</span><span class="text">Reducing Script Latency</span></h3>

<p> Script system network process persistance may be configured using NETSERVER
logical names. These can control the number and quiescent period of the server
processes. These logical names must be defined in the LOGIN.COM of the HTTP
server account on the target script system.

<ul class="list">


<li class="item"> <span class="high bold">NETSERVER&dollar;SERVERS_<span class="high italic">username</span> &ndash; </span>
This logical controls the number of network server processes that are kept
available at any one time. Defining this logical results in a minimum of the
specified number of quiescent server processes maintained. This can improve
script response latency by circumventing the need to create a process to
service the request, at the cost of cluttering the system with NETSERVER
processes.

<div class="blockof code">DEFINE /JOB NETSERVER&dollar;SERVERS_HTTP&dollar;NOBODY 5
</div>

<li class="item"> <span class="high bold">NETSERVER&dollar;TIMEOUT &ndash; </span>
This logical controls the duration a quiescent network process persists before
being deleted. The default period is five minutes. The following examples first
show reducing that to thirty seconds, the second increasing it to one hour.
Again, this can improve script response latency by circumventing the need to
create a process to service the request, at least during the period a
previously created process continues to exist.

<div class="blockof code">DEFINE /JOB NETSERVER&dollar;TIMEOUT &quot;0 00:00:30&quot;
DEFINE /JOB NETSERVER&dollar;TIMEOUT &quot;0 01:00:00&quot;
</div>

</ul>

<a id="8.1.4" href="#"></a>
<a id="8.1.4.decnetosustartup" href="#"></a>
<a id="decnetosustartup" href="#"></a>
<h3 class="head"><span class="numb">8.1.4</span><span class="text">DECnet/OSU Startup</span></h3>

<p> The example STARTUP.COM and STARTUP_DECNET.COM procedures found in the
<a class="link blank monosp" target="_blank" href="/wasd_root/example/">WASD_ROOT:[EXAMPLE]</a>
directory provide the essentials for DECnet/OSU scripting.  If the INSTALL.COM
startup environment is used setting the PROVIDE_DECNET symbol to 1 in
STARTUP.COM will create the DECnet scripting environment during server startup.

<a id="8.2" href="#"></a>
<a id="8.2.cgi" href="#"></a>
<a id="cgi" href="#"></a>
<h2 class="head"><span class="numb">8.2</span><span class="text">CGI</span></h2>

<p> CGI scripts that use HTTP GET (the default) may be transparently executed
within the DECnet scripting environment. This means that the script is
executed within a network process, on the target system (which could be the
local system), instead of within a process on the local system. Other than
that the WASD DECnet CGI environment behaves identically to the standard
(sub)process CGI environment. CGIplus scripting is not supported and if
CGIplus-only scripts are executed the behaviour is indeterminate.

<p> Scripts that wish to use HTTP POST will need to read the request body from
the NET&dollar;LINK stream, rather than from HTTP&dollar;INPUT as with (sub)process based
scripts.  End of body is indicated by an empty record rather than EOF.  Scripts
may quite simply be made to function appropriately in both environments.  The
following C code fragment illustrates this.

<div class="blockof code">if (getenv (&quot;NET&dollar;LINK&quot;) == NULL)
{
   /* via process CGI */
   while (ReadCount = fread (Buffer, 1, sizeof(Buffer), stdin))
   {
      /* processing, processing ... */
   }
}
else
{
   /* via DECnet CGI */
   if ((stdin = freopen (&quot;NET&dollar;LINK&quot;, &quot;r&quot;, stdin)) == NULL)
      exit (vaxc&dollar;errno);

   while (fgets (Buffer, sizeof(Buffer), stdin) != NULL)
   {
      /* check for end of stream */
      if (Buffer[0] == '\n' &amp;&amp; Buffer[0] == '\0') break;

      /* processing, processing ... */
   }
}
</div>

<p> An example of making the HELP database on a system other than that hosting
the HTTP server (using the CONAN script) would be done using the mapping rules

<div class="blockof code">map /FRODO/help /FRODO/help/
script /FRODO/help/* /FRODO::/cgi-bin/conan/*
</div>
 and for the example DCL SHOW script

<div class="blockof code">script /FRODO/show* /FRODO::/cgi-bin/show*
</div>

<a id="8.3" href="#"></a>
<a id="8.3.osudecthreadsemulation" href="#"></a>
<a id="osudecthreadsemulation" href="#"></a>
<h2 class="head"><span class="numb">8.3</span><span class="text">OSU (DECthreads) Emulation</span></h2>

<p> The WASD HTTP server provides an emulation of the OSU scripting
environment. This is provided so that OSU-based scripts (both CGI-style and
OSU-specific) may be employed by WASD with no modification. As this emulation
has been designed through examining OSU code and lots of trial and error its
behaviour may be incomplete or present errors.  A list of OSU scripts known to
work with WASD is provided at the end of this section
(<a class="link" href="#8.3.knownworkingscripts">&lsquo;Known Working Scripts&rsquo; in 8.3 OSU (DECthreads) Emulation</a>).

<p> Supported scripts include only those that depend on the OSU WWWEXEC object
and dialog for all functionality. Any script that uses other OSU-specific
functionality is not supported. Interactions between WASD's and OSU's
authentication/authorization schemes may be expected.

<p> OSU scripts expect to get the path information unmapped, whereas WASD
always additionally maps any path after the script component has been derived
from the request URI.  It may be necessary to ensure OSU scripts are activated
with the associated path SET to provide what they expect.  For example:

<div class="blockof code">set /htbin/* mapONCE
set /osu/* mapONCE
</div>

<p> The author would like to know of any OSU scripts the WASD emulation
<span class="high italic">barfs</span> on, and will attempt to address the associated limitation(s)
and/or problem(s).

<a id="8.3.0.0.1" href="#"></a>
<a id="8.3.osusetup" href="#"></a>
<a id="osusetup" href="#"></a>
<h5 class="head"><span class="text">OSU Setup</span></h5>

<p> Software necessary for supporting the OSU scripting environment (e.g.
WWWEXEC.COM) and selected OSU scripts (mainly for testing purposes) have been
extracted from the OSU v3.4 package and included in the
<a class="link blank" target="_blank" href="/wasd_root/src/osu/">WASD_ROOT:[SRC.OSU]</a>
directory.  This has been done within the express OSU licensing conditions.

<div class="blockof code">Copyright 1994,1997 The Ohio State University.  
The Ohio State University will not assert copyright with respect
to reproduction, distribution, performance and/or modification 
of this program by any person or entity that ensures that all 
copies made, controlled or distributed by or for him or it bear 
appropriate acknowlegement of the developers of this program.
</div>

<p> An example DECnet and OSU scripting startup may be found in
<a class="link blank" target="_blank" href="/wasd_root/example/">WASD_ROOT:[EXAMPLE]</a>.
This should be called from or used within the HTTP server startup. It includes
two logical definitions required for common OSU scripts. Other tailoring may
be required for specific OSU scripts.

<a id="8.3.0.0.2" href="#"></a>
<a id="8.3.osugeneralcomments" href="#"></a>
<a id="osugeneralcomments" href="#"></a>
<h5 class="head"><span class="text">OSU - General Comments</span></h5>

<p> David Jones, the author of the DECthreads (OSU) HTTP server, outlines his
reasons for basing OSUs scripting on DECnet (reproduced from a USENET NEWS
reply to a comment this author made about DECnet-based scripting).

<div class="blockof code">------------------------------------------------------------------------

From           JONESD@er6.eng.ohio-state.edu (David Jones)
Organization   The Ohio State University
Date           12 Aug 1997 09:04:11 GMT
Newsgroups     vmsnet.sysmgt,comp.os.vms,comp.infosystems.www.servers.misc
Message-ID     &lt;5sp8ub&dollar;brs&dollar;1@charm.magnus.acs.ohio-state.edu&gt;

------------------------------------------------------------------------

<span class="high italic">&hellip; some text omitted</span>

Since I was comfortable with DECnet, I based the scripting system
for the OSU server around it.    The key reasons to use netserver
processes rather than spawning sub-processes:

    1. DECnet automatically caches and re-uses netserver processes,
       whereas there were well-known performance problems with spawning
       sub-processes.

    2. DECnet processes are detached processes, so you don't worry about
       the effect of scripts consuming pooled quotas (e.g. bytlm) on
       the HTTP server process.

    3. Creation/connection with the DECnet server process is asynchronous
       with respect to the server so other operations can proceed concurrently.
       Spawning is done in supervisor mode, blocking the server's operation
       until the child process is completely initialized.

    4. With DECnet, scripts can be configured to run on different nodes
       for load balancing.

    5. In addition to the standard 'WWWEXEC' object, you can create
       other 'persistent' DECnet objects that the server communicates with
       as scripts. (this was implemented years before OpenMarket's FastCGI
       proposal).

    6. CGI is not the be-all end-all of scripting.  The dialog phase of
       OSU's scripting environment allows scripts to do things CGI
       is incapable of, such as ask the server to translate an arbitrary
       path and not just what followed the script name in the URL.

People grouse all the time about the installation difficulties caused by
it's reliance on DECnet, the reason shown above were cited to show that it
wasn't made so capricously.

<span class="high italic">&hellip; some text omitted</span>

David L. Jones               &verbar;      Phone:    (614) 292-6929
Ohio State Unviversity       &verbar;      Internet:
2070 Neil Ave. Rm. 122       &verbar;               jonesd@kcgl1.eng.ohio-state.edu
Columbus, OH 43210           &verbar;               vman+@osu.edu

Disclaimer: Dogs can't tell it's not bacon.
</div>

<p> The OSU server's DECnet scripting is not based on arbitrary considerations.
This author does not disagree with any of the concerns, and as may be seen from
WASD documentation the design of WASD also directly addresses points 1, 3 and 5
with the use of persistant processes and CGIplus. Certainly DECnet-based
scripting addresses the very legitimate point 4 (and also allows nodes with
specific resources to participate without installing full HTTP server
environments). Point 2 is not an issue with the use of detached scripting
processes, or for all practical purposes addressed by adjusting account quotas
to support the required number of subprocesses. Point 6 is only too true
(possibly at least until Java servers and <span class="high italic">servlets</span> become ubiquitous  <span class="high monosp">:^)</span>

<a id="8.3.0.0.3" href="#"></a>
<a id="8.3.knownworkingscripts" href="#"></a>
<a id="knownworkingscripts" href="#"></a>
<h5 class="head"><span class="text">Known Working Scripts</span></h5>

<p> The following is a list of OSU-specific scripts that the WASD
implementation has either been developed or tested against, and any
installation notes or other WASD specifics. The author would like to know of
any OSU scripts the WASD emulation has problems or works successfully with.

<ul class="list">

<li class="item"> All of the scripts, etc. provided in the
<a class="link blank" target="_blank" href="/wasd_root/src/osu/*.*">WASD_ROOT:[SRC.OSU]</a> directory.

<ul class="list simple list0">
<li class="item"> cgi_symbols
<li class="item"> cgi-mailto
<li class="item"> html_preproc
<li class="item"> set_dcl_env
<li class="item"> testcgi
<li class="item"> testform
<li class="item"> tmail
<li class="item"> vmshelpgate
<li class="item"> webbook
</ul>

<li class="item"> <span class="high bold">helpgate</span>

<p> Comment out the <span class="high italic">Conan The Librarian</span> mappings for the
&quot;/help&quot; path and provide the following in WASD_CONFIG_MAP:

<div class="blockof code"># first make &quot;/help&quot; into a script specification
map /help* /htbin/helpgate/help*
# general rule mapping &quot;/htbin&quot; to OSU DECnet scripts
exec /htbin/* /0::&quot;0=wwwexec&quot;/cgi-bin/*
# map the non-script part of the path back to just &quot;/help&quot;
pass /htbin/helpgate/help* /help*
</div>
 It is possible to support both HELP environments (although
<span class="high italic">helpgate</span> will not work without owning the &quot;/help&quot; path),
merely provide another mapping for <span class="high italic">Conan</span> with a slightly different
path, for example:

<div class="blockof code">map /chelp /chelp/
script /chelp/* /cgi-bin/conan/*
</div>

<li class="item"> <span class="high bold">HTML pre-processor</span>

<p> Yes, backward compatibility can be provided for those old OSU .HTMLX
files in your new WASD environment ;^) All that is needed is a file type
mapping to the script in the WASD_CONFIG_GLOBAL configuration file.

<div class="blockof code">[AddType]
.HTMLX  text/html  /htbin/html_preproc  OSU SSI HTML
</div>

</ul>

<a id="8.4" href="#"></a>
<a id="8.4.userscripts" href="#"></a>
<a id="userscripts" href="#"></a>
<h2 class="head"><span class="numb">8.4</span><span class="text">User Scripts</span></h2>

<p> The WASD DECnet environment provides a simple mechanism for executing
scripts within accounts other than the server's.  This allows configured users
to write and maintain scripts within their own areas and have them execute as
themselves.  Both standard CGI and OSU scripting may be provided for with this
facility.

<p> Of course there is always a down-side.  Be careful to whom this capability
is granted.  User scripts are executed within a user network-mode process
created by DECnet. Script actions cannot generally affect server behaviour, but
they can access any WORLD-readable and modify any WORLD-writable resource in
the system/cluster, opening a window for information leakage or
mischievous/malicious actions. Script authors should be aware of any potential
side-effects of their scripts and Web administrators vigilant against possible
destructive behaviours of scripts they do not author.

<p> User scripting is not enabled by default.  To provide this facility mapping
rules into the user area must be provided in much the same way as for user
directories, see
(<a class="link blank" target="_blank" href="../config/#mappinguserdirectories">Mapping User Directories</a> in <a class="link blank" target="_blank" href="../config/#0.">WASD Configuration</a>).  

<p> The &quot;EXEC&quot; rule provides a wildcard representation of users' script paths.
As part of this mapping a subdirectory specifically for the web scripts should
always be included. <span class="high bold">Never</span> map users' top-level directories. For instance if
a user's account home directory was located in the area WWW_USER:[DANIEL] the
following rule would potentially allow the user DANIEL to provide scripts from
the home subdirectory [.WWW.CGI-BIN] using the accompanying rules (first for
CGI, second for OSU scripts):

<div class="blockof code">exec /~*/cgi-bin/* /0&quot;~&quot;::/www_user/*/www/cgi-bin/*
exec /~*/htbin/* /0&quot;~&quot;::&quot;0=wwwexec&quot;/www_user/*/www/htbin/*
</div>

<p> Scripts located in these directories are accessible via paths such as the
following:

<div class="blockof code">/~daniel/cgi-bin/cgi_symbols
/~daniel/htbin/osu_testcgi
</div>

<a id="8.4.0.0.1" href="#"></a>
<a id="8.4.proxyaccess" href="#"></a>
<a id="proxyaccess" href="#"></a>
<h5 class="head"><span class="text">Proxy Access</span></h5>

<p> For each user account permitted to execute local scripts proxy access to
that account must be granted to the HTTP server account.

<div class="note">
<a id="8.4.0.0.2" href="#"></a>
<a id="8.4.caution" href="#"></a>
<a id="caution" href="#"></a>
<h5 class="head center"><span class="text">Caution!</span></h5>
<hr class="note_hr">
If unsure of the security implications of this action consult the relevant
VMS system management security documentation.
<hr class="note_hr">
</div>

<div class="blockof code">&dollar; SET DEFAULT SYS&dollar;SYSTEM
&dollar; MCR AUTHORIZE
UAF&gt; ADD /PROXY &lt;node&gt;::HTTP&dollar;NOBODY &lt;account&gt;
</div>

<p> For example, the following would allow the HTTP server to execute scripts
on behalf of the username DANIEL.

<div class="blockof code">UAF&gt; ADD /PROXY 0::HTTP&dollar;NOBODY DANIEL
</div>
<!-- source:0900_OTHER.WASDOC -->
<hr class="page">
<a id="9." href="#"></a>
<a id="9.otherenvironments" href="#"></a>
<a id="otherenvironments" href="#"></a>
<h1 class="head"><span class="numb">9.</span><span class="text">Other Environments</span></h1>

<div class="TOC2cols2">
<table class="TOC2table">
<tr><td><a href="#9.1.java"><span class="numb">9.1</span><span class="text">Java</span></a>
<tr><td><a href="#9.1.1.cgiplusonly"><span class="numb">9.1.1</span><span class="text">CGIplus Only</span></a>
<tr><td><a href="#9.1.2.requirements"><span class="numb">9.1.2</span><span class="text">Requirements</span></a>
<tr><td><a href="#9.1.3.carriagecontrol"><span class="numb">9.1.3</span><span class="text">Carriage Control</span></a>
<tr><td><a href="#9.2.perl"><span class="numb">9.2</span><span class="text">Perl</span></a>
<tr><td><a href="#9.2.1.activatingperl"><span class="numb">9.2.1</span><span class="text">Activating Perl</span></a>
<tr><td><a href="#9.2.2.cgienvironment"><span class="numb">9.2.2</span><span class="text">CGI Environment</span></a>
<tr><td><a href="#9.2.3.postedrequests"><span class="numb">9.2.3</span><span class="text">POSTed Requests</span></a>
<tr><td><a href="#9.2.4.reducinglatency"><span class="numb">9.2.4</span><span class="text">Reducing Latency</span></a>
<tr><td><a href="#9.2.4.1.cgiplus"><span class="numb">9.2.4.1</span><span class="text">CGIplus</span></a>
<tr><td><a href="#9.2.4.2.runtimeenvironment"><span class="numb">9.2.4.2</span><span class="text">Run-Time Environment</span></a>
<tr><td><a href="#9.2.5.requirements"><span class="numb">9.2.5</span><span class="text">Requirements</span></a>
</table>
</div>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#8.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#10.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> WASD supports a number of scripting engines.

<ul class="list simple list0">
<li class="item"> Java
<li class="item"> Perl
<li class="item"> PHP
<li class="item"> Python
</ul>

<p> Earlier releases of the WASD package included some of these in the basic
package.  Due to the growing number, greater complexity of the environments,
and increasing version dependencies, these environments will be distributed
independently of the main WASD package.  Current releases may be found at the
main WASD download site

<p class="indent"> <a class="link blank monosp" target="_blank" href="https://wasd.vsm.com.au/wasd/">https://wasd.vsm.com.au/wasd/</a>

<p> Pages generated by scripting environments can optionally be cached by the
server.  For a certain class of script output this can offer reduced response
latency and system impact.  See <a class="link" href="#1.4.cachingscriptoutput">1.4 Caching Script Output</a>.

<a id="9.1" href="#"></a>
<a id="9.1.java" href="#"></a>
<a id="java" href="#"></a>
<h2 class="head"><span class="numb">9.1</span><span class="text">Java</span></h2>

<p> Java classes may be used to perform CGI/CGIplus scripting with WASD.  This
<span class="high bold">is not</span> Java Server Pages, Tomcat, or anything of the like.  The Java refered
to here is a small, self-contained Java environment that may used with WASD
&quot;out-of-the-box&quot;.  All you need is java installed on your VMS system.  These
may be designed as standard CGI scripts (with the inevitable latency of the
class loading) or as CGIplus scripts (with the attendant benefit of lower
latency).

<p> WASD provides a class to allow a relatively simple interface to the CGI
environment for both GET and POST method scripts. This and a collection of
demonstration scripts may be found in the
<a class="link blank monosp" target="_blank" href="/wasd_root/src/java/">WASD_ROOT:[SRC.JAVA]</a> directory.

<p> As the Java environment is constantly under development, both as a
platform-independent environment and on the VMS platform in particular, it is
possible that the latest VMS Java kit may not integrate well with the WASD Java
environment.  Of course every effort will be made to keep the WASD Java
environment current.

<a id="9.1.1" href="#"></a>
<a id="9.1.1.cgiplusonly" href="#"></a>
<a id="cgiplusonly" href="#"></a>
<h3 class="head"><span class="numb">9.1.1</span><span class="text">CGIplus Only</span></h3>

<p> Java CGI/CGIplus scripts must always be mapped and executed using the
CGIplus path, however some can behave as standard CGI scripts, exiting after
responding to the request, while others can persist, responding to multiple
requests (<a class="link" href="#3.cgiplus">3. CGIplus</a>). The CGIplus path is always necessary as Java does
not have direct access to a process' general environment, the traditional way
of passing CGI variables, so the WASD implementation uses the CGIplus data
stream to provide CGI information. 

<a id="9.1.2" href="#"></a>
<a id="9.1.2.requirements" href="#"></a>
<a id="requirements" href="#"></a>
<h3 class="head"><span class="numb">9.1.2</span><span class="text">Requirements</span></h3>

<p> Ensure the Java class file type is mapped to the Java run-time in the
WASD_CONFIG_GLOBAL configuration file.

<div class="blockof code">[DclScriptRunTime]
.CLASS  @CGI-BIN:[000000]JAVA.COM
</div>

<p> The following content types are configured, also in WASD_CONFIG_GLOBAL. 

<div class="blockof code">[AddType]
.CLASS  application/octet-stream  -  Java class
.JAVA  text/plain  -  Java source
.JAR  application/octet-stream  -  Java archive
.PROPERTIES  text/plain  -  Java properties
</div>

<p> Class files should be copied to the [CGI-BIN] directory (where all
architecture neutral script files should be located).

<a id="9.1.3" href="#"></a>
<a id="9.1.3.carriagecontrol" href="#"></a>
<a id="carriagecontrol" href="#"></a>
<h3 class="head"><span class="numb">9.1.3</span><span class="text">Carriage Control</span></h3>

<p> Getting carriage-control to make sense is often a challenge.
System.out.print() only expresses carriage-control embedded in the string.
System.out.println() the same but then issues an independent linefeed (the
newline of the <span class="high italic">ln</span>) which appears to WASD as an empty record. Choose your
poison (and antidote).  Using the &quot;Script-Control: X-stream-mode&quot;,
&quot;Script-Control: X-record-mode&quot; or &quot;Script-Control: X-record0-mode&quot; can assist
WASD interpreting the output.  See <a class="link" href="#2.cgi">2. CGI</a>.

<a id="9.2" href="#"></a>
<a id="9.2.perl" href="#"></a>
<a id="perl" href="#"></a>
<h2 class="head"><span class="numb">9.2</span><span class="text">Perl</span></h2>

<p> WASD supports Perl scripting in the CGI, CGIplus and RTE environments. 
Generally no source changes are required to use standard CGI Perl scripts!
Information in this section pertains specifically to VMS Perl 5.6 and
following.  Earlier versions may have some limitations. VMS Perl 5.6 is a
relatively complete Perl implementation and standard distributions contain
some VMS-specific functionality.  In particular the VMS::DCLsym and VMS::Stdio
can make life simpler for the VMS perl developer.

<p> Users of VMS Perl are directed to &quot;Perl on VMS&quot; at
<a class="link blank monosp" target="_blank" href="http://www.sidhe.org/vmsperl/">http://www.sidhe.org/vmsperl/</a>
providing access to the latest release of Perl for VMS.

<div class="note">
<a id="9.2.0.0.1" href="#"></a>
<a id="9.2.pleasenote" href="#"></a>
<a id="pleasenote" href="#"></a>
<h5 class="head center"><span class="text">Please Note</span></h5>
<hr class="note_hr">
The author is very much the Perl novice and this chapter  probably reflects
that.  Additional material and improved code always gratefully received.
<hr class="note_hr">
</div>

<a id="9.2.1" href="#"></a>
<a id="9.2.1.activatingperl" href="#"></a>
<a id="activatingperl" href="#"></a>
<h3 class="head"><span class="numb">9.2.1</span><span class="text">Activating Perl</span></h3>

<p> There are a number of ways to activate a Perl script under VMS.  Any of
these may be used with the WASD server.  If the script file is accessible via
the <span class="high italic">exec</span> or <span class="high italic">script</span> rules of the WASD_CONFIG_MAP configuration
file it can be activated by the server.  The simplest example is to place the
scripts somewhere in the CGI-BIN:[000000] path and execute via /cgi-bin/,
although in common with other scripts it may be located anywhere a rule
provides a path to access it (<a class="link" href="#1.6.scriptmapping">1.6 Script Mapping</a>).

<a id="9.2.1.0.1" href="#"></a>
<a id="9.2.1.directly" href="#"></a>
<a id="directly" href="#"></a>
<h5 class="head"><span class="text">Directly</span></h5>

<p> When Perl is available from the command-line, either as a DCLTABLES defined
verb, a DCL&dollar;PATH available verb, or as a <span class="high italic">foreign</span> verb.  The script (the file
containg the Perl source) is provided to the Perl interpreter as a parameter to
the Perl verb.

<div class="blockof code">&dollar; PERL <span class="high italic">perl-script-file-name</span>
</div>

<a id="9.2.1.0.2" href="#"></a>
<a id="9.2.1.dclprocedurewrapped" href="#"></a>
<a id="dclprocedurewrapped" href="#"></a>
<h5 class="head"><span class="text">DCL Procedure Wrapped</span></h5>

<p> If DCL pre-processing, or some other specific environment needs to be set
up, the activation of the Perl script can be placed inside a DCL <span class="high italic">wrapper</span>
procedure.  This is often used to allow the transparent activation of Perl
scripts via the DCL&dollar;PATH mechanism.

<div class="blockof code">&dollar; PERL = &quot;&dollar;PERL_ROOT:[000000]PERL.EXE&quot;
&dollar; DEFINE /USER PERL_ENV_TABLES CLISYM_GLOBAL,LNM&dollar;PROCESS
&dollar; PERL <span class="high italic">perl-script-file-name</span>
</div>

<a id="9.2.1.0.3" href="#"></a>
<a id="9.2.1.dclprocedureembedded" href="#"></a>
<a id="dclprocedureembedded" href="#"></a>
<h5 class="head"><span class="text">DCL Procedure Embedded</span></h5>

<p> The Perl source is embedded as in-line data within a DCL procedure.

<div class="blockof code">&dollar; DEFINE /USER PERL_ENV_TABLES CLISYM_GLOBAL,LNM&dollar;PROCESS
&dollar; PERL
&dollar; DECK /DOLLARS=&quot;__END__&quot;
# start of Perl script
print &quot;Hello \&quot;&dollar;ENV{'WWW_REMOTE_HOST'}\&quot;\n&quot;;
__END__
</div>

<a id="9.2.2" href="#"></a>
<a id="9.2.2.cgienvironment" href="#"></a>
<a id="cgienvironment" href="#"></a>
<h3 class="head"><span class="numb">9.2.2</span><span class="text">CGI Environment</span></h3>

<p> Due to changes in environment handling sometime between versions 5.0 and
5.6 it was impossible to access DCL symbols via the %ENV hash, making CGI-based
scripts impossible to use under VMS Web servers without modification.  Version
5.6 addresses this issue by providing a versatile mechanism for controlling
where the environment variables are manipulated.  The logical name
PERL_ENV_TABLES specifies this location, or if defined as a search list, the
locations.

<table class="tabl">
<tr class="tabr under">
<th class="tabh">Name
<th class="tabh">Location
<tr class="tabr">
<tr class="tabr">
<td class="tabd">CRTL_ENV
<td class="tabd">C run-time environment array (i.e. getenv())
<tr class="tabr">
<td class="tabd">CLISYM_LOCAL
<td class="tabd">get DCL symbols, set local
<tr class="tabr">
<td class="tabd">CLISYM_GLOBAL
<td class="tabd">get DCL symbols, set global
<tr class="tabr">
<td class="tabd"><span class="high italic">logical name table</span>
<td class="tabd">any logical name table, including LNM&dollar;FILE_DEV
</table>

<p> For WASD Perl scripting it is recommended that this be defined as
CLISYM_GLOBAL,LNM&dollar;PROCESS.  The CLISYM_GLOBAL allows access to the CGI variable
environment, and LNM&dollar;PROCESS to significant logical name definitions for the
subprocess (e.g. HTTP&dollar;INPUT and callout sequences).  This can be done on a
system-wide basis (i.e. for all Perl scripting) using

<div class="blockof code">&dollar; DEFINE /SYSTEM PERL_ENV_TABLES CLISYM_GLOBAL,LNM&dollar;PROCESS
</div>

during system startup, or by defining a user-mode logical in a DCL procedure
<span class="high italic">wrapper</span> immediately before activating the Perl interpreter (as show in the
examples in this section).

<div class="note">
<a id="9.2.2.0.1" href="#"></a>
<a id="9.2.2.neversubstitute" href="#"></a>
<a id="neversubstitute" href="#"></a>
<h5 class="head center"><span class="text">NEVER substitute...</span></h5>
<hr class="note_hr"> ...the content of CGI variables directly into the code
stream using interpreters that will allows this (e.g. DCL, Perl).  You run a
very real risk of having unintended content maliciously change the intended
function of the code. Always pre-process the content of the variable first,
ensuring there has been nothing inserted that could subvert the intended
purpose. There are a number of security-related Perl scripting issues.  It is
suggested the reader consult one of the many Perl-CGI documents/books
available.
<hr class="note_hr">
</div>

<a id="9.2.3" href="#"></a>
<a id="9.2.3.postedrequests" href="#"></a>
<a id="postedrequests" href="#"></a>
<h3 class="head"><span class="numb">9.2.3</span><span class="text">POSTed Requests</span></h3>

<p> Requests using the POST method contain all the content in the body of the
request.  In particular, requests generated via HTML &lt;form&gt; contructs do not
deliver the form data via the request query string, it is provided in a
URL-form-encoded body.  This requires some explicit processing to recover the
form elements.  A number of Perl CGI modules exist to ease this chore,
including the most popular CGI.pm.  All of these should work in the VMS
environment, and of course then with WASD.

<p> For POSTed requests it is necessary for the script to have access to the
request body.  In Unix environments this is available via the &lt;stdin&gt; stream,
and under Perl via STDIN, &lt;&gt;, etc.  This equates to SYS&dollar;INPUT under VMS.

<p> With WASD, when activating the .PL script file directly via a
[DclScriptRunTime] entry (i.e. without a DCL procedure wrapper) STDIN is
directly available without further issues.

<p> If the script has a DCL wrapper procedure the DCL CLI has control of the
SYS&dollar;INPUT stream and it becomes  necessary to temporarily redirect this for the
duration of the script.  WASD provides the HTTP&dollar;INPUT process-level logical
name to identify the script body stream (along with WWW_IN and APACHE&dollar;INPUT
names for easing script portability).  The redirection is simply done, as shown
in the following example.

<div class="blockof code">&dollar; DEFINE /USER PERL_ENV_TABLES CLISYM_GLOBAL,LNM&dollar;PROCESS
&dollar; DEFINE /USER SYS&dollar;INPUT HTTP&dollar;INPUT
&dollar; PERL <span class="high italic">perl-script-file-name</span>
</div>

<p> If the script is embedded in a DCL procedure the DCL CLI is using SYS&dollar;INPUT
to provide the script source to the Perl interpreter and so is completely
unavailable for use.  The request body is still available to the script however
but must be explicitly read from HTTP&dollar;INPUT.  This example provides the basics.

<div class="blockof code">&dollar; DEFINE /USER PERL_ENV_TABLES CLISYM_GLOBAL,LNM&dollar;PROCESS
&dollar; PERL
&dollar; DECK /DOLLARS=&quot;__END__&quot;
# start of Perl script
print &quot;HTTP method is \&quot;&dollar;ENV{'WWW_REQUEST_METHOD'}\&quot;\n&quot;;
# read POSTed body stream
open (HTTPIN, &dollar;ENV{&quot;HTTP\&dollar;INPUT&quot;})
   or die &quot;Could not open &dollar;ENV{'HTTP\&dollar;INPUT'}\n&quot;;
while (&lt;HTTPIN&gt;)
{
  chop;  # remove trailing newline
  print &quot;&lt;HTTPIN&gt; &verbar;&dollar;_&verbar;\n&quot;;
}
__END__
</div>

<a id="9.2.4" href="#"></a>
<a id="9.2.4.reducinglatency" href="#"></a>
<a id="reducinglatency" href="#"></a>
<h3 class="head"><span class="numb">9.2.4</span><span class="text">Reducing Latency</span></h3>

<p> Perl is an interpreter, meaning scripts are provided and activated as source
form, the interpreter processing the program &quot;on-the-fly&quot;. Perl actually
translates the entire script into an intermediate form before beginning
execution.  This has the advantage of discovering and reporting syntax errors
before beginning any actual processing, and also improves the final run-time
performance.

<p> While having Perl an interpreter eases development and portability it does
incur a performance penalty, particularly in activation latency, due to both
interpreter image activation, and script  and associated Perl module
preprocessing.  With standard CGI, where each request processed is handled as
an autonomous activation, this becomes quite noticable and can have significant
system impact.

<p> WASD provides two solutions for this and other persistent scripting issues. 
Both of these require the supplementary Perl package available from the WASD
download page.  Both are briefly described below.

<a id="9.2.4.1" href="#"></a>
<a id="9.2.4.1.cgiplus" href="#"></a>
<a id="cgiplus" href="#"></a>
<h4 class="head"><span class="numb">9.2.4.1</span><span class="text">CGIplus</span></h4>

<p> CGIplus substantially eliminates the overhead associated with CGI processing
by allowing the subprocess and any associated image/application to continue
executing between uses (<a class="link" href="#3.cgiplus">3. CGIplus</a>).  The good news is, CGIplus is
relatively simple to support, even using Perl.  The great news is, <span class="high bold">CGIplus
can reduce latency and improve performance by some twenty-fold!!</span>

<p> With CGIplus the Perl script remains active for the life of the subprocess. 
That is it persists!  Read the general philosphy and implementation details in
the above reference.  Note that it is still substantially CGI!  The notable
differences are two.  CGI variables are obtained by reading a stream, not using
the %ENV hash.  The end-of-script is indicated by writing a special byte
sequence (detected and used by the server).  Of course the request body is
still available via the usual stream.

<p> Using the basic principles described in the CGIplus Chapter a Perl CGIplus
script would be relatively simple to build from scratch.  To assist in
deploying CGIplus Perl scripting a CGIplus.pm Perl module has been provided as
part of the supplementary package. 

<a id="9.2.4.2" href="#"></a>
<a id="9.2.4.2.runtimeenvironment" href="#"></a>
<a id="runtimeenvironment" href="#"></a>
<h4 class="head"><span class="numb">9.2.4.2</span><span class="text">Run-Time Environment</span></h4>

<p> A Run-Time Environment (RTE) is almost identical to CGIplus.  It allows an
environment to persist between requests, substantially improving response
latency and reducing system impact (<a class="link" href="#4.runtimeenvironments">4. Run-Time Environments</a>). There is a
significant difference between  RTE and CGIplus scripts.  With CGIplus the
script itself persists between uses, retaining all of its state.  With an RTE
the script does not persist or retain state, only the RTE itself.

<p> The WASD RTE Perl interpreter contains an embedded Perl engine and an
associated Perl module that allows multiple scripts to be activated,
preprocessed once and remain loaded <span class="high italic">read-to-run</span>.  This eliminates the
overhead associated with activating the interpreter and Perl script with each
request.  This mechanism parallels the Apache <span class="high italic">perl_mod</span> module and works on
substantially unmodified CGI scripts.  <span class="high bold">The test-bench indicates an
improvement of some twenty-five fold!</span>

<a id="9.2.5" href="#"></a>
<a id="9.2.5.requirements" href="#"></a>
<a id="requirements" href="#"></a>
<h3 class="head"><span class="numb">9.2.5</span><span class="text">Requirements</span></h3>

<p> These are the configuration requirements for using the basic CGI Perl.

<ul class="list">

<li class="item"> WASD_CONFIG_GLOBAL configuration file.

<div class="blockof code">[DclScriptRunTime]
.PL PERL
.CGI PERL
</div>

<li class="item"> The following content types are configured, also in WASD_CONFIG_GLOBAL. 

<div class="blockof code">[AddType]
.PL  text/plain  -  Perl source
.POD  text/plain  -  Perl documentation
.CGI  text/plain  -  Perl source
</div>

</ul>
<!-- source:1000_REDACT.WASDOC -->
<hr class="page">
<a id="10." href="#"></a>
<a id="10.requestredaction" href="#"></a>
<a id="requestredaction" href="#"></a>
<h1 class="head"><span class="numb">10.</span><span class="text">Request Redaction</span></h1>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#9.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#11.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<p> Callout processing may redact (completely rewrite and restart) a request.

<div class="blockof code">re-dact

  -verb (used with object)

  1.  to put into suitable literary form; revise; edit.
  2.  to draw up or frame (a statement, proclamation, etc.).

  [Origin: 13501400; ME &lt; L redactus (ptp. of redigere to lead back), equiv.
  to red- red- + ctus, ptp. of agere to lead; see act] 
</div>

<a id="10.0.0.0.1" href="#"></a>
<a id="10.redactcallout" href="#"></a>
<a id="redactcallout" href="#"></a>
<h5 class="head"><span class="text">REDACT: Callout</span></h5>

<p> To do this a script must use the REDACT:&lt;opaque&gt; callout to send
back to  the server a completely new request header and body (if applicable)
which the server then treats as if received from the client over the network. 
This allows a request to be partially or completely rewritten (as required) and
restarted.  The data supplied to this callout is treated as completely opaque
and care must be taken to include all and no extra carriage-control, etc.

<p> Request redaction may only be initiated (using the REDACT: callout) if the
CGI response header has not been sent.  Once request redaction has been
initiated no CGI output subsequently can be generated.  The server will
generate an error if such a protocol error occurs.

<a id="10.0.0.0.2" href="#"></a>
<a id="10.redactsizecallout" href="#"></a>
<a id="redactsizecallout" href="#"></a>
<h5 class="head"><span class="text">REDACT-SIZE: Callout</span></h5>

<p> The REDACT-SIZE:&lt;integer&gt; callout may be used prior to any
REDACT: callout.  By default the server allocates memory on demand to
accomodate the redacted request.  If the redacted request is large (more than
[BufferSizeDclOutput]) and the total size of the redacted request known in
advance there is some efficiency in requesting the server to preallocate this
amount of space using the REDACT-SIZE: callout.

<a id="10.0.0.0.3" href="#"></a>
<a id="10.codeexample" href="#"></a>
<a id="codeexample" href="#"></a>
<h5 class="head"><span class="text">Code Example</span></h5>

<p> An elementary (and somewhat contrived) example:

<div class="blockof code">stdout = freopen (&quot;SYS&dollar;OUTPUT:&quot;, &quot;w&quot;, stdout, &quot;ctx=bin&quot;, &quot;ctx=xplct&quot;);
fputs (getenv(&quot;CGIPLUSESC&quot;),stdout);
fflush (stdout);

fputs (&quot;REDACT:HTTP/1.1 POST /an_example.php\r\n\
Host: example.com\r\n\
Content-Length: 26\r\n\
Content-Type: application/x-www-form-urlencoded\r\n\
\r\n&quot;,
       stdout);
fflush (stdout);

fwrite (&quot;REDACT:one=two&amp;three=four\n&quot;, 26, 1, stdout);
fflush (stdout);

fputs (getenv(&quot;CGIPLUSEOT&quot;),stdout);
fflush (stdout);
</div>

<p> Once the request has been redacted the script just finishes processing
without other output and the server transparently restarts processing.

<p> An actual usage example may be found in the WASD PAPI authentication agent
(not a component of the standard WASD package).

<a id="10.0.0.0.4" href="#"></a>
<a id="10.redactrationale" href="#"></a>
<a id="redactrationale" href="#"></a>
<h5 class="head"><span class="text">Redact Rationale</span></h5>

<p> This facility was originally incorporated to allow a PAPI

<table class="tabl">
<tr class="tabr">
<td class="tabd"><a class="link blank monosp" target="_blank" href="http://papi.rediris.es/">http://papi.rediris.es/</a>
</table>

<p> authentication agent to store a request on-disk and then some time and
several processing steps later restart the original request processing.
<!-- source:1100_RAWTCPIP.WASDOC -->
<hr class="page">
<a id="11." href="#"></a>
<a id="11.rawtcpipsocket" href="#"></a>
<a id="rawtcpipsocket" href="#"></a>
<h1 class="head"><span class="numb">11.</span><span class="text">Raw TCP/IP Socket</span></h1>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#10.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#12.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<div class="note">
<a id="11.0.0.0.1" href="#"></a>
<a id="11.deprecatedanddiscouraged" href="#"></a>
<a id="deprecatedanddiscouraged" href="#"></a>
<h5 class="head center"><span class="text">Deprecated and Discouraged</span></h5>
<hr class="note_hr">
Unencrypted TCP/IP communication, especially for browser and other web
connections, increasingly is considered poor practise, even for trivial
purposes.  Access to the raw socket will likely be disabled in the future.  If
this facility is in use for script-&gt;client data transfer reasons the
consider using a shared-memory buffer as described in
<a class="link" href="#2.2.3.bulkcontentoutput">2.2.3 Bulk Content Output</a>.
<hr class="note_hr">
</div>

<p> For detached and subprocess scripting the raw TCP/IP socket can be made
available for  scripts to transfer data directly to the client.  The socket
BG<span class="high italic">nnnn</span>: device name is made available via the CGI variable
WWW_GATEWAY_BG.  This is enabled using the [DclGatewayBg] configuration
directive.  As it is a completely raw stream it cannot be used, and is not made
available for SSL (&quot;https:&quot;) encrypted requests. 

<p> Although one might imagine this direct transfer to be significantly more
efficient than the standard script mailbox the test-bench indicates that to all
purposes it provides a negligable improvement in throughput, even under high
load.  It probably only translates into measurable benefits for scripts
producing large quantities of output (for instance hundreds of thousands or
millions of bytes).  For the average script the overhead of opening a stream to
the raw TCP/IP device (which is not insignificant) and complications of the
callout requirements isn't worth the effort.  Still, it's there if someone
wants or requires it.

<p> The socket is created shareable between processes, and so a
channel may be assigned by the script subprocess and have data written to it. 
The data is raw, in the sense the script must provide all carriage control,
etc.  All data transfered this way is outside of the server and so may not be
WATCHed, etc. 

<p> The script must supply a full HTTP response.  This means a NPH-style header
(<a class="link" href="#2.2.2.nonparsedheaderoutput">2.2.2 Non-Parsed-Header Output</a>) and body, with full carriage-control as
required, etc.  The server <span class="high under">must</span> be notified that the script is using the
gateway device, by providing a CGI callout (<a class="link" href="#6.cgicallouts">6. CGI Callouts</a>) before any
script output and after output is concluded.  The first callout provides the
response HTTP status code, the second the number of bytes transfered.  These
are also required for correct logging of the request. If a channel to the BG:
device is opened it should always be closed when it is finished with.  Failure
to do so could lead to resource starvation for the server.

<p> The
<a class="link blank monosp" target="_blank" href="/wasd_root/src/other/gateway_bg_example.com">/wasd_root/src/other/gateway_bg_example.com</a>
example script demonstrates the use of the raw socket from DCL.  The priciples
can be applied to any scripting laguage.

<p> The following code fragment shows the essential requirements using the C
language.

<div class="blockof code">int  byteCount;
char  *gatewayBg;

/* see if there's a raw socket available */
if (gatewayBg = getenv (&quot;WWW_GATEWAY_BG&quot;))
{
   /* yes, begin a callout */
   fputs (getenv(&quot;CGIPLUSESC&quot;), stdout);
   fflush (stdout);

   /* notify of script response and HTTP status */
   fprintf (stdout, &quot;GATEWAY-BEGIN: %d&quot;, 200);
   fflush (stdout);

   /* reopen &lt;stdout&gt; to the raw TCP/IP device */
   if ((stdout = freopen (gatewayBgPtr, &quot;w&quot;, stdout, &quot;ctx=bin&quot;)) == NULL)
      exit (vaxc&dollar;errno);
}

byteCount = fprintf (stdout,
&quot;HTTP/1.0 200 OK\n\
Content-Type: text/plain\n\
\n&quot;);

&hellip; <span class="high italic">processing to &lt;stdout&gt;
   e.g. byteCount += fprintf (stdout, &quot;Hello world!\n&quot;);</span>

if (gatewayBg)
{
   /* reopen &lt;stdout&gt; so that it's communicating via the mailbox again */
   if ((stdout = freopen (&quot;SYS&dollar;OUTPUT:&quot;, &quot;w&quot;, stdout, &quot;ctx=rec&quot;)) == NULL)
      exit (vaxc&dollar;errno);

   /* continue callout, notify of request data transfered */
   fprintf (stdout, &quot;GATEWAY-END: %d&quot;, byteCount);
   fflush (stdout);

   /* end the callout */
   fputs (getenv(&quot;CGIPLUSEOT&quot;), stdout);
   fflush (stdout);
}
</div>

<a id="11.0.0.0.2" href="#"></a>
<a id="11.carriagecontrol" href="#"></a>
<a id="carriagecontrol" href="#"></a>
<h5 class="head"><span class="text">Carriage Control</span></h5>

<p> By default the TCP/IP BG device driver supplies a &lt;CR&gt;&lt;LF&gt; sequence as
carriage control for each record.  This supports record-oriented output such as
DCL and various VMS utilities but is an issue when needing to output a binary
object such as a large graphic. The CGI callout (<a class="link" href="#6.cgicallouts">6. CGI Callouts</a>)
GATEWAY-CCL: directive allows the  device carriage control to be set and reset
programmatically.  A value of 1 enables a &lt;CR&gt;&lt;LF&gt; with each record, while 0
disables it.  This is analagous to the APACHE&dollar;SET_CCL utility.

<a id="11.0.0.0.3" href="#"></a>
<a id="11.notsupported" href="#"></a>
<a id="notsupported" href="#"></a>
<h5 class="head"><span class="text">Not Supported?</span></h5>

<p> Not all vendor's TCP/IP package BG drivers, or not all older versions, may
support the C_SHARE option when creating sockets.  Symptoms may range from it
being ignored (and the script being unable to open a channel to the BG<span class="high italic">nnnn</span>:
device) to an error being reported as the socket is being created (and the
server being unable to start at all).  If this occurs merely disable the
[DclGatewayBg] configuration option.  Script output is of course still
available via the standard script output mailbox.

<p> For portability scripts that use the raw socket for output should always
use a construct similar to the above example code so only to redirect output
when the GATEWAY_BG device is indicated as available.
<!-- source:1200_INDEX.WASDOC -->
<hr class="page">
<a id="12." href="#"></a>
<a id="12.index" href="#"></a>
<a id="index" href="#"></a>
<h1 class="head"><span class="numb">12.</span><span class="text">Index</span></h1>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#11.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a href="#13.">&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<div class="IDXcols2">
<table class="IDXtable">
<tr><td class="alpha">A</td><td class="text"><a href="#0.abstract">&lsquo;Abstract&rsquo; in  WASD Scripting Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.1.activatingperl">9.2.1&nbsp;Activating Perl</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#0.apachelicenseversion20">&lsquo;Apache License, Version 2.0&rsquo; in  WASD Scripting Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.attributionandacknowledgement">13.&nbsp;Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.1.authenticateduserscripting">&lsquo;Authenticated User Scripting&rsquo; in 1.2.3.1 Persona Scripting</a>
<tr><td class="alpha">B</td><td class="text"><a href="#13.bjoumlernhoumlehrmann">&lsquo;Bj&ouml;ern H&ouml;ehrmann&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.3.bulkcontentoutput">2.2.3&nbsp;Bulk Content Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.1.bytlm">&lsquo;BYTLM&rsquo; in 5.1 Multi-Client WebSocket Applications</a>
<tr><td class="alpha">C</td><td class="text"><a href="#2.2.1.crtlfeatures">&lsquo;C-RTL Features&rsquo; in 2.2.1 CGI Compliant Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.4.cachingscriptoutput">1.4&nbsp;Caching Script Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.6.carefulofthirdpartyscriptlocations">&lsquo;Careful of third-party script locations&rsquo; in 1.6 Script Mapping</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#11.carriagecontrol">&lsquo;Carriage Control&rsquo; in 11. Raw TCP/IP Socket</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.1.3.carriagecontrol">9.1.3&nbsp;Carriage Control</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.4.caution">&lsquo;Caution!&rsquo; in 8.4 User Scripts</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.1.1.caution">&lsquo;Caution!&rsquo; in 8.1.1 Proxy Access</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.2.cgi">8.2&nbsp;CGI</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.cgi">2.&nbsp;CGI</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#6.cgicallouts">6.&nbsp;CGI Callouts</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.1.cgicompliantoutput">2.2.1&nbsp;CGI Compliant Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.2.cgienvironment">9.2.2&nbsp;CGI Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.cgienvironmentvariables">2.1&nbsp;CGI Environment Variables</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.cgienvironmentvariables">&lsquo;CGI Environment Variables&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.1.cgifunctionlibrary">&lsquo;CGI Function Library&rsquo; in 3.1 CGIplus Programming</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.4.cgifunctionlibrary">2.4&nbsp;CGI Function Library</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.cgivariabledemonstration">&lsquo;CGI Variable Demonstration&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.cgivariables">&lsquo;CGI Variables&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.cgiplus">3.&nbsp;CGIplus</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.4.1.cgiplus">9.2.4.1&nbsp;CGIplus</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#4.cgiplusexample">&lsquo;CGIplus Example&rsquo; in 4. Run-Time Environments</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.1.1.cgiplusonly">9.1.1&nbsp;CGIplus Only</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.2.cgiplusoutput">&lsquo;CGIplus Output&rsquo; in 3.2 Code Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.cgiplusperformance">&lsquo;CGIplus Performance&rsquo; in 3. CGIplus</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.1.cgiplusprogramming">3.1&nbsp;CGIplus Programming</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.3.cgiplusrulemapping">&lsquo;CGIplus Rule Mapping&rsquo; in 3.3 Other Considerations</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#7.1.cgisapi">7.1&nbsp;CGIsapi</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#7.2.cgisapiconsiderations">&lsquo;CGIsapi Considerations&rsquo; in 7.2 Writing ISAPI Scripts</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.5.cgiutlutility">2.5&nbsp;CGIUTL Utility</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.4.1.chat">5.4.1&nbsp;Chat</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.3.1.chat">5.8.3.1&nbsp;Chat</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.clarkcooperetal">&lsquo;Clark Cooper, et.al.&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.7.clientrecalcitrance">1.2.7&nbsp;Client Recalcitrance</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#10.codeexample">&lsquo;Code Example&rsquo; in 10. Request Redaction</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.2.codeexamples">3.2&nbsp;Code Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#6.2.codeexamples">6.2&nbsp;Code Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.4.controllingscriptcaching">&lsquo;Controlling Script Caching&rsquo; in 1.4 Caching Script Output</a>
<tr><td class="alpha">D</td><td class="text"><a href="#4.2.dclprocedure">&lsquo;DCL procedure&rsquo; in 4.2 Server Configuration</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.1.dclprocedureembedded">&lsquo;DCL Procedure Embedded&rsquo; in 9.2.1 Activating Perl</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.1.dclprocedurewrapped">&lsquo;DCL Procedure Wrapped&rsquo; in 9.2.1 Activating Perl</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.11.dclprocessingofrequests">1.11&nbsp;DCL Processing of Requests</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.decnetamposu">8.&nbsp;DECnet &amp; OSU</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.1.2.decnetobjects">8.1.2&nbsp;DECnet Objects</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.decnetperformance">&lsquo;DECnet Performance&rsquo; in 8. DECnet &amp; OSU</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.1.2.decnetplusosiphasev">&lsquo;DECnet-Plus (OSI/Phase-V)&rsquo; in 8.1.2 DECnet Objects</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.1.4.decnetosustartup">8.1.4&nbsp;DECnet/OSU Startup</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.1.defaultaccounts">&lsquo;Default Accounts&rsquo; in 1.1 Scripting Accounts</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#11.deprecatedanddiscouraged">&lsquo;Deprecated and Discouraged&rsquo; in 11. Raw TCP/IP Socket</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.1.directly">&lsquo;Directly&rsquo; in 9.2.1 Activating Perl</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.4.doesthisbrowsersupportwebsocket">&lsquo;Does this browser support WebSocket?&rsquo; in 5.4 WebSocket Application Examples</a>
<tr><td class="alpha">E</td><td class="text"><a href="#5.4.2.echo">5.4.2&nbsp;Echo</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.3.2.echo">5.8.3.2&nbsp;Echo</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.5.enablingascript">1.5&nbsp;Enabling A Script</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.1.enablingpersonascripting">&lsquo;Enabling Persona Scripting&rsquo; in 1.2.3.1 Persona Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.1.exampledclscripts">&lsquo;Example DCL Scripts&rsquo; in 2.2.1 CGI Compliant Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.4.examples">&lsquo;Examples&rsquo; in 1.4 Caching Script Output</a>
<tr><td class="alpha">F</td><td class="text"><a href="#13.freesoftwarefoundation">&lsquo;Free Software Foundation&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">H</td><td class="text"><a href="#1.2.1.hardlimit">&lsquo;Hard Limit&rsquo; in 1.2.1 Process Management</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.2.hint">&lsquo;Hint!&rsquo; in 3.2 Code Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.3.hint">&lsquo;Hint!&rsquo; in 3.3 Other Considerations</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#7.2.hint">&lsquo;Hint!&rsquo; in 7.2 Writing ISAPI Scripts</a>
<tr><td class="alpha">I</td><td class="text"><a href="#12.index">12.&nbsp;Index</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.introduction">1.&nbsp;Introduction</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.1.ipctickler">&lsquo;IPC Tickler&rsquo; in 2.2.1 CGI Compliant Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#7.isapi">7.&nbsp;ISAPI</a>
<tr><td class="alpha">J</td><td class="text"><a href="#9.1.java">9.1&nbsp;Java</a>
<tr><td class="alpha">K</td><td class="text"><a href="#8.3.knownworkingscripts">&lsquo;Known Working Scripts&rsquo; in 8.3 OSU (DECthreads) Emulation</a>
<tr><td class="alpha">L</td><td class="text"><a href="#0.license">&lsquo;License&rsquo; in  WASD Scripting Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.licensedundertheapachelicenseversion20">&lsquo;Licensed under the Apache License, Version 2.0&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.1.lifetimes">&lsquo;Lifetimes&rsquo; in 1.2.1 Process Management</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.localsystem">&lsquo;Local System&rsquo; in 8. DECnet &amp; OSU</a>
<tr><td class="alpha">M</td><td class="text"><a href="#1.6.mappinglocalorthirdpartyscripts">&lsquo;Mapping Local or Third-Party Scripts&rsquo; in 1.6 Script Mapping</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.5.minimiseavailablescripts">&lsquo;Minimise available scripts&rsquo; in 1.5 Enabling A Script</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.4.3.mouse">5.4.3&nbsp;Mouse</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.1.multiclientwebsocketapplications">5.1&nbsp;Multi-Client WebSocket Applications</a>
<tr><td class="alpha">N</td><td class="text"><a href="#1.11.neversubstitute">&lsquo;NEVER substitute...&rsquo; in 1.11 DCL Processing of Requests</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.2.neversubstitute">&lsquo;NEVER substitute...&rsquo; in 9.2.2 CGI Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.nevereversubstitute">&lsquo;NEVER, EVER substitute...&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.2.nonparsedheaderoutput">2.2.2&nbsp;Non-Parsed-Header Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.noneofthefollowinglicensingappearsincompatiblewiththeapachelicense">&lsquo;None of the following licensing appears incompatible with the Apache License&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#11.notsupported">&lsquo;Not Supported?&rsquo; in 11. Raw TCP/IP Socket</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#4.2.note">&lsquo;Note&rsquo; in 4.2 Server Configuration</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.note">&lsquo;Note&rsquo; in 5.8 WASD &quot;Raw&quot;Socket</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.note">&lsquo;Note&rsquo; in 8. DECnet &amp; OSU</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.2.nphcscript">&lsquo;NPH C Script&rsquo; in 2.2.2 Non-Parsed-Header Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.2.nphdclscript">&lsquo;NPH DCL Script&rsquo; in 2.2.2 Non-Parsed-Header Output</a>
<tr><td class="alpha">O</td><td class="text"><a href="#13.ohiostateuniversity">&lsquo;Ohio State University&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#0.onlinesearch">&lsquo;Online Search&rsquo; in  WASD Scripting Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.opensslproject">&lsquo;OpenSSL Project&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.3.osudecthreadsemulation">8.3&nbsp;OSU (DECthreads) Emulation</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.3.osugeneralcomments">&lsquo;OSU - General Comments&rsquo; in 8.3 OSU (DECthreads) Emulation</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.3.osusetup">&lsquo;OSU Setup&rsquo; in 8.3 OSU (DECthreads) Emulation</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.3.otherconsiderations">3.3&nbsp;Other Considerations</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.otherenvironments">9.&nbsp;Other Environments</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.1.outputandhttp11">&lsquo;Output and HTTP/1.1&rsquo; in 2.2.1 CGI Compliant Output</a>
<tr><td class="alpha">P</td><td class="text"><a href="#13.paulejones">&lsquo;Paul E. Jones&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.perl">9.2&nbsp;Perl</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.1.personascripting">1.2.3.1&nbsp;Persona Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.1.2.phaseiv">&lsquo;Phase-IV&rsquo; in 8.1.2 DECnet Objects</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.pleasenote">&lsquo;Please Note&rsquo; in 9.2 Perl</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.3.postedrequests">9.2.3&nbsp;POSTed Requests</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.3.postscript">&lsquo;Postscript&rsquo; in 2.2.3 Bulk Content Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.1.privilegeduserscripting">&lsquo;Privileged User Scripting&rsquo; in 1.2.3.1 Persona Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.processmanagement">&lsquo;Process Management&rsquo; in 1.2.3 Process Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.1.processmanagement">1.2.1&nbsp;Process Management</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.2.processnomenclature">1.2.2&nbsp;Process Nomenclature</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.3.processpriorities">1.2.3.3&nbsp;Process Priorities</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.processscripting">1.2.3&nbsp;Process Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.3.proctorconfiguration">&lsquo;Proctor Configuration&rsquo; in 1.3 Script Proctor</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.3.proctorexample">&lsquo;Proctor Example&rsquo; in 1.3 Script Proctor</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.1.1.proxyaccess">8.1.1&nbsp;Proxy Access</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.4.proxyaccess">&lsquo;Proxy Access&rsquo; in 8.4 User Scripts</a>
<tr><td class="alpha">Q</td><td class="text"><a href="#2.1.querystringvariables">&lsquo;Query String Variables&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">R</td><td class="text"><a href="#2.3.rawhttpinputpostprocessing">2.3&nbsp;Raw HTTP Input (POST Processing)</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#11.rawtcpipsocket">11.&nbsp;Raw TCP/IP Socket</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.1.rawsocketapplication">5.8.1&nbsp;RawSocket Application</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.3.rawsocketapplicationexamples">5.8.3&nbsp;RawSocket Application Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.4.rawsocketconfiguration">5.8.4&nbsp;RawSocket Configuration</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.2.rawsocketlibrary">5.8.2&nbsp;RawSocket Library</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.2.recommendation">&lsquo;Recommendation&rsquo; in 1.2.3.2 Restricting Persona Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.1.recordmodecgiplus">&lsquo;Record-Mode CGIplus&rsquo; in 3.1 CGIplus Programming</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.2.recordmodecode">&lsquo;Record-Mode Code&rsquo; in 3.2 Code Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#10.redactrationale">&lsquo;Redact Rationale&rsquo; in 10. Request Redaction</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#10.redactsizecallout">&lsquo;REDACT-SIZE: Callout&rsquo; in 10. Request Redaction</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#10.redactcallout">&lsquo;REDACT: Callout&rsquo; in 10. Request Redaction</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.4.reducinglatency">9.2.4&nbsp;Reducing Latency</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.1.3.reducingscriptlatency">8.1.3&nbsp;Reducing Script Latency</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.3.remember">&lsquo;Remember&rsquo; in 1.3 Script Proctor</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#10.requestredaction">10.&nbsp;Request Redaction</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#6.1.requestsandresponses">6.1&nbsp;Requests and Responses</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.5.requirements">9.2.5&nbsp;Requirements</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.1.2.requirements">9.1.2&nbsp;Requirements</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.1.requirementswhenusingcgiplus">&lsquo;Requirements when using CGIplus&rsquo; in 3.1 CGIplus Programming</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.2.restrictingpersonascripting">1.2.3.2&nbsp;Restricting Persona Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.rsadatasecurity">&lsquo;RSA Data Security&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#4.rteexample">&lsquo;RTE Example&rsquo; in 4. Run-Time Environments</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#4.1.rteprogramming">4.1&nbsp;RTE Programming</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.rulemapping">&lsquo;Rule Mapping&rsquo; in 8. DECnet &amp; OSU</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#9.2.4.2.runtimeenvironment">9.2.4.2&nbsp;Run-Time Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#4.runtimeenvironments">4.&nbsp;Run-Time Environments</a>
<tr><td class="alpha">S</td><td class="text"><a href="#1.7.scriptfileextensions">&lsquo;Script File Extensions&rsquo; in 1.7 Script Run-Time</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.6.scriptmapping">1.6&nbsp;Script Mapping</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.scriptoutput">2.2&nbsp;Script Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.4.scriptprocessdefault">1.2.4&nbsp;Script Process Default</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.5.scriptprocessparsetype">1.2.5&nbsp;Script Process Parse Type</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.6.scriptprocessrundown">1.2.6&nbsp;Script Process Run-Down</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.3.scriptproctor">1.3&nbsp;Script Proctor</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.7.scriptruntime">1.7&nbsp;Script Run-Time</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.1.scriptsystemenvironment">8.1&nbsp;Script System Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.1.scriptcontrol">&lsquo;Script-Control:&rsquo; in 2.2.1 CGI Compliant Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.13.scriptrequestedservergeneratederrorresponses">1.13&nbsp;Script-Requested, Server-Generated Error Responses</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.scriptingaccount">&lsquo;Scripting Account&rsquo; in 8. DECnet &amp; OSU</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.1.scriptingaccounts">1.1&nbsp;Scripting Accounts</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.12.scriptingfunctionlibrary">1.12&nbsp;Scripting Function Library</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.9.scriptinglogicals">1.9&nbsp;Scripting Logicals</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.scriptingprocesses">1.2&nbsp;Scripting Processes</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.10.scriptingscratchspace">1.10&nbsp;Scripting Scratch Space</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#4.2.serverconfiguration">4.2&nbsp;Server Configuration</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#7.3.serverconfiguration">7.3&nbsp;Server Configuration</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.10.sharedscratchareas">&lsquo;Shared scratch areas&rsquo; in 1.10 Scripting Scratch Space</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.1.softlimit">&lsquo;Soft Limit&rsquo; in 1.2.1 Process Management</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.1.structmodecgiplus">&lsquo;Struct-Mode CGIplus&rsquo; in 3.1 CGIplus Programming</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#3.2.structmodecode">&lsquo;Struct-Mode Code&rsquo; in 3.2 Code Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.stuartlangridge">&lsquo;Stuart Langridge&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#4.summary">&lsquo;Summary&rsquo; in 4. Run-Time Environments</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.syloginandloginprocedures">&lsquo;SYLOGIN and LOGIN Procedures&rsquo; in 1.2.3 Process Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.symboltruncation">&lsquo;Symbol Truncation&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">T</td><td class="text"><a href="#0.tableofcontent">&lsquo;Table of Content&rsquo; in  WASD Scripting Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.tatsuhirotsujikawa">&lsquo;Tatsuhiro Tsujikawa&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.3.3.terminalserver">5.8.3.3&nbsp;Terminal Server</a>
<tr><td class="alpha">U</td><td class="text"><a href="#1.10.uniquefilenamesndashclanguage">&lsquo;Unique File Names &ndash; C Language&rsquo; in 1.10 Scripting Scratch Space</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.10.uniquefilenamesndashdcl">&lsquo;Unique File Names &ndash; DCL&rsquo; in 1.10 Scripting Scratch Space</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.uniqueidnote">&lsquo;UNIQUE_ID Note&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.8.unixsyntax">1.8&nbsp;Unix Syntax</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#1.2.3.1.useraccountscripting">&lsquo;User Account Scripting&rsquo; in 1.2.3.1 Persona Scripting</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#8.4.userscripts">8.4&nbsp;User Scripts</a>
<tr><td class="alpha">V</td><td class="text"><a href="#2.1.vmsapachecswscompliance">&lsquo;VMS Apache (CSWS) Compliance&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.vmsv731andearlierhellip">&lsquo;VMS V7.3-1 and earlier &hellip;&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.1.vmsv732andlaterhellip">&lsquo;VMS V7.3-2 and later &hellip;&rsquo; in 2.1 CGI Environment Variables</a>
<tr><td class="alpha">W</td><td class="text"><a href="#1.6.quotwrappingquotlocalorthirdpartyscripts">&lsquo;&quot;Wrapping&quot; Local or Third-Party Scripts&rsquo; in 1.6 Script Mapping</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.8.wasdquotrawquotsocket">5.8&nbsp;WASD &quot;Raw&quot;Socket</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#0.wasdscriptingenvironment">&lsquo;WASD Scripting Environment&rsquo; in  WASD Scripting Environment</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#2.2.1.wasdspecifics">&lsquo;WASD Specifics&rsquo; in 2.2.1 CGI Compliant Output</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#13.wasdvmswebservicesndashcopyrightcopy19962021markgdaniel">&lsquo;WASD VMS Web Services &ndash; Copyright &copy; 1996-2021 Mark G. Daniel&rsquo; in 13. Attribution and Acknowledgement</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.websocket">5.&nbsp;WebSocket</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.4.websocketdoesthisbrowsersupport">&lsquo;WebSocket - does this browser support?&rsquo; in 5.4 WebSocket Application Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.2.websocketapplication">5.2&nbsp;WebSocket Application</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.4.websocketapplicationexamples">5.4&nbsp;WebSocket Application Examples</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.5.2.websocketcommandline">5.5.2&nbsp;WebSocket Command-Line</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.5.websocketconfiguration">5.5&nbsp;WebSocket Configuration</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.3.websocketlibrary">5.3&nbsp;WebSocket Library</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.7.websocketreferences">5.7&nbsp;WebSocket References</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.5.1.websocketthrottle">5.5.1&nbsp;WebSocket Throttle</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.6.websocketthroughput">5.6&nbsp;WebSocket Throughput</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#5.5.3.websocketversion">5.5.3&nbsp;WebSocket Version</a>
<tr><td class="alpha">&nbsp;</td><td class="text"><a href="#7.2.writingisapiscripts">7.2&nbsp;Writing ISAPI Scripts</a>
<tr><td class="alpha">Y</td><td class="text"><a href="#2.2.3.ymmv">&lsquo;YMMV&rsquo; in 2.2.3 Bulk Content Output</a>
</table>
</div>


<hr class="page">
<a id="13." href="#"></a>
<a id="13.attributionandacknowledgement" href="#"></a>
<a id="attributionandacknowledgement" href="#"></a>
<h1 class="head"><span class="numb">13.</span><span class="text">Attribution and Acknowledgement</span></h1>

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#12.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a>&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>

<a id="13.0.0.0.1" href="#"></a>
<a id="13.wasdvmswebservicesndashcopyrightcopy19962021markgdaniel" href="#"></a>
<a id="wasdvmswebservicesndashcopyrightcopy19962021markgdaniel" href="#"></a>
<h5 class="head"><span class="text">WASD VMS Web Services &ndash; Copyright &copy; 1996-2021 Mark G. Daniel</span></h5>

<a id="13.0.0.0.2" href="#"></a>
<a id="13.licensedundertheapachelicenseversion20" href="#"></a>
<a id="licensedundertheapachelicenseversion20" href="#"></a>
<h5 class="head"><span class="text">Licensed under the <span class="high bold">Apache License</span>, Version 2.0</span></h5>

<p>
<div class="blockof code">You may not use this software except in compliance with the License.
You may obtain a copy of the License at

<a class="link blank" target="_blank" style="margin-left:1em;" href="https://www.apache.org/licenses/LICENSE-2.0">https://www.apache.org/licenses/LICENSE-2.0</a>

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
</div>

<a id="13.0.0.0.3" href="#"></a>
<a id="13.noneofthefollowinglicensingappearsincompatiblewiththeapachelicense" href="#"></a>
<a id="noneofthefollowinglicensingappearsincompatiblewiththeapachelicense" href="#"></a>
<h5 class="head"><span class="text">None of the following licensing appears incompatible with the Apache License</span></h5>

<a id="13.0.0.0.4" href="#"></a>
<a id="13.clarkcooperetal" href="#"></a>
<a id="clarkcooperetal" href="#"></a>
<h5 class="head"><span class="text">Clark Cooper, et.al.</span></h5>

<p> This package uses the Expat XML parsing toolkit.

<div class="blockof code">Copyright (c) 1998, 1999, 2000
Thai Open Source Software Center Ltd and Clark Cooper
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
&quot;Software&quot;), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
</div>

<a id="13.0.0.0.5" href="#"></a>
<a id="13.bjoumlernhoumlehrmann" href="#"></a>
<a id="bjoumlernhoumlehrmann" href="#"></a>
<h5 class="head"><span class="text">Bj&ouml;ern H&ouml;ehrmann</span></h5>

<p> This package uses essential algorithm and code from Flexible and Economical
UTF-8 Decoder.

<div class="blockof code">Copyright (c) 2008-2009 Bj&ouml;ern H&ouml;ehrmann (&lt;bjoern@hoehrmann.de&gt;)

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
&quot;Software&quot;), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
</div>

<a id="13.0.0.0.6" href="#"></a>
<a id="13.freesoftwarefoundation" href="#"></a>
<a id="freesoftwarefoundation" href="#"></a>
<h5 class="head"><span class="text">Free Software Foundation</span></h5>

<p> This package contains software made available by the Free Software
Foundation under the GNU General Public License.

<div class="blockof code">This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
</div>

<a id="13.0.0.0.7" href="#"></a>
<a id="13.ohiostateuniversity" href="#"></a>
<a id="ohiostateuniversity" href="#"></a>
<h5 class="head"><span class="text">Ohio State University</span></h5>

<p> This package contains software provided with the OSU (DECthreads) HTTP
server package, authored by David Jones:

<div class="blockof code">Copyright 1994,1997 The Ohio State University.  
The Ohio State University will not assert copyright with respect
to reproduction, distribution, performance and/or modification 
of this program by any person or entity that ensures that all 
copies made, controlled or distributed by or for him or it bear 
appropriate acknowlegement of the developers of this program.
</div>

<a id="13.0.0.0.8" href="#"></a>
<a id="13.opensslproject" href="#"></a>
<a id="opensslproject" href="#"></a>
<h5 class="head"><span class="text">OpenSSL Project</span></h5>
                                                                           
<p> This product <span class="high italic">can</span> include software developed by the OpenSSL Project for
use in the OpenSSL Toolkit (<a class="link blank" target="_blank" href="https://www.openssl.org/">https://www.openssl.org/</a>).

<div class="blockof code">Redistribution and use in source and binary forms, with or without
modification, are permitted ...
</div>

<a id="13.0.0.0.9" href="#"></a>
<a id="13.paulejones" href="#"></a>
<a id="paulejones" href="#"></a>
<h5 class="head"><span class="text">Paul E. Jones</span></h5>

<p> This package uses SHA-1 hash code.

<div class="blockof code">Copyright (C) 1998, 2009
Paul E. Jones &lt;paulej@packetizer.com&gt;

Freeware Public License (FPL)

This software is licensed as &quot;freeware.&quot;  Permission to distribute this
software in source and binary forms, including incorporation  into other
products, is hereby granted without a fee.
</div>

<a id="13.0.0.0.10" href="#"></a>
<a id="13.rsadatasecurity" href="#"></a>
<a id="rsadatasecurity" href="#"></a>
<h5 class="head"><span class="text">RSA Data Security</span></h5>

<p> This software contains code derived in part from RSA Data Security, Inc:

<div class="blockof code">permission granted to make and use derivative works provided that such works
are identified as &quot;derived from the RSA Data Security, Inc. MD5 Message-Digest
Algorithm&quot; in all material mentioning or referencing the derived work.
</div>

<a id="13.0.0.0.11" href="#"></a>
<a id="13.stuartlangridge" href="#"></a>
<a id="stuartlangridge" href="#"></a>
<h5 class="head"><span class="text">Stuart Langridge</span></h5>

<p> SortTable version 2
<br> Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/

<div class="blockof code">Thanks to many, many people for contributions and suggestions.
Licenced as X11: <a class="link blank" target="_blank" href="http://www.kryogenix.org/code/browser/licence.html">http://www.kryogenix.org/code/browser/licence.html</a>
This basically means: do what you want with it.
</div>

<a id="13.0.0.0.12" href="#"></a>
<a id="13.tatsuhirotsujikawa" href="#"></a>
<a id="tatsuhirotsujikawa" href="#"></a>
<h5 class="head"><span class="text">Tatsuhiro Tsujikawa</span></h5>

<p> nghttp2 - HTTP/2 C Library
<br> Tatsuhiro Tsujikawa, <a class="link blank" target="_blank" href="https://github.com/tatsuhiro-t">https://github.com/tatsuhiro-t</a>

<div class="blockof code">Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the &quot;Software&quot;), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
</div>

<p> <span class="high bold">VSI OpenVMS</span>,
<span class="high bold">VSI TCP/IP Services for OpenVMS</span>,
<span class="high bold">VSI C</span>

<br> are registered trademarks of VMS Software Inc. 

<p> <span class="high bold">OpenVMS</span>,
<span class="high bold">HP TCP/IP Services for OpenVMS</span>,
<span class="high bold">HP C</span>,
<span class="high bold">Alpha</span>,
<span class="high bold">Itanium</span> and
<span class="high bold">VAX</span>

<br> are registered trademarks of Hewlett Packard Enterprise 

<p> <span class="high bold">MultiNet</span> and <span class="high bold">TCPware</span> are registered trademarks of Process Software
Corporation

<table class="NAVtable NAVprint"><tr>
<td><a href="javascript:window.history.back();">&#8617;&#xFE0E;</a>
<td><a href="#12.">&#8598;&#xFE0E;</a>
<td><a href="#0.">&#8593;&#xFE0E;</a>
<td><a>&#8600;&#xFE0E;</a>
<td><a href="javascript:window.history.forward();">&#8618;&#xFE0E;</a>
</table>
<title>WASD Scripting Environment</title>