Repository: louislam/uptime-kuma
File: server/model/monitor.js (JavaScript)

Code before:
                        basicAuthHeader = {
                            "Authorization": "Basic " + this.encodeBase64(this.basic_auth_user, this.basic_auth_pass),
                        };
                    }

                    const httpsAgentOptions = {
                        maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
                        rejectUnauthorized: !this.getIgnoreTls(),
                    };

                    log.debug("monitor", `[${this.name}] Prepare Options for axios`);

                    let contentType = null;
                    let bodyValue = null;

                    if (this.body && (typeof this.body === "string" && this.body.trim().length > 0)) {
                        if (!this.httpBodyEncoding || this.httpBodyEncoding === "json") {
                            try {
                                bodyValue = JSON.parse(this.body);
                                contentType = "application/json";
                            } catch (e) {
                                throw new Error("Your JSON body is invalid. " + e.message);
                            }
                        } else if (this.httpBodyEncoding === "form") {
                            bodyValue = this.body;
                            contentType = "application/x-www-form-urlencoded; charset=utf-8";
                        } else if (this.httpBodyEncoding === "xml") {
                            bodyValue = this.body;
                            contentType = "text/xml; charset=utf-8";
                        }
                    }

                    // Axios Options
                    const options = {
                        url: this.url,
                        method: (this.method || "get").toLowerCase(),
                        timeout: this.interval * 1000 * 0.8,
                        headers: {
                            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
                            "User-Agent": "Uptime-Kuma/" + version,
                            ...(contentType ? { "Content-Type": contentType } : {}),
                            ...(basicAuthHeader),
                            ...(this.headers ? JSON.parse(this.headers) : {})
                        },
                        maxRedirects: this.maxredirects,
                        validateStatus: (status) => {
                            return checkStatusCode(status, this.getAcceptedStatuscodes());
                        },
                    };

                    if (bodyValue) {

Review comment (bug):
See https://stackoverflow.com/questions/16819502/application-x-www-form-urlencoded-and-charset-utf-8
=> not needed

```suggestion
                            contentType = "application/x-www-form-urlencoded";
```

Code after:
            let bean = R.dispense("heartbeat");
            bean.monitor_id = this.id;
            bean.time = R.isoDateTimeMillis(dayjs.utc());
            bean.status = DOWN;
            bean.downCount = previousBeat?.downCount || 0;

            if (this.isUpsideDown()) {
                bean.status = flipStatus(bean.status);
            }

            try {
                if (await Monitor.isUnderMaintenance(this.id)) {
                    bean.msg = "Monitor under maintenance";
                    bean.status = MAINTENANCE;
                } else if (this.type === "group") {
                    const children = await Monitor.getChildren(this.id);

                    if (children.length > 0) {
                        bean.status = UP;
                        bean.msg = "All children up and running";
                        for (const child of children) {
                            if (!child.active) {
                                // Ignore inactive childs
                                continue;
                            }
                            const lastBeat = await Monitor.getPreviousHeartbeat(child.id);

                            // Only change state if the monitor is in worse conditions then the ones before
                            // lastBeat.status could be null
                            if (!lastBeat) {
                                bean.status = PENDING;
                            } else if (bean.status === UP && (lastBeat.status === PENDING || lastBeat.status === DOWN)) {
                                bean.status = lastBeat.status;
                            } else if (bean.status === PENDING && lastBeat.status === DOWN) {
                                bean.status = lastBeat.status;
                            }
                        }

                        if (bean.status !== UP) {
                            bean.msg = "Child inaccessible";
                        }
                    } else {
                        // Set status pending if group is empty
                        bean.status = PENDING;
                        bean.msg = "Group empty";
                    }

                } else if (this.type === "http" || this.type === "keyword" || this.type === "json-query") {
                    // Do not do any queries/high loading things before the "bean.ping"
                    let startTime = dayjs().valueOf();