httpd: explicit errors on unknown method or missing http version
Hi, If a client sends a bogus request with an unknown method or no http version string, httpd currently grabs the last error with strerror(), this patch causes it to call server_abort_http() directly with a more explicit error message: Index: server_http.c === RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v retrieving revision 1.54 diff -u -p -r1.54 server_http.c --- server_http.c 25 Oct 2014 03:23:49 - 1.54 +++ server_http.c 28 Nov 2014 15:37:51 - @@ -216,8 +216,10 @@ server_read_http(struct bufferevent *bev */ if (clt-clt_line == 1) { if ((desc-http_method = server_httpmethod_byname(key)) - == HTTP_METHOD_NONE) - goto fail; + == HTTP_METHOD_NONE) { + server_abort_http(clt, 501, unknown method); + return + } /* * Decode request path and query @@ -230,7 +232,8 @@ server_read_http(struct bufferevent *bev desc-http_version = strchr(desc-http_path, ' '); if (desc-http_version == NULL) { free(line); - goto fail; + server_abort_http(clt, 500, no http version); + return; } *desc-http_version++ = '\0'; desc-http_query = strchr(desc-http_path, '?');
Re: httpd: don't send error body with HEAD method
Bertrand Janin wrote : Philip Guenther wrote : On Mon, Nov 24, 2014 at 11:24 AM, Florian Obser flor...@openbsd.org wrote: ... Since we are probably not supposed to send a Content-Type header I think it makes sense to duplicate the httpmsg generating code in this case; If a GET of that resource would have a Content-Type, then the HEAD of it should have one. Per RFC 2616, HEAD and GET should return the same header fields and only differ by HEAD leaving out the body. Here is an updated patch which fix the leak identified by Florian, ensures the headers are identical with HEAD and non-HEAD methods and adds Content-Length. Replaced strlen() with the output from asprintf(), any comments? Index: usr.sbin/httpd/server_http.c === RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v retrieving revision 1.54 diff -u -p -r1.54 server_http.c --- usr.sbin/httpd/server_http.c25 Oct 2014 03:23:49 - 1.54 +++ usr.sbin/httpd/server_http.c26 Nov 2014 03:05:48 - @@ -665,10 +665,11 @@ server_abort_http(struct client *clt, u_ struct server *srv = clt-clt_srv; struct server_config*srv_conf = srv-srv_conf; struct bufferevent *bev = clt-clt_bev; - const char *httperr = NULL, *text = ; - char*httpmsg, *extraheader = NULL; + struct http_descriptor *desc = clt-clt_descreq; + const char *httperr = NULL, *style; + char*httpmsg, *body = NULL, *extraheader = NULL; char tmbuf[32], hbuf[128]; - const char *style; + int bodylen; if ((httperr = server_httperror_byid(code)) == NULL) httperr = Unknown Error; @@ -710,15 +711,9 @@ server_abort_http(struct client *clt, u_ style = body { background-color: white; color: black; font-family: 'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }\n hr { border: 0; border-bottom: 1px dashed; }\n; - /* Generate simple HTTP+HTML error document */ - if (asprintf(httpmsg, - HTTP/1.0 %03d %s\r\n - Date: %s\r\n - Server: %s\r\n - Connection: close\r\n - Content-Type: text/html\r\n - %s - \r\n + + /* Generate simple HTML error document */ + if ((bodylen = asprintf(body, !DOCTYPE HTML PUBLIC \-//W3C//DTD HTML 4.01 Transitional//EN\\n html\n @@ -728,14 +723,26 @@ server_abort_http(struct client *clt, u_ /head\n body\n h1%03d %s/h1\n - div id='m'%s/div\n hr\naddress%s/address\n /body\n /html\n, - code, httperr, tmbuf, HTTPD_SERVERNAME, + code, httperr, style, code, httperr, HTTPD_SERVERNAME)) == -1) + goto done; + + /* Add basic HTTP headers */ + if (asprintf(httpmsg, + HTTP/1.0 %03d %s\r\n + Date: %s\r\n + Server: %s\r\n + Connection: close\r\n + Content-Type: text/html\r\n + Content-Length: %d\r\n + %s + \r\n + %s, + code, httperr, tmbuf, HTTPD_SERVERNAME, bodylen, extraheader == NULL ? : extraheader, - code, httperr, style, code, httperr, text, - HTTPD_SERVERNAME) == -1) + desc-http_method == HTTP_METHOD_HEAD ? : body) == -1) goto done; /* Dump the message without checking for success */ @@ -743,6 +750,7 @@ server_abort_http(struct client *clt, u_ free(httpmsg); done: + free(body); free(extraheader); if (asprintf(httpmsg, %s (%03d %s), msg, code, httperr) == -1) { server_close(clt, msg);
Re: httpd: don't send error body with HEAD method
Florian Obser wrote : On Sun, Nov 23, 2014 at 08:15:47PM -0500, Bertrand Janin wrote: Hi, This patch updates server_abort_http() to only send the body of default http error if the method is not HEAD. I first noticed that with curl -v -I which complains about the excess data: * Excess found in a non pipelined read: excess = 397 url = /asd (zero-length body) Nice catch. However, your diff will leak body if the second asprintf(3) fails. Since we are probably not supposed to send a Content-Type header I think it makes sense to duplicate the httpmsg generating code in this case; it feels easier. While in there nuke unneeded text variable and shuffle variable declarations around. Indeed, that's much better. -b
httpd: don't send error body with HEAD method
Hi, This patch updates server_abort_http() to only send the body of default http error if the method is not HEAD. I first noticed that with curl -v -I which complains about the excess data: * Excess found in a non pipelined read: excess = 397 url = /asd (zero-length body) Index: usr.sbin/httpd/server_http.c === RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v retrieving revision 1.54 diff -u -p -r1.54 server_http.c --- usr.sbin/httpd/server_http.c25 Oct 2014 03:23:49 - 1.54 +++ usr.sbin/httpd/server_http.c23 Nov 2014 23:49:44 - @@ -665,8 +665,9 @@ server_abort_http(struct client *clt, u_ struct server *srv = clt-clt_srv; struct server_config*srv_conf = srv-srv_conf; struct bufferevent *bev = clt-clt_bev; + struct http_descriptor *desc = clt-clt_descreq; const char *httperr = NULL, *text = ; - char*httpmsg, *extraheader = NULL; + char*httpmsg, *body = NULL, *extraheader = NULL; char tmbuf[32], hbuf[128]; const char *style; @@ -706,10 +707,33 @@ server_abort_http(struct client *clt, u_ break; } - /* A CSS stylesheet allows minimal customization by the user */ - style = body { background-color: white; color: black; font-family: - 'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', sans-serif; }\n - hr { border: 0; border-bottom: 1px dashed; }\n; + /* Generate the body (not needed for HEAD requests) */ + if (desc-http_method != HTTP_METHOD_HEAD) { + /* A CSS stylesheet allows minimal customization by the user */ + style = body { background-color: white; color: black; + font-family: 'Comic Sans MS', 'Chalkboard SE', + 'Comic Neue', sans-serif; }\n + hr { border: 0; border-bottom: 1px dashed; }\n; + + if (asprintf(body, + !DOCTYPE HTML PUBLIC + \-//W3C//DTD HTML 4.01 Transitional//EN\\n + html\n + head\n + title%03d %s/title\n + style type=\text/css\!--\n%s\n--/style\n + /head\n + body\n + h1%03d %s/h1\n + div id='m'%s/div\n + hr\naddress%s/address\n + /body\n + /html\n, + code, httperr, style, code, httperr, text, + HTTPD_SERVERNAME) == -1) + goto done; + } + /* Generate simple HTTP+HTML error document */ if (asprintf(httpmsg, HTTP/1.0 %03d %s\r\n @@ -719,28 +743,16 @@ server_abort_http(struct client *clt, u_ Content-Type: text/html\r\n %s \r\n - !DOCTYPE HTML PUBLIC - \-//W3C//DTD HTML 4.01 Transitional//EN\\n - html\n - head\n - title%03d %s/title\n - style type=\text/css\!--\n%s\n--/style\n - /head\n - body\n - h1%03d %s/h1\n - div id='m'%s/div\n - hr\naddress%s/address\n - /body\n - /html\n, + %s, code, httperr, tmbuf, HTTPD_SERVERNAME, extraheader == NULL ? : extraheader, - code, httperr, style, code, httperr, text, - HTTPD_SERVERNAME) == -1) + body == NULL ? : body) == -1) goto done; /* Dump the message without checking for success */ server_dump(clt, httpmsg, strlen(httpmsg)); free(httpmsg); + free(body); done: free(extraheader);
ksh global PWD env variable
PWD is considered local in /bin/ksh while it is global in most other shells (ksh93, csh, bash, zsh). In practice, it means calling getenv(PWD) from a child process returns NULL on ksh (and pdksh) unless you export it before hand. I discovered this while using getenv(PWD) to get the parent shell's current path without resolved symlinks. It worked everywhere except on my OpenBSD machines. I don't mind putting export PWD in my kshrc but is there a reason why it couldn't be a default? -b Index: main.c === RCS file: /cvs/src/bin/ksh/main.c,v retrieving revision 1.52 diff -p -u -r1.52 main.c --- main.c 15 Jun 2013 17:25:19 - 1.52 +++ main.c 21 Jul 2013 19:10:02 - @@ -31,7 +31,7 @@ static const char initsubs[] = ${PS2= static const char *initcoms [] = { typeset, -r, KSH_VERSION, NULL, - typeset, -x, SHELL, PATH, HOME, NULL, + typeset, -x, SHELL, PATH, HOME, PWD, NULL, typeset, -i, PPID, NULL, typeset, -i, OPTIND=1, NULL, eval, typeset -i RANDOM MAILCHECK=\${MAILCHECK-600}\ SECONDS=\${SECONDS-0}\ TMOUT=\${TMOUT-0}\, NULL,
Re: ksh global PWD env variable
I for one don't see a general interest in knowing ones parents potentially faked wd. Many things can be faked by the parent. One could check if getcwd() and getenv(PWD) resolves to the same directory if this is a concern. Based on the fact that other shells have a different behavior I was curious if there was a reason to keep it this way or if it was just historical stuff from pdksh. You can find out your wd by saner means. I'd love to hear it if you don't mind, getcwd(3) returns resolved symlinks. ksh keeps track of the symlinked folders I assume for the purpose of ease of use. If a client application wants to keep the same context I think it's useful to have access to it.
Re: cwm(1) hide borders on maximize
Bertrand Janin wrote : With Xinerama enabled, the borders of a maximized window will show up on all adjacent screens. This patch hides the borders while the window is maximized. Bertrand [demime 1.01d removed an attachment of type text/x-diff] And here is the patch. Index: client.c === RCS file: /cvs/xenocara/app/cwm/client.c,v retrieving revision 1.64 diff -p -u -r1.64 client.c --- client.c27 Aug 2009 01:38:08 - 1.64 +++ client.c1 Sep 2009 03:08:33 - @@ -244,8 +244,8 @@ client_maximize(struct client_ctx *cc) ymax = xine-height; } calc: - cc-geom.x = x_org - cc-bwidth + Conf.gap_left; - cc-geom.y = y_org - cc-bwidth + Conf.gap_top; + cc-geom.x = x_org + Conf.gap_left; + cc-geom.y = y_org + Conf.gap_top; cc-geom.height = ymax - (Conf.gap_top + Conf.gap_bottom); cc-geom.width = xmax - (Conf.gap_left + Conf.gap_right); cc-flags |= CLIENT_DOMAXIMIZE; @@ -323,6 +323,7 @@ client_resize(struct client_ctx *cc) CLIENT_HMAXIMIZED); if (cc-flags CLIENT_DOMAXIMIZE) { + cc-bwidth = 0; cc-flags = ~CLIENT_DOMAXIMIZE; cc-flags |= CLIENT_MAXIMIZED; } else if (cc-flags CLIENT_DOVMAXIMIZE) { @@ -331,7 +332,11 @@ client_resize(struct client_ctx *cc) } else if (cc-flags CLIENT_DOHMAXIMIZE) { cc-flags = ~CLIENT_DOHMAXIMIZE; cc-flags |= CLIENT_HMAXIMIZED; + } else { + cc-bwidth = Conf.bwidth; } + + client_draw_border(cc); XMoveResizeWindow(X_Dpy, cc-win, cc-geom.x, cc-geom.y, cc-geom.width, cc-geom.height);