You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Jesse Pelton <js...@pkc.com> on 1998/11/06 20:44:20 UTC

os-windows/3358: Extra CR LF follows headers under ISAPI

>Number:         3358
>Category:       os-windows
>Synopsis:       Extra CR LF follows headers under ISAPI
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    apache
>State:          open
>Class:          sw-bug
>Submitter-Id:   apache
>Arrival-Date:   Fri Nov  6 11:50:00 PST 1998
>Last-Modified:
>Originator:     jsp@pkc.com
>Organization:
apache
>Release:        1.3.3
>Environment:
Windows NT Workstation 4.0 SP4
MSVC++ 5.0
Netscape Navigator 3.0, 4.07, 4.5
Internet Explorer 4.0 (4.72.3110.8)
>Description:
This is similar to, but I think distinct from, PR 2060.

Apache's ServerSupportFunction(HSE_REQ_SEND_RESPONSE_HEADER) behaves differently
from the one in Microsoft's Internet Information Server and Personal Web Server.
The MS servers do not write an empty header line to signify the end of the
headers, so it's up to the ISA to do so.  MFC's CHttpServer::HttpExtensionProc()
(in isapi.cpp) therefore includes the following code:

  // write a newline to separate content from headers

  if (ctxtCall.m_bSendHeaders)
  {
    *pbContent = cSaved;
    DWORD dwNewLineSize = 2;
    bWorked = ctxtCall.WriteClient(_T("\r\n"), &dwNewLineSize, 0);
  }

Apache writes a blank line, then MFC writes another.  This is harmless if the
ISA is writing HTML, but if it's writing binary data (in my case, image/png),
the transmitted data are likely to be rendered invalid by the extra bytes.
>How-To-Repeat:
Use MFC to create an ISA that uses AddHeader() to specify a content-type of
image/png, then copy a valid PNG file to the output stream.  Don't use MFC's
StartContent() and EndContent(); they emit HMTL.  If you get your ISA "right,"
you'll be able to view the image in a browser if the server is IIS/PWS, but
the image will have \r\n prepended under Apache.

My premise, of course, is that Microsoft's servers are the only real
authority on correct ISAPI implementation, whether or not they operate in
accord with the ISAPI specification.
>Fix:
None that I really like.  The following hack works for me:

In http_protocol.c:
- Add a parameter to terminate_header() specifying whether or not to emit a
  blank line.
- In ap_send_http_header(), check whether we're running an ISA, and if so, tell
  terminate_header() not to emit the blank line.  I use code like:

  int blank_line = 1;

#ifdef WIN32
  blank_line = strcmp(r->handler, "isapi-isa") ;
#endif

  terminate_header(r->connection->client, blank_line);

It's not clear to me whether ap_send_http_options() and ap_send_error_response()
should also test for ISAPI before calling terminate_header().  I *think* they
should always send the blank line.

I'm a bit uncomfortable about the string comparison, but I'm not an Apache
whiz (or wiz), and this was the only way I could come up with to determine
whether an ISA is running.  As an alternative, I suppose one could add a
blank_line parameter to ap_send_http_header(); it would always be true, except
in mod_isapi.c.
>Audit-Trail:
>Unformatted:
[In order for any reply to be added to the PR database, ]
[you need to include <ap...@Apache.Org> in the Cc line ]
[and leave the subject line UNCHANGED.  This is not done]
[automatically because of the potential for mail loops. ]
[If you do not include this Cc, your reply may be ig-   ]
[nored unless you are responding to an explicit request ]
[from a developer.                                      ]
[Reply only with text; DO NOT SEND ATTACHMENTS!         ]