httpd response mimetype bug

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

httpd response mimetype bug

Hidvégi Gábor
 >Synopsis: httpd reports wrong mimetype when item is in the browser cache
 >Category: httpd
 >Environment:
         System      : OpenBSD 6.2
         Details     : OpenBSD 6.2 (GENERIC) #91: Wed Oct  4 00:35:21
MDT 2017
 
[hidden email]:/usr/src/sys/arch/armv7/compile/GENERIC

         Architecture: OpenBSD.armv7
         Machine     : armv7
 >Description:

httpd serves static files (eg. images) with Last-Modified http header.
When a browser next time asks whether this file changed (sends
If-Modified-Since http header) httpd responds with wrong mimetype,
'text/html' when the resource is in the browser cache (304 Not Modified
status code).

 >How-To-Repeat:

This bug is common, not arm only. When for example you open this image:
https://man.openbsd.org/openbsd.gif

in a browser with developer tools (F12) open, on the network tab you can
take a look at the response headers, mimetype is correct (image/gif).
After opening press refresh (F5) and look at the response headers again,
and you get the incorrect mimetype, 'text/html'.

 >Fix:

check httpd source

dmesg:
OpenBSD 6.2 (GENERIC) #91: Wed Oct  4 00:35:21 MDT 2017
     [hidden email]:/usr/src/sys/arch/armv7/compile/GENERIC
real mem  = 1073741824 (1024MB)
avail mem = 1043845120 (995MB)
mainbus0 at root: Cubietech Cubieboard2
cpu0 at mainbus0: ARM Cortex-A7 r0p4 (ARMv7)
cpu0: DC enabled IC enabled WB disabled EABT branch prediction enabled
cpu0: 32KB(32b/l,2way) I-cache, 32KB(64b/l,4way) wr-back D-cache
cortex0 at mainbus0
sxiccmu0 at mainbus0
psci0 at mainbus0
agtimer0 at mainbus0: tick rate 24000 KHz
simplebus0 at mainbus0: "soc"
sxipio0 at simplebus0: 175 pins
sximmc0 at simplebus0
sdmmc0 at sximmc0: 4-bit, sd high-speed, mmc high-speed, dma
ehci0 at simplebus0
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 configuration 1 interface 0 "Generic EHCI root hub" rev
2.00/1.00 addr 1
sxiahci0 at simplebus0: AHCI 1.1
scsibus0 at sxiahci0: 32 targets
ehci1 at simplebus0
usb1 at ehci1: USB revision 2.0
uhub1 at usb1 configuration 1 interface 0 "Generic EHCI root hub" rev
2.00/1.00 addr 1
sxidog0 at simplebus0
sxirtc0 at simplebus0
com0 at simplebus0: ns16550, no working fifo
com0: console
sxitwi0 at simplebus0
iic0 at sxitwi0
axppmic0 at iic0 addr 0x34: AXP209, ACIN
sxitwi1 at simplebus0
iic1 at sxitwi1
dwge0 at simplebus0
dwge0: address: fe:e1:ba:d0:c1:00
rlphy0 at dwge0 phy 1: RTL8201L 10/100 PHY, rev. 1
ampintc0 at simplebus0 nirq 160, ncpu 2
gpio0 at sxipio0: 32 pins
gpio1 at sxipio0: 32 pins
gpio2 at sxipio0: 32 pins
gpio3 at sxipio0: 32 pins
gpio4 at sxipio0: 32 pins
gpio5 at sxipio0: 32 pins
gpio6 at sxipio0: 32 pins
gpio7 at sxipio0: 32 pins
gpio8 at sxipio0: 32 pins
scsibus1 at sdmmc0: 2 targets, initiator 0
sd0 at scsibus1 targ 1 lun 0: <SD/MMC, SD16G, 0030> SCSI2 0/direct removable
sd0: 14756MB, 512 bytes/sector, 30220288 sectors
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
boot device: sd0
root on sd0a (71701353fb3b725d.a) swap on sd0b dump on sd0b

usbdevs:
Controller /dev/usb0:
addr 1: high speed, self powered, config 1, EHCI root hub(0x0000),
Generic(0x0000), rev 1.00
  port 1 powered
Controller /dev/usb1:
addr 1: high speed, self powered, config 1, EHCI root hub(0x0000),
Generic(0x0000), rev 1.00
  port 1 powered


Gábor Hidvégi

Reply | Threaded
Open this post in threaded view
|

Re: httpd response mimetype bug

Hiltjo Posthuma
On Sat, Jan 13, 2018 at 09:39:44AM +0100, Anton Lindqvist wrote:

> On Tue, Jan 09, 2018 at 05:38:57PM +0100, Hidvégi Gábor wrote:
> > >Synopsis: httpd reports wrong mimetype when item is in the browser cache
> > >Category: httpd
> > >Environment:
> >         System      : OpenBSD 6.2
> >         Details     : OpenBSD 6.2 (GENERIC) #91: Wed Oct  4 00:35:21 MDT
> > 2017
> >
> > [hidden email]:/usr/src/sys/arch/armv7/compile/GENERIC
> >
> >         Architecture: OpenBSD.armv7
> >         Machine     : armv7
> > >Description:
> >
> > httpd serves static files (eg. images) with Last-Modified http header. When
> > a browser next time asks whether this file changed (sends If-Modified-Since
> > http header) httpd responds with wrong mimetype, 'text/html' when the
> > resource is in the browser cache (304 Not Modified status code).
> >
> > >How-To-Repeat:
> >
> > This bug is common, not arm only. When for example you open this image:
> > https://man.openbsd.org/openbsd.gif
> >
> > in a browser with developer tools (F12) open, on the network tab you can
> > take a look at the response headers, mimetype is correct (image/gif). After
> > opening press refresh (F5) and look at the response headers again, and you
> > get the incorrect mimetype, 'text/html'.
> >
> > >Fix:
> >
> > check httpd source
>
> Please try out this diff, it makes sure to set the correct MIME-type and
> not respond with a body if the resource has not changed. Sending this to
> tech@ as well.
>
> Index: server_file.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/httpd/server_file.c,v
> retrieving revision 1.65
> diff -u -p -r1.65 server_file.c
> --- server_file.c 2 Feb 2017 22:19:59 -0000 1.65
> +++ server_file.c 12 Jan 2018 19:10:20 -0000
> @@ -230,8 +230,15 @@ server_file_request(struct httpd *env, s
>   goto abort;
>   }
>  
> - if ((ret = server_file_modified_since(clt->clt_descreq, st)) != -1)
> - return (ret);
> + if (server_file_modified_since(clt->clt_descreq, st) == 0) {
> + media = media_find_config(env, srv_conf, path);
> + ret = server_response_http(clt, 304, media, 0,
> +    st->st_mtim.tv_sec);
> + if (ret != -1)
> + goto done;
> + else
> + goto fail;
> + }
>  
>   /* Now open the file, should be readable or we have another problem */
>   if ((fd = open(path, O_RDONLY)) == -1)
> @@ -663,10 +670,10 @@ server_file_modified_since(struct http_d
>   if (strptime(since->kv_value,
>      "%a, %d %h %Y %T %Z", &tm) != NULL &&
>      timegm(&tm) >= st->st_mtim.tv_sec)
> - return (304);
> + return (0);
>   }
>  
> - return (-1);
> + return (1);
>  }
>  
>  int
>

Hey,

I've tested your patch.

When requesting a non-modified CSS file:

        #!/bin/sh
        host="127.0.0.1"
        port="6970"
        printf 'GET /style.css HTTP/1.1\r\nHost: %s:%s\r\nIf-Modified-Since: Sat, 16 Dec 2017 13:07:53 GMT\r\nConnection: close\r\n\r\n' "$host" "$port" | \
        nc "$host" "$port"

Full HTTP response:

        HTTP/1.1 304 Not Modified
        Connection: close
        Content-Length: 0
        Content-Type: text/css
        Date: Sat, 13 Jan 2018 11:54:13 GMT
        Last-Modified: Sun, 05 Mar 2017 12:22:05 GMT
        Server: OpenBSD httpd

I wonder if httpd should just omit the response header Content-Length and
Content-Type entirely for this statuscode. Some httpd such as Nginx just
omit them aswell.

At the moment responses with redirects (statuscode 301 and 302) also
output a body response. Maybe it is better to handle it in server_http.c
in the function server_abort_http() and not output the body there for some
response status codes? I'm not sure.

--
Kind regards,
Hiltjo