ML07-0001-0

Chapter 8. Operating HTTPD

This chapter is for the operator. It shows how to start and stop HTTPD, what a healthy start and a normal stop look like on the console, and how to look at a running server and change a few of its settings without a restart. It also shows how to read the server from a browser or from curl with the display modules, and what to watch on a server that runs for weeks. The complete list of commands and messages is in the HTTPD Reference, in the chapters “Console Commands” and “Messages”.

The screens in this chapter were taken from a test system. The numbers in them, such as the control block addresses and the times, are those of that system and will differ on yours.

Starting

Start HTTPD with the console command S. The installation put the procedure into your procedure library (Chapter 2, “Installing HTTPD”).

S HTTPD
S HTTPD,M=HTTPPRM1
S HTTPD,D='MY.PARMLIB'

The first form reads the member that the procedure names, the second reads another member of the same library, and the third reads the member from another library. The two symbolic parameters of the procedure are M (the member) and D (the data set). The members, the keywords and the route lines are the subject of Chapter 4, “Configuring HTTPD” and Chapter 5, “Routes and Server Modules”.

The server reads the Parmlib member once, at the start. There is no command that reads it again. A change of the member takes effect at the next start (“Restarting”).

A healthy start

A good start looks like this on the console. The Parmlib member of this server has four routes for the module MVSMF:

S HTTPD
$HASP100 HTTPD    ON STCINRDR
$HASP373 HTTPD    STARTED
IEF403I HTTPD - STARTED - TIME=05.44.51
HTTPD000I HTTPD 4.5.1 (nnnnnnn) STARTING
HTTPD005I LIBC370 2.26.0 (3AA3B28)
HTTPD002I AUTHORIZED BY SVC (MODULE KEY 8)
HTTPD004I STC IDENTITY SET TO HTTPD/USER VIA RACINIT
RAKF0004 INVALID ATTEMPT TO ACCESS SYSTEM:  USER:HTTPPRB
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/info
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/services/authenticate
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/restconsoles/*
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/*
HTTPD054I LISTENING ON ANY PORT 8080
HTTPD061I STARTING SOCKET THREAD    TCB(9CD7C8) TASK(152FC8) STACKSIZE(32768)
HTTPD061I STARTING WORKER(164D00)   TCB(9BBEB8) TASK(166FC8) STACKSIZE(65536)
HTTPD061I STARTING WORKER(164C00)   TCB(9BBB88) TASK(177FC8) STACKSIZE(65536)
HTTPD061I STARTING WORKER(164B80)   TCB(9BB858) TASK(188FC8) STACKSIZE(65536)
HTTPD001I HTTPD 4.5.1 READY - SERVING /www

The first four lines come from the system. The messages of HTTPD come in the order of the table. A message in the table that does not appear above appears only in some cases.

MessageWhat it tells
HTTPD000IThe version and the commit of the build.
HTTPD005IThe version of LIBC/370 that HTTPD was linked with.
HTTPD006WOnly in a build from a changed working tree. A released build never writes it.
HTTPD002IHow HTTPD got its authority: from the library (module key 0) or by the SVC (key 8). Both are good. Chapter 2, “Installing HTTPD” explains the two ways.
HTTPD003W, HTTPD004I, HTTPD004WThe security identity of the task. HTTPD004I says that the task took the user ID and the group of the procedure parameters STCUSER and STCGRP. The two warnings say that the identity was not changed and the task keeps the one it was started with (Chapter 6, “Authentication and Security”).
RAKF0004From HTTPD 4.5.1, one line after HTTPD004I: INVALID ATTEMPT TO ACCESS SYSTEM: USER:HTTPPRB. It is RAKF refusing the test logon that the server makes. It belongs to a healthy start (“A Security System That Accepts Any User ID”).
HTTPD042WOnly if the security product accepts any user ID. The server refuses all logins and needs a new start after the cause is gone (“A Security System That Accepts Any User ID”). A healthy start does not have it.
HTTPD020WOnly if the Parmlib member could not be opened (“A missing Parmlib member is not a refusal”).
HTTPD036IOne line for each route with a program (MOD=). The line names the module and the path.
HTTPD417IOne line for each static location (LOC=).
HTTPD430WOnly if the SMF level is above NONE and SMF is not active in the system (“Recording with SMF”).
HTTPD054IHTTPD listens on the port.
HTTPD066IOnly if TRACE= is set: the request trace is on (“The Request Trace”).
HTTPD061IOne line for the socket thread and one for each worker that starts. The number of workers is the value of MINTASK.
HTTPD001IHTTPD is ready. The text is READY - SERVING and the document root, or READY - NO DOCUMENT ROOT on a server that has none.

Table 24. The messages of a start, in order

HTTPD is ready for clients only when HTTPD001I has appeared. A start that is stopped before that point ends with a message that says what failed. Chapter 12, “Troubleshooting” lists the common ones.

The next start used the lab configuration of this book. It adds the display modules and some static locations:

# HTTPD lab configuration (ug-ops, ug-security, ug-routes)
PORT=8080
DOCROOT=/www
REALM=MVS.EXAMPLE
MOD=MVSMF /zosmf/info                    AUTH=NONE
MOD=MVSMF /zosmf/services/authenticate   AUTH=NONE
MOD=MVSMF /zosmf/restconsoles/*          AUTH=TOKEN RES=FACILITY:MVSMF.CONSOLE
MOD=MVSMF /zosmf/*                       AUTH=TOKEN
MOD=HTTPDSRV /.dsrv                      AUTH=FORM
MOD=HTTPDM /.dm                          AUTH=BASIC
MOD=HTTPDMTT /.dmtt                      AUTH=BASIC
LOC=/pub/*                               AUTH=NONE
LOC=/private/*                           AUTH=BASIC
LOC=/form/*                              AUTH=FORM
LOC=/token/*                             AUTH=TOKEN
LOC=/admin/*                             AUTH=BASIC RES=FACILITY:HTTPD.ADMIN
LOC=/denied/*                            AUTH=BASIC RES=FACILITY:HTTPD.DENIED

The routes of this member register seven programs and six locations. The server writes one HTTPD036I for each program route and one HTTPD417I for each location:

S HTTPD,M=HTTPPRM1
$HASP100 HTTPD    ON STCINRDR
$HASP373 HTTPD    STARTED
IEF403I HTTPD - STARTED - TIME=05.38.23
HTTPD000I HTTPD 4.5.1 (nnnnnnn) STARTING
HTTPD005I LIBC370 2.26.0 (3AA3B28)
HTTPD002I AUTHORIZED BY SVC (MODULE KEY 8)
HTTPD004I STC IDENTITY SET TO HTTPD/USER VIA RACINIT
RAKF0004 INVALID ATTEMPT TO ACCESS SYSTEM:  USER:HTTPPRB
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/info
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/services/authenticate
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/restconsoles/*
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/*
HTTPD036I MODULE HTTPDSRV REGISTERED FOR /.dsrv
HTTPD036I MODULE HTTPDM REGISTERED FOR /.dm
HTTPD036I MODULE HTTPDMTT REGISTERED FOR /.dmtt
HTTPD417I LOCATION /pub/* REGISTERED
HTTPD417I LOCATION /private/* REGISTERED
HTTPD417I LOCATION /form/* REGISTERED
HTTPD417I LOCATION /token/* REGISTERED
HTTPD417I LOCATION /admin/* REGISTERED
HTTPD417I LOCATION /denied/* REGISTERED
HTTPD054I LISTENING ON ANY PORT 8080
HTTPD061I STARTING SOCKET THREAD    TCB(9CD6E8) TASK(1A6FC8) STACKSIZE(32768)
HTTPD061I STARTING WORKER(0FE748)   TCB(9BBA58) TASK(1BAFC8) STACKSIZE(65536)
HTTPD061I STARTING WORKER(0FE648)   TCB(9BB328) TASK(1CBFC8) STACKSIZE(65536)
HTTPD061I STARTING WORKER(0FE5C8)   TCB(9BAEB8) TASK(1DCFC8) STACKSIZE(65536)
HTTPD001I HTTPD 4.5.1 READY - SERVING /www

Count the routes in the messages and compare the count with your Parmlib member. A route that is missing from the messages is a route that the server does not have.

A start that is refused

A second HTTPD must not run on the port of a first one. HTTPD takes an exclusive lock with the name of the port when it starts. When the lock is held by another HTTPD, the new one writes HTTPD037E, stops, and the job step ends with return code 8. The member in this example has the port 8081, and another HTTPD was already running on that port:

PORT=8081
BIND_TRIES=2
BIND_SLEEP=2
DOCROOT=/www
MOD=MVSMF /zosmf/*  AUTH=TOKEN
S HTTPD,M=PRMPORT
$HASP100 HTTPD    ON STCINRDR
$HASP373 HTTPD    STARTED
IEF403I HTTPD - STARTED - TIME=05.31.14
HTTPD000I HTTPD 4.5.1 (nnnnnnn) STARTING
HTTPD005I LIBC370 2.26.0 (3AA3B28)
HTTPD002I AUTHORIZED BY SVC (MODULE KEY 8)
HTTPD004I STC IDENTITY SET TO HTTPD/USER VIA RACINIT
RAKF0004 INVALID ATTEMPT TO ACCESS SYSTEM:  USER:HTTPPRB
HTTPD036I MODULE MVSMF REGISTERED FOR /zosmf/*
HTTPD037E HTTPD IS ALREADY ACTIVE ON PORT 8081, THIS INSTANCE ENDS
HTTPD098I HTTPD SHUTTING DOWN
HTTPD416I STATS: 0 REQUESTS, 0 ERRORS, 0 BYTES
HTTPD099I HTTPD SHUTDOWN COMPLETE
IEF404I HTTPD - ENDED - TIME=05.31.14
$HASP395 HTTPD    ENDED

The three lines HTTPD098I, HTTPD416I and HTTPD099I are the lines of a normal stop (“Stopping”). The new server has read the member and registered the route (HTTPD036I) before it found the port taken, but it never listens. The first server is not touched. Look at the running one with D P (“The Operator Commands”) and decide: stop it, or give the new member another PORT.

The lock stops only a second HTTPD. A different program that holds the port is found later, when HTTPD binds the port. “Restarting” shows what the server does in that case.

A missing Parmlib member is not a refusal

The most dangerous start is the one that looks like a good one. A member name that does not exist, as in S HTTPD,M=NOSUCH, does not stop the server. HTTPD writes a warning, runs on its built-in defaults, and writes HTTPD001I READY:

S HTTPD,M=NOSUCH
$HASP100 HTTPD    ON STCINRDR
$HASP373 HTTPD    STARTED
IEF403I HTTPD - STARTED - TIME=05.48.26
HTTPD000I HTTPD 4.5.1 (nnnnnnn) STARTING
HTTPD005I LIBC370 2.26.0 (3AA3B28)
HTTPD002I AUTHORIZED BY SVC (MODULE KEY 8)
HTTPD004I STC IDENTITY SET TO HTTPD/USER VIA RACINIT
RAKF0004 INVALID ATTEMPT TO ACCESS SYSTEM:  USER:HTTPPRB
HTTPD020W CANNOT OPEN DD:HTTPPRM -- USING DEFAULTS
HTTPD054I LISTENING ON ANY PORT 8080
HTTPD061I STARTING SOCKET THREAD    TCB(9CDB00) TASK(100FC8) STACKSIZE(32768)
HTTPD061I STARTING WORKER(0DD1A8)   TCB(9CD410) TASK(114FC8) STACKSIZE(65536)
HTTPD061I STARTING WORKER(0DD0A8)   TCB(9CD0E0) TASK(125FC8) STACKSIZE(65536)
HTTPD061I STARTING WORKER(0DD028)   TCB(9BBCF8) TASK(136FC8) STACKSIZE(65536)
HTTPD001I HTTPD 4.5.1 READY - SERVING /www

Look at the capture. There is no HTTPD036I and no HTTPD417I: the server has the port 8080 and no routes. It runs, but it is not the server that the member would have given you. Treat HTTPD020W as a failed start: stop the server, correct the member name or the library, and start again. A line in the member that is not of the form KEYWORD=VALUE gives HTTPD026W in the same way and the server goes on (Chapter 4, “Configuring HTTPD”).

Stopping

Stop HTTPD with the console command P:

P HTTPD

HTTPD stops accepting connections, waits for its socket thread, ends the workers and gives back what it holds. On the console this is:

P HTTPD
HTTPD098I HTTPD SHUTTING DOWN
HTTPD060I SHUTDOWN SOCKET THREAD    TCB(9CD7C8) TASK(14FFC8) STACKSIZE(32768)
HTTPD060I SHUTDOWN WORKER(161B80)   TCB(9BA858) TASK(185FC8) STACKSIZE(65536)
HTTPD060I SHUTDOWN WORKER(161C00)   TCB(9BAB88) TASK(174FC8) STACKSIZE(65536)
HTTPD060I SHUTDOWN WORKER(161D00)   TCB(9BAEB8) TASK(163FC8) STACKSIZE(65536)
HTTPD416I STATS: 30 REQUESTS, 12 ERRORS, 21694 BYTES
HTTPD099I HTTPD SHUTDOWN COMPLETE
$HASP395 HTTPD    ENDED
IEF404I HTTPD - ENDED - TIME=00.42.25

The steps are these.

  1. HTTPD098I starts the stop.
  2. HTTPD waits up to 10 seconds for the socket thread to end. From the second second on it writes HTTPD040I WAITING FOR SOCKET THREAD TO TERMINATE (n). If the thread is still there after 10 seconds, HTTPD041I says that HTTPD detaches it by force.
  3. The listener is closed and every worker ends. Each thread writes one HTTPD060I. The count is the socket thread and the workers that were running.
  4. The modules that the server held in storage are released, and the clients and the routes are freed.
  5. HTTPD416I shows the requests, errors and bytes of the run. HTTPD099I ends the sequence, and the job ends.

A normal stop ends with return code 0. If the shutdown itself fails, the server writes HTTPD912E and the code of the failure. There is no second way to stop HTTPD from the console, and no MODIFY command stops it. The comment lines of the procedure that ships with HTTPD name a command F HTTPD,SHUTDOWN. The server does not have it. This is what it answers:

F HTTPD,SHUTDOWN
HTTPD100I CONS(0) "SHUTDOWN"
HTTPD101E UNKNOWN CONSOLE COMMAND "SHUTDOWN"
HTTPD150I MODIFY COMMANDS ARE:
HTTPD151I DISPLAY Config (D C)
HTTPD151I     DISPLAYS THE CONFIGURATION THIS SERVER IS RUNNING
HTTPD151I DISPLAY Login (D L)
HTTPD151I     DISPLAYS USERS THAT ARE LOGGED INTO THE HTTPD SERVER
HTTPD151I DISPLAY Memory xxxxxx~,nnn~ (D M xxxxxx)
HTTPD151I     DISPLAYS MEMORY AT THE GIVEN ADDRESS xxxxxx
HTTPD151I DISPLAY Ports (D P)
HTTPD151I     DISPLAYS THE PORT NUMBER THIS SERVER IS LISTENING ON
HTTPD151I DISPLAY Stats (D S)
HTTPD151I     DISPLAYS HTTPD CLIENT STATISTICS
HTTPD151I DISPLAY Threads (D T)
HTTPD151I     DISPLAYS INFORMATION ABOUT THE SERVER THREADS
HTTPD151I DISPLAY TIme ~-|+~~minutes~ (D TI)
HTTPD151I     DISPLAYS THE CURRENT TIME IN GMT AND LOCAL TIME
HTTPD151I DISPLAY Version (D V)
HTTPD151I     DISPLAYS THE SERVER VERSION AND BUILD
HTTPD151I
HTTPD151I SET MAxtask n (S MA n)
HTTPD151I     SETS THE WORKER MAXIMUM THREAD COUNT
HTTPD151I SET MIntask n (S MI n)
HTTPD151I     SETS THE WORKER MINIMUM THREAD COUNT
HTTPD151I SET Stats NONE|ERROR|AUTH|ALL ~RESET~
HTTPD151I     SETS THE SMF RECORDING LEVEL
HTTPD151I
HTTPD151I EXAMPLE: /F HTTPD,D C

A request that is in progress when the server stops is not guaranteed to complete. The sends of the server look at the stop flags, and a module that runs for a long time has to look at them itself (“Long-Running Handlers”). Before you stop the server, check with D T that no worker serves a client you care about (“The threads”).

Cancelling

P is the way to stop HTTPD (“Stopping”). The console command C ends the address space at once, whether the server is idle or serving. Cancel a server only when it does not end after P:

C HTTPD
IEE301I HTTPD    CANCEL COMMAND ACCEPTED
IEF450I HTTPD HTTPD - ABEND S222 U0000 - TIME=12.07.14
$HASP395 HTTPD    ENDED

The system ends the task, not HTTPD. IEF450I shows the abend code S222, the code of a cancel by the operator. The shutdown of the server does not run. The console shows none of HTTPD098I, HTTPD060I, HTTPD416I and HTTPD099I, so you get no counters for the run. An idle server and a server with clients connected give the same lines.

When the job has ended, start the server as after a stop (“Restarting”).

Lines from libc370. HTTPD 4.3.0 and 4.4.0 wrote lines that start with libc370 recovery: and libc370 @@@try.c failed() during a cancel, several lines, more when requests were in progress. They said only that a task was ending, which IEF450I says as well. HTTPD 4.5.0 is built with libc370 2.26.0, and the server writes none of them.

Note: A server module carries its own copy of libc370. A module that was linked with a level older than 2.26.0 can still write libc370 @@@try.c failed(): recovery cleanup-only, retry suppressed when a request is inside it at the cancel. MVSMF 1.3.0, which was linked with libc370 2.12.1, writes one such line in front of IEF450I. The line is harmless. It goes away when the module is built with libc370 2.26.0 or later.

The quiet cancel changes only the line for a task that ends because of the cancel. An abend of a request is reported as before (“Worker Abends”).

Restarting

There is no restart command. Restart is a stop and a start:

P HTTPD
S HTTPD

Wait for HTTPD099I before you start. Restart the server after

Do not mix this up with the three commands that change a setting while the server runs (“Changing the number of workers and the SMF level”). They cannot do the work of a restart.

After a quick restart the TCP/IP stack may not have released the port yet. The new server then cannot bind it. It writes HTTPD030E with the codes of the failure and, when the reason is that the address is in use, it does not give up at once. It writes

HTTPD030I EADDRINUSE, WAITING FOR TCPIP TO RELEASE HTTP PORT 8080

and tries again after a pause. The number of tries and the pause are the Parmlib keywords BIND_TRIES (default 10) and BIND_SLEEP (default 10 seconds). If the bind still fails after the last try, the server writes HTTPD030E again and the start ends. The Reference chapter “Messages” lists the codes. Wait for the line HTTPD001I before you tell the users that the server is back.

The Operator Commands

A running HTTPD takes commands with the MODIFY command of the system:

F HTTPD,D C

The answers are messages on the console, with the prefix HTTPD. The answers never go to a web client. The commands are these.

CommandTask
HELP, ?List the commands.
D CWhich configuration is the server running with?
D PWhich port does it listen on?
D VWhich version and build?
D TI [-|+][min]What time does the server see?
D LWho is logged in?
D TWhat are the threads doing?
D M address[,len]Dump storage of the server.
D SHow many requests, errors and bytes? How many connections are open?
SET MA nChange the largest number of workers.
SET MI nChange the smallest number of workers.
SET STATS level [RESET]Change the SMF level, or set the counters to zero.

Table 25. The commands for the operator

Some rules hold for all commands:

Help

F HTTPD,HELP and F HTTPD,? list the commands. The shortest form of a keyword shows in capitals. The brackets that mark an optional part show as tilde characters on the console, as in the capture below.

F HTTPD,?
HTTPD100I CONS(0) "?"
HTTPD150I MODIFY COMMANDS ARE:
HTTPD151I DISPLAY Config (D C)
HTTPD151I     DISPLAYS THE CONFIGURATION THIS SERVER IS RUNNING
HTTPD151I DISPLAY Login (D L)
HTTPD151I     DISPLAYS USERS THAT ARE LOGGED INTO THE HTTPD SERVER
HTTPD151I DISPLAY Memory xxxxxx~,nnn~ (D M xxxxxx)
HTTPD151I     DISPLAYS MEMORY AT THE GIVEN ADDRESS xxxxxx
HTTPD151I DISPLAY Ports (D P)
HTTPD151I     DISPLAYS THE PORT NUMBER THIS SERVER IS LISTENING ON
HTTPD151I DISPLAY Stats (D S)
HTTPD151I     DISPLAYS HTTPD CLIENT STATISTICS
HTTPD151I DISPLAY Threads (D T)
HTTPD151I     DISPLAYS INFORMATION ABOUT THE SERVER THREADS
HTTPD151I DISPLAY TIme ~-|+~~minutes~ (D TI)
HTTPD151I     DISPLAYS THE CURRENT TIME IN GMT AND LOCAL TIME
HTTPD151I DISPLAY Version (D V)
HTTPD151I     DISPLAYS THE SERVER VERSION AND BUILD
HTTPD151I
HTTPD151I SET MAxtask n (S MA n)
HTTPD151I     SETS THE WORKER MAXIMUM THREAD COUNT
HTTPD151I SET MIntask n (S MI n)
HTTPD151I     SETS THE WORKER MINIMUM THREAD COUNT
HTTPD151I SET Stats NONE|ERROR|AUTH|ALL ~RESET~
HTTPD151I     SETS THE SMF RECORDING LEVEL
HTTPD151I
HTTPD151I EXAMPLE: /F HTTPD,D C

The configuration, the port, the version and the time

D C shows the values that the server holds after it has read the member. Use it to see what the server made of the member, not what you meant it to do:

F HTTPD,D C
HTTPD100I CONS(0) "D C"
HTTPD128I PORT 8080  MINTASK 3  MAXTASK 9
HTTPD129I CLIENT_TIMEOUT 10  KEEPALIVE 5/100
HTTPD130I SESSION_TIMEOUT 30 MIN
HTTPD135I SESSION_MAXAGE 480 MIN
HTTPD131I DOCROOT /www
HTTPD134I CODEPAGE CP037
HTTPD136I REALM MVS.EXAMPLE
HTTPD132I SMF TYPE 243 LEVEL NONE
HTTPD133I CONFIG FROM DD:HTTPPRM
HTTPD137I RESIDENT YES  MODULES HELD 4
HTTPD138I RES_NOPROFILE ALLOW

Read the lines in this way.

MessageWhat it tells
HTTPD128IThe port and the numbers of workers. These are the values from the Parmlib member. SET MA and SET MI do not change them (“Changing the number of workers and the SMF level”).
HTTPD129IThe client timeout in seconds, and the keep-alive timeout in seconds and the number of requests on one connection.
HTTPD130I, HTTPD135IThe idle time and the maximum age of a login, in minutes (Chapter 6, “Authentication and Security”).
HTTPD131IThe document root.
HTTPD134IThe code page.
HTTPD136IThe realm of the Basic authentication.
HTTPD132IThe SMF record type and the level in effect now.
HTTPD133IWhere the configuration came from. DD:HTTPPRM means the member of the HTTPPRM DD of the procedure.
HTTPD137IWhether the modules are held in storage, and how many different modules are held. The four modules in the screen above are MVSMF, HTTPDSRV, HTTPDM and HTTPDMTT; they have seven routes.
HTTPD138IThe value of RES_NOPROFILE, ALLOW or DENY (“Refusing a Route Whose Profile Is Missing”).

Table 26. The lines of D C

The command does not list the routes. The display module HTTPDSRV does (“The Display Modules over HTTP”).

D P shows the port, D V the version and the build, and D TI the time of the server in GMT and in local time. The offset is in minutes. With a number, as in D TI -60, the command shows the time for that offset. This changes only the display.

F HTTPD,D P
HTTPD100I CONS(0) "D P"
HTTPD102I HTTPD IS LISTENING ON PORT 8080
F HTTPD,D V
HTTPD100I CONS(2) "D V"
HTTPD140I HTTPD 4.5.1 (nnnnnnn)
F HTTPD,D TI
HTTPD100I CONS(0) "D TI"
HTTPD142I TIME 2026/10/27 05:44:39 GMT
HTTPD143I TIME 2026/10/27 00:44:39 LOCAL OFFSET=-300

Who is logged in

The server holds a login for a user until it expires (Chapter 6, “Authentication and Security”). The login has the security environment (the ACEE) of the user. D L shows how many logins there are, and for each one the user ID, the address of the client and the address of the ACEE:

F HTTPD,D L
HTTPD100I CONS(0) "D L"
HTTPD121I USERS LOGGED IN: 1
HTTPD122I USER IBMUSER  IP 192.0.2.17 ACEE(9BA1E0)

The threads

D T shows each thread of the server in a block of lines that ends with a line of dashes (HTTPD199I). The blocks come in this order: the main thread, the socket thread, the dispatcher and the workers. The screen shows an idle server with three workers:

F HTTPD,D T
HTTPD100I CONS(0) "D T"
HTTPD103I ..THREAD 000FBFC8 MAIN SERVER THREAD
HTTPD104I .....EYE CTHDTASK  .....TCB 009DC328  ..OWNTCB 00000000
HTTPD105I .TERMECB 00000000  ......RC 00000000  STACKSZE 00010030
HTTPD106I ....FUNC 0009987C  ....ARG1 00000003  ....ARG2 000DB0F0
HTTPD120I ...RNAME HTTPD.0007
HTTPD199I -------------------------------------------------------
HTTPD103I ..THREAD 001A0FC8 SOCKET THREAD
HTTPD104I .....EYE CTHDTASK  .....TCB 009CD608  ..OWNTCB 009DC328
HTTPD105I .TERMECB 00000000  ......RC 00000000  STACKSZE 00008000
HTTPD106I ....FUNC 00098430  ....ARG1 000DB390  ....ARG2 0009E2E8
HTTPD119I ..SOCKET        3  ....PORT     8080  (HTTP PROTOCOL)
HTTPD199I -------------------------------------------------------
HTTPD103I ..THREAD 001A9FC8 DISPATCHER THREAD
HTTPD104I .....EYE CTHDTASK  .....TCB 009BAC18  ..OWNTCB 009DC328
HTTPD105I .TERMECB 00000000  ......RC 00000000  STACKSZE 00008000
HTTPD106I ....FUNC 000A15DC  ....ARG1 000DAE18  ....ARG2 00000000
HTTPD107I .....EYE CTHDMGR   ....TASK 001A9FC8  .WAITECB 809CD330
HTTPD108I ....FUNC 00098F1C  ...UDATA 000DB390  STACKSZE 00010000
HTTPD109I ..WORKER 000FB6D4  ...QUEUE 000FB07C  ...STATE 00000004 WAITING
HTTPD110I .MINTASK        3  .MAXTASK        9
HTTPD111I .WORKERS        3  .DISPCNT 18
HTTPD199I -------------------------------------------------------
HTTPD103I ..THREAD 001B4FC8 WORKER THREAD
HTTPD104I .....EYE CTHDTASK  .....TCB 009BAAA8  ..OWNTCB 009BAC18
HTTPD105I .TERMECB 00000000  ......RC 00000000  STACKSZE 00010000
HTTPD106I ....FUNC 00098F1C  ....ARG1 000DB390  ....ARG2 000FB748
HTTPD112I ..WORKER 000FB748  .....EYE CTHDWORK  .WAITECB 809B9F98
HTTPD113I .....MGR 000DAE18  ....TASK 001B4FC8  ...QUEUE 00000000
HTTPD114I ...STATE 00000002 WAITING
HTTPD115I ...START 000000006AE039DF  Tue Oct 27 00:42:55 2026
HTTPD116I ....WAIT 000000006AE03A28  Tue Oct 27 00:44:08 2026
HTTPD117I ....DISP 000000006AE03A27  Tue Oct 27 00:44:07 2026
HTTPD141I .DISPCNT 6
HTTPD199I -------------------------------------------------------
HTTPD103I ..THREAD 001C5FC8 WORKER THREAD
HTTPD104I .....EYE CTHDTASK  .....TCB 009BA378  ..OWNTCB 009BAC18
HTTPD105I .TERMECB 00000000  ......RC 00000000  STACKSZE 00010000
HTTPD106I ....FUNC 00098F1C  ....ARG1 000DB390  ....ARG2 000FB648
HTTPD112I ..WORKER 000FB648  .....EYE CTHDWORK  .WAITECB 809CD498
HTTPD113I .....MGR 000DAE18  ....TASK 001C5FC8  ...QUEUE 00000000
HTTPD114I ...STATE 00000002 WAITING
HTTPD115I ...START 000000006AE039DF  Tue Oct 27 00:42:55 2026
HTTPD116I ....WAIT 000000006AE03A27  Tue Oct 27 00:44:07 2026
HTTPD117I ....DISP 000000006AE03A27  Tue Oct 27 00:44:07 2026
HTTPD141I .DISPCNT 6
HTTPD199I -------------------------------------------------------
HTTPD103I ..THREAD 001D6FC8 WORKER THREAD
HTTPD104I .....EYE CTHDTASK  .....TCB 009BA048  ..OWNTCB 009BAC18
HTTPD105I .TERMECB 00000000  ......RC 00000000  STACKSZE 00010000
HTTPD106I ....FUNC 00098F1C  ....ARG1 000DB390  ....ARG2 000FB5C8
HTTPD112I ..WORKER 000FB5C8  .....EYE CTHDWORK  .WAITECB 809BA538
HTTPD113I .....MGR 000DAE18  ....TASK 001D6FC8  ...QUEUE 00000000
HTTPD114I ...STATE 00000002 WAITING
HTTPD115I ...START 000000006AE039DF  Tue Oct 27 00:42:55 2026
HTTPD116I ....WAIT 000000006AE03A28  Tue Oct 27 00:44:08 2026
HTTPD117I ....DISP 000000006AE03A27  Tue Oct 27 00:44:07 2026
HTTPD141I .DISPCNT 6
HTTPD199I -------------------------------------------------------

In the dispatcher block, HTTPD110I shows the smallest and the largest number of workers that are in effect now, and HTTPD111I the number of workers and the number of requests the dispatcher has handed out (.DISPCNT). A worker block shows the state of the worker (WAITING when it has nothing to do) and three times: when the worker started, when it last waited, and when it last got a request. A worker that serves a client has three more lines: the user, the address of the client and the socket of the connection (HTTPD118I to HTTPD120I). That is how you find a request that does not end (“Watching a Long-Running Server”).

Storage

D M address,length dumps storage of the server. The address is in hex and must be below 16 MB (hex 00FFFFFF), else the server answers with HTTPD144E. Without an address the answer is HTTPD148I, a line that shows the syntax. The length is a decimal number, or a hex number with the prefix 0x. A number with a leading 0 is octal. The default is 256 bytes, and the largest dump is 4096. An address that the task cannot read ends the dump with HTTPD147E, and the server goes on.

F HTTPD,D M 10,16
HTTPD100I CONS(0) "D M 10,16"
Dump of 00000010 "DISPLAY MEMORY" (16 bytes)
+00000 0001D048 00000000 070E0000 00000000 :..}.............:
HTTPD145I END OF MEMORY DUMP FOR 0x000010

The dump itself is not a numbered message. HTTPD145I ends it. The command is a tool for a person who knows the control blocks. The same dump is easier to read, and has links that follow the pointers, in the display modules (“The Display Modules over HTTP”).

The statistics

D S shows the SMF level and four counters:

F HTTPD,D S
HTTPD100I CONS(0) "D S"
HTTPD123I SMF: NONE (TYPE 243)
HTTPD124I REQUESTS: 18  ERRORS: 3  BYTES: 186629  ACTIVE: 0

REQUESTS is the number of requests that the server has handled since the start, ERRORS the number of responses with a status of 400 or more, and BYTES the number of bytes it has sent. ACTIVE is the number of connections that are open now. The three counters count at every SMF level, also at NONE. The same three counters are in the line HTTPD416I at the stop.

Changing the number of workers and the SMF level

Three settings can change while the server runs.

The number of workers. SET MA n sets the largest number of worker threads, SET MI n the smallest. Give the number: without one, and with a negative number, HTTPD answers HTTPD149I and changes nothing. HTTPD takes the value 0 as 1 and a value above 100 as 100, and a word that is not a number as 1. The new value holds until the server stops. The Parmlib member does not change, and D C still shows the values from the member.

The answer is the dispatcher block of D T. It shows the new limits. The count of workers in it is the count from before the server reacted. The server then starts or ends workers, and each one writes HTTPD061I or HTTPD060I:

F HTTPD,SET MA 12
HTTPD100I CONS(0) "SET MA 12"
HTTPD107I .....EYE CTHDMGR   ....TASK 001A9FC8  .WAITECB 40000000
HTTPD108I ....FUNC 00098F1C  ...UDATA 000DB390  STACKSZE 00010000
HTTPD109I ..WORKER 000FB6D4  ...QUEUE 000FB07C  ...STATE 00000004 WAITING
HTTPD110I .MINTASK        3  .MAXTASK       12
HTTPD111I .WORKERS        3  .DISPCNT 18
HTTPD199I -------------------------------------------------------
F HTTPD,SET MI 4
HTTPD100I CONS(0) "SET MI 4"
HTTPD107I .....EYE CTHDMGR   ....TASK 001A9FC8  .WAITECB 40000000
HTTPD108I ....FUNC 00098F1C  ...UDATA 000DB390  STACKSZE 00010000
HTTPD109I ..WORKER 000FB6D4  ...QUEUE 000FB07C  ...STATE 00000004 WAITING
HTTPD110I .MINTASK        4  .MAXTASK      100
HTTPD111I .WORKERS        3  .DISPCNT 18
HTTPD199I -------------------------------------------------------
HTTPD061I STARTING WORKER(0FB0F0)   TCB(9B9C70) TASK(1E7FC8) STACKSIZE(65536)

The second screen shows that a larger MINTASK starts the missing worker at once. The next screen shows the cut to 100. When MAXTASK is set below MINTASK, MINTASK follows it down, and when MINTASK is set above MAXTASK, MAXTASK follows it up. Every worker has a stack of 64 KB (the value STACKSIZE(65536) in HTTPD061I) and the region of the server is fixed in the procedure, so do not raise the limits without need.

F HTTPD,SET MA 99999
HTTPD100I CONS(0) "SET MA 99999"
HTTPD107I .....EYE CTHDMGR   ....TASK 001A9FC8  .WAITECB 40000000
HTTPD108I ....FUNC 00098F1C  ...UDATA 000DB390  STACKSZE 00010000
HTTPD109I ..WORKER 000FB6D4  ...QUEUE 000FB07C  ...STATE 00000004 WAITING
HTTPD110I .MINTASK        3  .MAXTASK      100
HTTPD111I .WORKERS        3  .DISPCNT 18
HTTPD199I -------------------------------------------------------

The SMF level. SET STATS with NONE, ERROR, AUTH or ALL sets the level of recording at once. Write the name in full. The word RESET after the level, or alone, sets the three counters to zero. The number of active connections is not set to zero.

F HTTPD,SET STATS ALL
HTTPD100I CONS(0) "SET STATS ALL"
HTTPD126I SMF LEVEL SET TO ALL
F HTTPD,SET STATS ALL RESET
HTTPD100I CONS(0) "SET STATS ALL RESET"
HTTPD126I SMF LEVEL SET TO ALL
HTTPD125I STATISTICS COUNTERS RESET

A level that the server does not know is an error, and it keeps the old level:

F HTTPD,SET STATS BOGUS
HTTPD100I CONS(0) "SET STATS BOGUS"
HTTPD126E INVALID SET STATS VALUE "BOGUS"

Commands that are not accepted

A word that HTTPD does not know as the first word gives HTTPD101E and the help text. Look at the first lines of the answer, the rest is the help:

F HTTPD,BOGUS
HTTPD100I CONS(0) "BOGUS"
HTTPD101E UNKNOWN CONSOLE COMMAND "BOGUS"
HTTPD150I MODIFY COMMANDS ARE:
HTTPD151I DISPLAY Config (D C)
HTTPD151I     DISPLAYS THE CONFIGURATION THIS SERVER IS RUNNING
HTTPD151I DISPLAY Login (D L)
HTTPD151I     DISPLAYS USERS THAT ARE LOGGED INTO THE HTTPD SERVER
HTTPD151I DISPLAY Memory xxxxxx~,nnn~ (D M xxxxxx)
HTTPD151I     DISPLAYS MEMORY AT THE GIVEN ADDRESS xxxxxx
HTTPD151I DISPLAY Ports (D P)
HTTPD151I     DISPLAYS THE PORT NUMBER THIS SERVER IS LISTENING ON
HTTPD151I DISPLAY Stats (D S)
HTTPD151I     DISPLAYS HTTPD CLIENT STATISTICS
HTTPD151I DISPLAY Threads (D T)
HTTPD151I     DISPLAYS INFORMATION ABOUT THE SERVER THREADS
HTTPD151I DISPLAY TIme ~-|+~~minutes~ (D TI)
HTTPD151I     DISPLAYS THE CURRENT TIME IN GMT AND LOCAL TIME
HTTPD151I DISPLAY Version (D V)
HTTPD151I     DISPLAYS THE SERVER VERSION AND BUILD
HTTPD151I
HTTPD151I SET MAxtask n (S MA n)
HTTPD151I     SETS THE WORKER MAXIMUM THREAD COUNT
HTTPD151I SET MIntask n (S MI n)
HTTPD151I     SETS THE WORKER MINIMUM THREAD COUNT
HTTPD151I SET Stats NONE|ERROR|AUTH|ALL ~RESET~
HTTPD151I     SETS THE SMF RECORDING LEVEL
HTTPD151I
HTTPD151I EXAMPLE: /F HTTPD,D C

A known first word with an unknown second word gives only the error:

F HTTPD,D BOGUS
HTTPD100I CONS(0) "D BOGUS"
HTTPD101E UNKNOWN CONSOLE COMMAND "DISPLAY BOGUS"
F HTTPD,SET BOGUS 1
HTTPD100I CONS(0) "SET BOGUS 1"
HTTPD101E UNKNOWN CONSOLE COMMAND "SET BOGUS"

DISPLAY or SET alone gets no answer except the echo. SET STATS without a level gives HTTPD127W, and SET MA or SET MI without a number gives HTTPD149I. Check that the echo HTTPD100I shows the command that you meant to send, and then that the answer is what you expect. A command that reaches the server and is not understood is not an abend, it is a mistyped command.

The Display Modules over HTTP

HTTPD comes with three small server modules that show the running server through HTTP. HTTPDSRV shows the control blocks of the server, such as the server block, the worker pool and the routes. HTTPDM shows any piece of storage as a dump. HTTPDMTT shows the Master Trace Table of the system. A fourth module, ABEND0C1, abends on purpose for a test of the recovery. The HTTPD Reference describes each one in the chapter “The Display Modules”. This section shows how an operator uses them.

Setting up the routes

The server registers no route for the modules by itself. The recommended lines are the ones that the lab member above has:

MOD=HTTPDSRV /.dsrv     AUTH=FORM
MOD=HTTPDM   /.dm       AUTH=BASIC
MOD=HTTPDMTT /.dmtt     AUTH=BASIC

Three rules apply, and they are not optional.

The path of the route for HTTPDM must be exactly /.dm, because the pages of HTTPDSRV have links to that path.

What authentication they need

Every route takes every kind of credential that HTTPD knows: the cookie of a login, a bearer token, and a user ID and password in Basic form. The mode in the line, FORM or BASIC, says only what a client without a credential gets. FORM sends a browser to a login page. BASIC answers with the status 401 and the request to log in. For a tool such as curl this means that curl -u works against all three routes, also against the route of HTTPDSRV, which has AUTH=FORM. Chapter 6, “Authentication and Security” explains the modes.

A request without a credential is answered with the status 401 and the realm of the server (the REALM of the member, shown in D C):

$ curl -i "http://localhost:8080/.dm?m=10&l=16"
HTTP/1.1 401 Unauthorized
Date: Tue, 27 Oct 2026 05:43:50 GMT
Server: HTTPD Server
X-Powered-By: MVSLOVERS
Connection: keep-alive
WWW-Authenticate: Basic realm="MVS.EXAMPLE"
Cache-Control: no-store
Content-Type: text/plain
Transfer-Encoding: chunked

401 Unauthorized

A user ID with a wrong password gets the same answer. The server does not say which of the two is wrong:

$ curl -i -u IBMUSER:wrong "http://localhost:8080/.dm?m=10&l=16"
HTTP/1.1 401 Unauthorized
Date: Tue, 27 Oct 2026 05:43:50 GMT
Server: HTTPD Server
X-Powered-By: MVSLOVERS
Connection: keep-alive
WWW-Authenticate: Basic realm="MVS.EXAMPLE"
Cache-Control: no-store
Content-Type: text/plain
Transfer-Encoding: chunked

401 Unauthorized

The user ID must be known to the security product. The password is in the command line of curl and so in the process list and in the history of the shell. Give the user ID alone (-u IBMUSER) and curl asks for the password. The Basic form sends the user ID and the password with every request, encoded but not encrypted.

HTTPDM, a dump of storage

The parameters of HTTPDM are the address (m), the length (l), the size of a line (c) and the output form (d). The address is in hex, the length is decimal, and the longest dump is 4096 bytes. The default output is an HTML page where every group of four bytes is a link to the storage that the four bytes point to. With d=1 the answer is plain text. The parameter t is a title that goes unchanged into the first line, so do not put text from other people into it.

The first example reads 16 bytes at the address 10 (hex), which is 16 in decimal. The first word there is the pointer to the CVT:

$ curl -s -u IBMUSER:****** "http://localhost:8080/.dm?m=10&l=16&t=CVTPTR" | sed -n "/<pre>/,/<\/pre>/p" | sed -e "s/<[^>]*>//g" | tr -cd "\n -~"

Dump of CVTPTR 00000010 (16 byte chunks) (16 bytes total)
+00000 0001D048 00000000 078D2000 000D1152 :..}.............:

The second example follows the pointer. The address 0001D048 is the first word of the first dump. It reads 64 bytes in lines of 16 bytes, and the parameter t puts the name CVT in the first line:

$ curl -s -u IBMUSER:****** "http://localhost:8080/.dm?m=0001D048&l=64&c=16&t=CVT" | sed -n "/<pre>/,/<\/pre>/p" | sed -e "s/<[^>]*>//g" | tr -cd "\n -~"

Dump of CVT 0001D048 (16 byte chunks) (64 bytes total)
+00000 00000218 00043C28 0001CD04 00000000 :................:
+00010 00000000 00034338 00043D64 00038EE6 :...............W:
+00020 00038E60 00006490 000064E6 00044014 :...-.......W.. .:
+00030 000019D8 00044360 0126300F 0001C090 :...Q...-......{.:

The two commands in the captures cut the answer down to the dump with sed, because the page has a form around it. In a browser you get the whole page and follow the links.

HTTPDSRV, the control blocks

HTTPDSRV is for the browser. The parameter target says what to show: HTTPD (the default), MGR, MOD, WORKERS, TASK, FILE, FS and TRACE. Some of them need an address in the parameter m. The other targets answer with HTML pages. They give the offset, the name, the meaning and the value of each field. The target TRACE answers in plain text, one line for each request (“The Request Trace”). The HTTPD Reference lists the targets. The help page of HTTPDSRV lists more targets than the module has, and says that some need an address when they do not. The Reference has the correct list, and this guide uses only the targets of the Reference.

The server block shows the state and the counters of the whole server. The flag byte (offset +002C) is the state, the counters of requests, errors and bytes sent and the number of active connections are the same as in D S, and the up time is the time of the start. The screen is cut after the counters:

$ curl -s -u IBMUSER:****** "http://localhost:8080/.dsrv?target=HTTPD" | sed -n "/<table>/,/<\/table>/p" | sed -e "s/<\/t[dh]><t[dh]>/  /g" -e "s/<[^>]*>//g" | tr -cd "\n -~"

Offset  Data Name  Description  Contents
+0000  httpd->eye  Eye Catcher  "*HTTPD*"
+0008  httpd->httpx  Function Pointers for CGI modules  0009DAA8
+000C  httpd->httpc  HTTP Client Array (0)  00000000
+0010  httpd->addr  HTTP Address  0.0.0.0
+0014  httpd->port  HTTP Port  8080
+0018  httpd->listen  HTTP Listen Socket  1
+001C  httpd->cfg_realm  Basic realm / server name  MVS.EXAMPLE
+0020  httpd->dbg  HTTP Debug File Handle  00000000
+0024  httpd->tzoffset  Time Zone Offset (seconds)  -18000
+0028  httpd->busy  HTTP Busy Client Array (1)  001B8D54
+002C  httpd->flag  Processing Flag  07 INIT LISTENER READY
+002D  httpd->unused_2d  Reserved (was: global LOGIN policy, retired)  00
+002E  httpd->client  Client Options  E0 TIMEOUT DUMP STATS
+002F  httpd->sockstate  socket thread: 0 starting, 1 running, 2 gone  01
+0030  httpd->socket_thread  Socket Thread Handle  001A6FC8
+0034  httpd->mgr  Thread Manager Handle  000DDE18
+0038  httpd->rname  Resource Name  "HTTPD.0007"
+0044  httpd->route  Route Array (MOD= programs, LOC= static prefixes)  000DD6D4
+0048  httpd->uptime  Server Up Time  Sat Oct 31 05:33:53 2026
+0050  httpd->trace  Request trace (NULL = off)  00000000
+0054  httpd->ufssys  UFS System Handle  000DDBB8
+0058  httpd->readerr_last  Time of Last UFS Read Error Message (#346)  0
+005C  httpd->version  Version String  "4.5.1"
+0060  httpd->readerr_held  UFS Read Errors Not Yet Reported (#346)  0
+0064  httpd->cfg_maxtask  Config Max Task  9
+0065  httpd->cfg_mintask  Config Min Task  3
+0066  httpd->cfg_client_timeout  Config Client Timeout Seconds  10
+0067  httpd->smf_level  SMF Recording Level  0 NONE
+0068  httpd->smf_type  SMF Record Type  243
+0069  httpd->cfg_resident  Config Hold MOD= Modules  YES
+006A  httpd->resident_held  Modules Held Resident  4
+006B  httpd->cfg_cgictx  Config CGI Context Pointers  255
+006C  httpd->ufs_enabled  UFS Filesystem Enabled  1
+006D  httpd->dbg_enabled  Debug Output Enabled  0
+006E  httpd->bind_tries  Socket Bind Retry Count  10
+006F  httpd->bind_sleep  Socket Bind Retry Delay (seconds)  10
+0070  httpd->total_requests  Total HTTP Requests  1
+0074  httpd->total_errors  Total Error Responses  0
+0078  httpd->total_bytes_sent  Total Bytes Sent  25440
+007C  httpd->active_connections  Active Connections  1

Further down the page, the row httpd->sec_open (offset +0122) says whether the security product accepted the test logon at the start. A healthy server shows NO. The value YES, LOGIN REFUSED goes with the message HTTPD042W (“A Security System That Accepts Any User ID”). You can read the row in a browser only through a route that lets you reach HTTPDSRV without a login, because a refused login also keeps you out of the display modules.

The block of the manager of the worker pool shows the limits that are in effect now and the number of requests that were handed out:

$ curl -s -u IBMUSER:****** "http://localhost:8080/.dsrv?target=MGR" | sed -n "/<table>/,/<\/table>/p" | sed -e "s/<\/t[dh]><t[dh]>/  /g" -e "s/<[^>]*>//g" | tr -cd "\n -~"

Offset  Data Name  Description  Contents
+0000  mgr->eye  Eye Catcher  "CTHDMGR"
+0008  mgr->task  Thread Manager Task Handle  001A9FC8
+000C  mgr->wait  Wait For Work ECB  809CD330
+0010  mgr->func  Thread Function Address  00098F1C
+0014  mgr->udata  Thread User Data  000DB390
+0018  mgr->stacksize  Thread Stack Size  65536
+001C  mgr->worker  Worker Threads Array  000FB6D4
+0020  mgr->queue  Worker Queue Array  000FB07C
+0024  mgr->state  Current State  4 "WAITING"
+0028  mgr->mintask  Minimum Worker Threads  3
+002C  mgr->maxtask  Maximum Worker Threads  9
+0030  mgr->dispatched  Dispatched Worker Threads Count  8
+0038  mgr->start  Round Robin Start Index  2
+003C  mgr->rname  Resource Name String  "CTHDMGR.0007.000DAE18"

The route array of the server block (offset +0044) is the address for the target MOD. The page for it shows every route with its path, its program, its authentication mode and its RACF resource. This is the place to check that the server holds the routes that you wrote in the member. The screen is cut after the third route. The lab member has thirteen:

$ curl -s -u IBMUSER:****** "http://localhost:8080/.dsrv?target=MOD&m=000DA6D4" | sed -n "/<table>/,/<\/table>/p" | sed -e "s/<\/t[dh]><t[dh]>/  /g" -e "s/<[^>]*>//g" | tr -cd "\n -~"

Offset  Data Name  Description  Contents
+0000  route->eye  Eye Catcher  "*ROUTE*"
+0008  route->wild  Is Wildcard  0
+0009  route->unused_09  Reserved (was: login required, retired)  0
+000A  route->len  Path Length  11
+000C  route->path  Path Name  "/zosmf/info"
+0010  route->pgm  Program Name (NULL = LOC static route)  "MVSMF"
+0014  route->auth  Auth Mode (AUTH=)  0 NONE (public -- AUTH=NONE or no AUTH=)
+0015  route->resattr  RACF Access Attribute  00 READ (assumed, RESATTR not set)
+0018  route->resclass  RACF Class (RES=, NULL = no resource gate)  "(none)"
+001C  route->resname  RACF Resource Name (RES=)  "(none)"


Offset  Data Name  Description  Contents
+0000  route->eye  Eye Catcher  "*ROUTE*"
+0008  route->wild  Is Wildcard  0
+0009  route->unused_09  Reserved (was: login required, retired)  0
+000A  route->len  Path Length  28
+000C  route->path  Path Name  "/zosmf/services/authenticate"
+0010  route->pgm  Program Name (NULL = LOC static route)  "MVSMF"
+0014  route->auth  Auth Mode (AUTH=)  0 NONE (public -- AUTH=NONE or no AUTH=)
+0015  route->resattr  RACF Access Attribute  00 READ (assumed, RESATTR not set)
+0018  route->resclass  RACF Class (RES=, NULL = no resource gate)  "(none)"
+001C  route->resname  RACF Resource Name (RES=)  "(none)"


Offset  Data Name  Description  Contents
+0000  route->eye  Eye Catcher  "*ROUTE*"
+0008  route->wild  Is Wildcard  1
+0009  route->unused_09  Reserved (was: login required, retired)  0
+000A  route->len  Path Length  21
+000C  route->path  Path Name  "/zosmf/restconsoles/*"
+0010  route->pgm  Program Name (NULL = LOC static route)  "MVSMF"
+0014  route->auth  Auth Mode (AUTH=)  3 TOKEN (bare 401, API route)
+0015  route->resattr  RACF Access Attribute  02 READ
+0018  route->resclass  RACF Class (RES=, NULL = no resource gate)  "FACILITY"
+001C  route->resname  RACF Resource Name (RES=)  "MVSMF.CONSOLE"

HTTPDMTT, the Master Trace Table

Every message that HTTPD writes to the console also goes into the Master Trace Table of the system. The table keeps the most recent messages of the console, and HTTPD writes only what an operator can act on. What went wrong with a client is in the response, not here. So the table is the diagnostic channel of the server, and HTTPDMTT shows it in a browser or with curl, without a TSO session. The module takes one parameter, d. With d=1 the answer is plain text. This is the end of the table after the start of the lab server (the capture shows the last four lines of the answer):

$ curl -s -u IBMUSER:****** http://localhost:8080/.dmtt | sed -n "/<pre>/,/<\/pre>/p" | sed -e "s/<[^>]*>//g" | tail -n 4
FFFF  5.33.53 STC   nn  HTTPD061I STARTING WORKER(0FE648)   TCB(9BB328) TASK(1CBFC8) STACKSIZE(65536)
FFFF  5.33.53 STC   nn  HTTPD061I STARTING WORKER(0FE5C8)   TCB(9BAEB8) TASK(1DCFC8) STACKSIZE(65536)
FFFF  5.33.54 STC   nn  HTTPD001I HTTPD 4.5.1 READY - SERVING /www

Each line has some fields of the table entry, the time of the entry and the text of the message. The module does not select or search. Use the plain form with a tool of your own, for example grep. The table holds only the recent messages, so a server that has run for a long time may have lost its start messages: read the table soon after a failure. It holds the messages of the whole system. It is as sensitive as the console, and the route needs the strongest authentication that you have (Chapter 6, “Authentication and Security”).

The module ABEND0C1 abends on purpose, to show that the recovery of the server works. Register it only on a test system (“Worker Abends”).

Worker Abends

HTTPD has two layers of recovery, and an abend in a request does not stop the server.

A module abends. A module runs in the task of a worker. If it abends, HTTPD frees the storage the module took from its request area, writes HTTPD908E EXTERNAL PROGRAM name failed with Sxxx ABEND to the console, and, if the module has not started a response, sends the client the status 503 with a text body. The worker goes on with the next request. If the free of the storage fails, HTTPD906W tells you. The module chapter says more about what a module has to do for itself (“When a Module Abends”).

The server code abends. If the abend is in the code of the server and not in a module, the worker writes HTTPD062E ABEND code IN WORKER(..)
CLIENT(..) SOCKET(n)
, closes the client, and goes on with the next request. If the worker cannot recover at all, the message is HTTPD063E, which says that there is no recovery and the client is dropped.

What to do: write down the message, in particular the name of the module and the code. A module that abends with every request is a defect of the module, and a module that abends now and then points to its input. The Master Trace Table keeps the message (“HTTPDMTT, the Master Trace Table”). Do not restart the server for one HTTPD908E: the worker lives on. A repeated HTTPD062E with the same code is different. It points to the server itself, and Chapter 12, “Troubleshooting” is the place to go on.

On a test system you can check the recovery. Register ABEND0C1 with AUTH=BASIC and call it a few times. Every call must give the status 503 and the text “External program ABEND0C1 failed with S0C1 ABEND”, and the other routes must go on working.

Recording with SMF

HTTPD can write an SMF record for each request, and for each connection at the highest level. This chapter gives only what the operator needs. The record layouts and the keywords are in the HTTPD Reference, in the chapter “SMF Records”.

The level is one of NONE (the default), ERROR (a record for each request with a status of 400 or more), AUTH (the requests with a status of 401 or 403, and the other errors) and ALL (every request and every connection). The default type is

  1. The Parmlib keyword SMF sets the level at the start, and

SET STATS sets it while the server runs. A level that you set with the command lasts until the server stops. The member does not change, so the next start uses the level of the member.

You can see the level in two places: HTTPD132I in D C and HTTPD123I in D S. The counters of D S run at every level. They do not tell you whether records are written.

If the member asks for a level above NONE and SMF is not active in the system, the server writes HTTPD430W at the start and runs, but it writes no record. It checks for every record whether SMF is active, so the records start when SMF becomes active. An SMF that does not record the type is a matter of the SMF parameters of your installation, which this guide does not cover.

Things to Know

Watching a Long-Running Server

A server that runs for weeks needs few commands. The commands show what they show, and no more. There is no command that shows the free storage of the region, and none that keeps a history. Write the readings into your own log if you need one.

Is it up, and busy? D S shows the requests, the errors, the bytes and the active connections. Look at it at the same time each day, and keep the numbers. The difference between two readings is the work of the period. The number of ERRORS is the number of responses with a status of 400 or more. A client that sends a wrong password adds to it, so it is not the same as a fault of the server. After SET STATS ... RESET the counters start again from zero. The count of active connections is not reset.

Are the workers free? D T shows the state of each worker. At rest all workers are WAITING. A worker that has served the same client for a long time shows the client in the lines HTTPD118I to HTTPD120I. Compare the time of the last start of work (HTTPD117I) with the time now (D TI). If all workers up to MAXTASK are busy and the clients wait, raise MAXTASK with SET MA and look at the dispatcher block again. If one request is stuck in a module, the module is the cause, and more workers do not cure it (Chapter 12, “Troubleshooting”).

Memory. The region of the server is fixed in the procedure. The commands show the sizes of the thread stacks, and D C the number of modules that the server holds. They do not show how much storage is left. Abends of workers and modules (HTTPD062E, HTTPD908E) are in the Master Trace Table (“HTTPDMTT, the Master Trace Table”). Do not raise MAXTASK far above what the load needs.

Logins. D L shows the users who are logged in. A login ends after the idle time or the maximum age that D C shows in HTTPD130I and HTTPD135I. Many logins of one user from one address may mean a client that logs in again for every request (Chapter 6, “Authentication and Security”).

Time. D TI shows the GMT and the local time of the server. The offset is the one of the system. Compare the time with a clock you trust after a change of the time zone.

The long view. With SMF at ERROR, and SMF active and set to keep the record type, the failed requests can be read later from the SMF data (“Recording with SMF”). The Master Trace Table shows the messages of the last hours, no more.