Blob
- Date:
- Message:
- import gotwebd thread fcgi response to client for rendering in browser as data is returned fix potential problem with a stuck loop if the client is hammering the server with random clicks and stop/restarts render our index! WOOHOO! small var refactoring. fcgi.c to handle all clean-up, various error clean-up remove output used to trace down got bug temporarily stop overloading a socket, but a better solution needs to be found return on fcgi_gen_response, so we can track if a client is writable or not this stops page creation when the client is unavailable remove old comments enable profile building, although, i don't think this works thoroughly in a priv/proc daemon catch more errors correctly count repos remove temp logger we don't need to start our responder thread so early. move it to fcgi.c and start when we start processing html kill the unneeded thread, stop queueing responses, and just write to clients immediately clean up some memory leaks and dead stores rework querystring so an error can be displayed instead of showing the index on querystring error get framework in place for the rest of the content add server struct to response struct bo last commit get back a usable gotweb. not sure what i was thinking yesterday properly move our structs around this time remember index page for sitelink, fix leak unused var is annoying, so stop it for now. don't forget to change this! style briefs nearly completed. finish briefs output add briefs to summary cleanup some html properly retrieve next and previous commit ids for list navigation follow naddy's stailq macro change we will never have a previous link on the summary page goto correct label, so we get a previous link on the last page of briefs don't wrap short line simplify got_get_repo_commits code start rendering a diff start rendering a diff this was by accident finish diff output functions cleanup prepare for fd request that was a stupid idea, just flush the priv_fd bo that too. that won't work eith with append in mkstemp that isn't going to work actually zero out the priv_fd missed seek to beginning of file was overwriting first line of diff fsync our fd as well add link to repo path by sitelink and add back verbose fcgi debugging that was removed add modest write heuristics to fcgi_send_response fix dead assignments and XXX comment where a leak is happening that I can't find right now there was no leak. stsp is brilliant and knew it was the cache growing prevent double-free, render prettier err output if we can remove unused variables correctly fix double-free fix gotwebd to build with main's changes after rebase fix double-free don't error on index if pack files missing and fixup some error handling render commits finish up tag briefs and start the tag page finish up tag page unbreak TAGS and SUMMARY actions grab the correct tag from the queue unbreak TAGS and SUMMARY actions again update some error handling clean up unneeded code and start tree output render tree render branches remove tags from summary if there aren't any fix tree div structure and start blob render render blob render blame fix tree href in briefs clean up some css add headref to querystrings load correct commit for tree and diff fixup some error output update some copyright dates add full SNI support rm debug line found by Lucas6023, notified via IRC. thanks!! fix tree fix crash when querystring is manipulated to not have a commit id in certain instances. also break a stuck while loop on client error. fix for new got_object_id_by_path arguments rebase and fix prep for multiple fds per socket, instead of just one fix overlooked shift/reduce conflicts backout priv_fds as a list. after discussion with stsp, an array and length are the better direction prepare array of fds to pass into got functions make a new set of pack fds, which will be passed to got_repo_open work with new pack_fds in got_repo_open give output when no tags exist escape html in blame output change files listed in tree view to show blob, file commits, and blame, instead of blob, blob, blame. idea from mp4 on irc. this is way more handy. stop populating the queue from the headref and figure out previous commit id while iterating. this should reduce some overhead. actually purge our sockets instead of not using the function start work with new blob rm volatile use new diff change func names no more temp files increase blame number line width set content-type to text/plain so firefox won't download files rm test infra for now account for -Wwrite-strings fix for sigs and algorithm choice clean up some leaks and other mistakes
- Actions:
- History | Blame | Raw File
1 /*2 * Copyright (c) 2020-2021 Tracey Emery <tracey@traceyemery.net>3 * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>4 *5 * Permission to use, copy, modify, and distribute this software for any6 * purpose with or without fee is hereby granted, provided that the above7 * copyright notice and this permission notice appear in all copies.8 *9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16 */18 #include <sys/types.h>19 #include <sys/queue.h>20 #include <sys/time.h>21 #include <sys/uio.h>22 #include <sys/socket.h>24 #include <net/if.h>25 #include <netinet/in.h>27 #include <stdio.h>28 #include <stdlib.h>29 #include <termios.h>30 #include <unistd.h>31 #include <limits.h>32 #include <string.h>33 #include <event.h>34 #include <fcntl.h>35 #include <util.h>36 #include <errno.h>37 #include <imsg.h>39 #include "got_opentemp.h"41 #include "proc.h"42 #include "gotwebd.h"44 int45 config_init(struct gotwebd *env)46 {47 struct privsep *ps = env->gotwebd_ps;48 unsigned int what;50 /* Global configuration. */51 if (privsep_process == PROC_GOTWEBD)52 env->prefork_gotwebd = GOTWEBD_NUMPROC;54 ps->ps_what[PROC_GOTWEBD] = CONFIG_ALL;55 ps->ps_what[PROC_SOCKS] = CONFIG_SOCKS;57 /* Other configuration. */58 what = ps->ps_what[privsep_process];59 if (what & CONFIG_SOCKS) {60 env->server_cnt = 0;61 env->servers = calloc(1, sizeof(*env->servers));62 if (env->servers == NULL)63 fatalx("%s: calloc", __func__);64 env->sockets = calloc(1, sizeof(*env->sockets));65 if (env->sockets == NULL)66 fatalx("%s: calloc", __func__);67 TAILQ_INIT(env->servers);68 TAILQ_INIT(env->sockets);69 }70 return 0;71 }73 int74 config_getcfg(struct gotwebd *env, struct imsg *imsg)75 {76 /* nothing to do but tell gotwebd configuration is done */77 if (privsep_process != PROC_GOTWEBD)78 proc_compose(env->gotwebd_ps, PROC_GOTWEBD,79 IMSG_CFG_DONE, NULL, 0);81 return 0;82 }84 int85 config_setserver(struct gotwebd *env, struct server *srv)86 {87 struct server ssrv;88 struct privsep *ps = env->gotwebd_ps;90 memcpy(&ssrv, srv, sizeof(ssrv));91 proc_compose(ps, PROC_SOCKS, IMSG_CFG_SRV, &ssrv, sizeof(ssrv));92 return 0;93 }95 int96 config_getserver(struct gotwebd *env, struct imsg *imsg)97 {98 struct server *srv;99 uint8_t *p = imsg->data;101 IMSG_SIZE_CHECK(imsg, &srv);103 srv = calloc(1, sizeof(*srv));104 if (srv == NULL)105 fatalx("%s: calloc", __func__);106 memcpy(srv, p, sizeof(*srv));108 if (IMSG_DATA_SIZE(imsg) != sizeof(*srv)) {109 log_debug("%s: imsg size error", __func__);110 free(srv);111 return 1;112 }114 /* log server info */115 log_debug("%s: server=%s fcgi_socket=%s unix_socket=%s", __func__,116 srv->name, srv->fcgi_socket ? "yes" : "no", srv->unix_socket ?117 "yes" : "no");119 TAILQ_INSERT_TAIL(env->servers, srv, entry);121 return 0;122 }124 int125 config_setsock(struct gotwebd *env, struct socket *sock)126 {127 struct privsep *ps = env->gotwebd_ps;128 struct socket_conf s;129 int id;130 int fd = -1, n, m;131 struct iovec iov[6];132 size_t c;133 unsigned int what;135 /* open listening sockets */136 if (sockets_privinit(env, sock) == -1)137 return -1;139 for (id = 0; id < PROC_MAX; id++) {140 what = ps->ps_what[id];142 if ((what & CONFIG_SOCKS) == 0 || id == privsep_process)143 continue;145 memcpy(&s, &sock->conf, sizeof(s));147 c = 0;148 iov[c].iov_base = &s;149 iov[c++].iov_len = sizeof(s);151 if (id == PROC_SOCKS) {152 /* XXX imsg code will close the fd after 1st call */153 n = -1;154 proc_range(ps, id, &n, &m);155 for (n = 0; n < m; n++) {156 if (sock->fd == -1)157 fd = -1;158 else if ((fd = dup(sock->fd)) == -1)159 return 1;160 if (proc_composev_imsg(ps, id, n, IMSG_CFG_SOCK,161 -1, fd, iov, c) != 0) {162 log_warn("%s: failed to compose "163 "IMSG_CFG_SOCK imsg",164 __func__);165 return 1;166 }167 if (proc_flush_imsg(ps, id, n) == -1) {168 log_warn("%s: failed to flush "169 "IMSG_CFG_SOCK imsg",170 __func__);171 return 1;172 }173 }174 }175 }177 /* Close socket early to prevent fd exhaustion in gotwebd. */178 if (sock->fd != -1) {179 close(sock->fd);180 sock->fd = -1;181 }183 return 0;184 }186 int187 config_getsock(struct gotwebd *env, struct imsg *imsg)188 {189 struct socket *sock = NULL;190 struct socket_conf sock_conf;191 uint8_t *p = imsg->data;192 int i;194 IMSG_SIZE_CHECK(imsg, &sock_conf);195 memcpy(&sock_conf, p, sizeof(sock_conf));197 if (IMSG_DATA_SIZE(imsg) != sizeof(sock_conf)) {198 log_debug("%s: imsg size error", __func__);199 return 1;200 }202 /* create a new socket */203 if ((sock = calloc(1, sizeof(*sock))) == NULL) {204 if (imsg->fd != -1)205 close(imsg->fd);206 return 1;207 }209 memcpy(&sock->conf, &sock_conf, sizeof(sock->conf));210 sock->fd = imsg->fd;212 TAILQ_INSERT_TAIL(env->sockets, sock, entry);214 for (i = 0; i < PRIV_FDS__MAX; i++)215 sock->priv_fd[i] = -1;217 for (i = 0; i < GOT_PACK_NUM_TEMPFILES; i++)218 sock->pack_fds[i] = -1;220 /* log new socket info */221 log_debug("%s: name=%s id=%d server=%s child_id=%d parent_id=%d "222 "type=%s ipv4=%d ipv6=%d socket_path=%s",223 __func__, sock->conf.name, sock->conf.id, sock->conf.srv_name,224 sock->conf.child_id, sock->conf.parent_id, sock->conf.type ?225 "fcgi" : "unix", sock->conf.ipv4, sock->conf.ipv6,226 strlen(sock->conf.unix_socket_name) ?227 sock->conf.unix_socket_name : "none");229 return 0;230 }232 int233 config_setfd(struct gotwebd *env, struct socket *sock)234 {235 struct privsep *ps = env->gotwebd_ps;236 int id, s;237 int fd = -1, n, m, j;238 struct iovec iov[6];239 size_t c;240 unsigned int what;242 log_debug("%s: Allocating %d file descriptors",243 __func__, PRIV_FDS__MAX + GOT_PACK_NUM_TEMPFILES);245 for (j = 0; j < PRIV_FDS__MAX + GOT_PACK_NUM_TEMPFILES; j++) {246 for (id = 0; id < PROC_MAX; id++) {247 what = ps->ps_what[id];249 if ((what & CONFIG_SOCKS) == 0 || id == privsep_process)250 continue;252 s = sock->conf.id;253 c = 0;254 iov[c].iov_base = &s;255 iov[c++].iov_len = sizeof(s);257 if (id == PROC_SOCKS) {258 /*259 * XXX imsg code will close the fd260 * after 1st call261 */262 n = -1;263 proc_range(ps, id, &n, &m);264 for (n = 0; n < m; n++) {265 fd = got_opentempfd();266 if (fd == -1)267 return 1;268 if (proc_composev_imsg(ps, id, n,269 IMSG_CFG_FD, -1, fd, iov, c) != 0) {270 log_warn("%s: failed to compose "271 "IMSG_CFG_FD imsg",272 __func__);273 return 1;274 }275 if (proc_flush_imsg(ps, id, n) == -1) {276 log_warn("%s: failed to flush "277 "IMSG_CFG_FD imsg",278 __func__);279 return 1;280 }281 }282 }283 }285 /* Close fd early to prevent fd exhaustion in gotwebd. */286 if (fd != -1)287 close(fd);288 }289 return 0;290 }292 int293 config_getfd(struct gotwebd *env, struct imsg *imsg)294 {295 struct socket *sock;296 uint8_t *p = imsg->data;297 int sock_id, match = 0, i;299 IMSG_SIZE_CHECK(imsg, &sock_id);300 memcpy(&sock_id, p, sizeof(sock_id));302 TAILQ_FOREACH(sock, env->sockets, entry) {303 for (i = 0; i < (GOT_PACK_NUM_TEMPFILES + PRIV_FDS__MAX); i++) {304 if (i < PRIV_FDS__MAX && sock->priv_fd[i] == -1) {305 log_debug("%s: assigning socket %d priv_fd %d",306 __func__, sock_id, imsg->fd);307 sock->priv_fd[i] = imsg->fd;308 match = 1;309 break;310 }311 if (sock->pack_fds[i - PRIV_FDS__MAX] == -1) {312 log_debug("%s: assigning socket %d pack_fd %d",313 __func__, sock_id, imsg->fd);314 sock->pack_fds[i - PRIV_FDS__MAX] = imsg->fd;315 match = 1;316 break;317 }318 }319 }321 if (match)322 return 0;323 else324 return 1;325 }