I notice the code to have the login result in either an html page or a redirect is somewhat awkwardly distributed between login-form (through fnform) and the login function itself.
I found it helpful to make a base op in srv.arc which outputs no headers, and then my login function was able to itself either output a page, or call a function named redirect with the url which outputs the redirect headers.