[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]
<!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>
<title>WASD Scripting Environment &ndash; CGI</title>
<a id="2." href="#"></a>
<a id="2.cgi" href="#"></a>
<a id="cgi" href="#"></a>
<h1 class="head chunk">WASD Scripting Environment</h1>
<h1 class="head"><span class="numb">2.</span><span class="text">CGI</span></h1>

<div class="TOC2cols2">
<table class="TOC2table">
<tr><td><a href="scripting002.html#2.1.cgienvironmentvariables"><span class="numb">2.1</span><span class="text">CGI Environment Variables</span></a>
<tr><td><a href="scripting002.html#2.2.scriptoutput"><span class="numb">2.2</span><span class="text">Script Output</span></a>
<tr><td><a href="scripting002.html#2.2.1.cgicompliantoutput"><span class="numb">2.2.1</span><span class="text">CGI Compliant Output</span></a>
<tr><td><a href="scripting002.html#2.2.2.nonparsedheaderoutput"><span class="numb">2.2.2</span><span class="text">Non-Parsed-Header Output</span></a>
<tr><td><a href="scripting002.html#2.2.3.bulkcontentoutput"><span class="numb">2.2.3</span><span class="text">Bulk Content Output</span></a>
<tr><td><a href="scripting002.html#2.3.rawhttpinputpostprocessing"><span class="numb">2.3</span><span class="text">Raw HTTP Input (POST Processing)</span></a>
<tr><td><a href="scripting002.html#2.4.cgifunctionlibrary"><span class="numb">2.4</span><span class="text">CGI Function Library</span></a>
<tr><td><a href="scripting002.html#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="scripting001.html#1.">&#8598;&#xFE0E;</a>
<td><a href="scripting000.html#0.">&#8593;&#xFE0E;</a>
<td><a href="scripting003.html#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="scripting001.html#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="scripting002.html#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="scripting002.html#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="scripting002.html#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="scripting002.html#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="scripting002.html#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="scripting002.html#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="scripting002.html#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="scripting006.html#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="scripting001.html#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="scripting002.html#2.5.cgiutlutility">2.5 CGIUTL Utility</a>).
<!-- source:0300_CGIPLUS.WASDOC -->

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