void RequestHandler::handleRequest(TCPSocket* sock) { char mtd[16]; char uri[512]; char bfr[c_max_request_size] = {0}; // Search for end of request. unsigned idx = 0; unsigned didx = 0; bool eor = false; while (!eor && (idx < (c_max_request_size - 1))) { int rv = sock->read(bfr + idx, 1); if (rv <= 0) throw ConnectionClosed(); if (didx == 0 && bfr[idx] == '\r') didx = 1; else if (didx == 1 && bfr[idx] == '\n') didx = 2; else if (didx == 2 && bfr[idx] == '\r') didx = 3; else if (didx == 3 && bfr[idx] == '\n') { eor = true; didx = 0; } else didx = 0; ++idx; } // Get header. int size = idx - 4; if (size <= 0) { DUNE_WRN("HTTP", "request too short"); return; } char* hdr = new char[size + 1]; std::memcpy(hdr, bfr, size); hdr[size] = 0; Utils::TupleList headers(hdr, ":", "\r\n", true); // Parse request line. if (std::sscanf(hdr, "%s %s %*s", mtd, uri) == 2) { std::string uri_dec = URL::decode(uri); const char* uri_clean = uri_dec.c_str(); if (std::strcmp(mtd, "GET") == 0) { handleGET(sock, headers, uri_clean); } else if (std::strcmp(mtd, "POST") == 0) { handlePOST(sock, headers, uri_clean); } else if (std::strcmp(mtd, "PUT") == 0) { handlePUT(sock, headers, uri_clean); } } delete[] hdr; }
/* * Command mode network thread routine */ int doCmdClient(session_node_t * sn) { /*TODO: Optimize memory usage; these buffers occupy 6 kB stack * memory. */ char line[MAXSRCPLINELEN]; char reply[MAXSRCPLINELEN]; char cbus[MAXSRCPLINELEN]; char command[MAXSRCPLINELEN]; char devicegroup[MAXSRCPLINELEN]; char parameter[MAXSRCPLINELEN]; bus_t bus; long int rc, nelem; struct timeval akt_time; ssize_t result; syslog_session(sn->session, DBG_INFO, "Command mode starting."); while (true) { pthread_testcancel(); memset(line, 0, sizeof(line)); result = socket_readline(sn->socket, line, sizeof(line) - 1); /* client terminated connection */ if (0 == result) { shutdown(sn->socket, SHUT_RDWR); break; } /* read errror */ if (-1 == result) { syslog_session(sn->session, DBG_ERROR, "Socket read failed: %s (errno = %d)\n", strerror(errno), errno); break; } /*remove terminating line break */ size_t linelen = strlen(line); if (linelen > 1 && (line[linelen - 1] == '\n')) line[linelen - 1] = '\0'; memset(command, 0, sizeof(command)); memset(cbus, 0, sizeof(cbus)); memset(devicegroup, 0, sizeof(devicegroup)); memset(parameter, 0, sizeof(parameter)); memset(reply, 0, sizeof(reply)); nelem = sscanf(line, "%s %s %s %1000c", command, cbus, devicegroup, parameter); bus = atoi(cbus); reply[0] = 0x00; if (nelem >= 3) { if (bus <= num_buses) { rc = SRCP_UNKNOWNCOMMAND; if (strncasecmp(command, "SET", 3) == 0) { rc = handleSET(sn->session, bus, devicegroup, parameter, reply); } else if (strncasecmp(command, "GET", 3) == 0) { rc = handleGET(sn->session, bus, devicegroup, parameter, reply, sizeof(reply)); } else if (strncasecmp(command, "WAIT", 4) == 0) { rc = handleWAIT(sn->session, bus, devicegroup, parameter, reply, sizeof(reply)); } else if (strncasecmp(command, "INIT", 4) == 0) { rc = handleINIT(sn->session, bus, devicegroup, parameter, reply); } else if (strncasecmp(command, "TERM", 4) == 0) { rc = handleTERM(sn->session, bus, devicegroup, parameter, reply); /*special option for session termination (?) */ if (rc < 0) { if (writen(sn->socket, reply, strlen(reply)) == -1) { syslog_session(sn->session, DBG_ERROR, "Socket write failed: %s (errno = %d)\n", strerror(errno), errno); break; } break; } rc = abs(rc); } else if (strncasecmp(command, "VERIFY", 6) == 0) { rc = handleVERIFY(sn->session, bus, devicegroup, parameter, reply); } else if (strncasecmp(command, "RESET", 5) == 0) { rc = handleRESET(sn->session, bus, devicegroup, parameter, reply); } } /* bus > num_buses */ else { rc = SRCP_WRONGVALUE; gettimeofday(&akt_time, NULL); srcp_fmt_msg(rc, reply, akt_time); } } /* nelem < 3 */ else { syslog_session(sn->session, DBG_DEBUG, "List too short: %d", nelem); rc = SRCP_LISTTOOSHORT; gettimeofday(&akt_time, NULL); srcp_fmt_msg(rc, reply, akt_time); } if (writen(sn->socket, reply, strlen(reply)) == -1) { syslog_session(sn->session, DBG_ERROR, "Socket write failed: %s (errno = %d)\n", strerror(errno), errno); break; } } return 0; }