/* Reads a request, sends a large response, reads a request, then * sends a little response. */ static int serve_large_response(ne_socket *sock, void *ud) { int n = 0; char empty[8192]; CALL(discard_request(sock)); SEND_STRING(sock, "HTTP/1.1 200 OK\r\n" "Content-Length: " RESPSTR "\r\n" "Server: BigFileServerTM\r\n" "\r\n"); memset(empty, 0, sizeof empty); for (n = 0; n < RESPSIZE/sizeof(empty); n++) { if (ne_sock_fullwrite(sock, empty, sizeof empty)) { NE_DEBUG(NE_DBG_SOCKET, "fullwrite failed\n"); return 1; } } NE_DEBUG(NE_DBG_SOCKET, "Wrote %d lots of %d\n", n, (int)sizeof empty); CALL(discard_request(sock)); SEND_STRING(sock, "HTTP/1.1 200 OK\r\n" "Connection: close\r\n\r\n"); return 0; }
static int serve_response(ne_socket *s, const char *response) { CALL(discard_request(s)); CALL(discard_body(s)); ONN("failed to send response", SEND_STRING(s, response)); return OK; }
int serve_infinite(ne_socket *sock, void *ud) { struct infinite *i = ud; CALL(discard_request(sock)); SEND_STRING(sock, i->header); while (server_send(sock, i->repeat, strlen(i->repeat)) == 0) /* nullop */; return OK; }
int double_serve_sstring(ne_socket *s, void *userdata) { struct double_serve_args *args = userdata; struct string *str; CALL(discard_request(s)); CALL(discard_body(s)); str = &args->first; NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n", (int)str->len, str->data); ONN("write failed", ne_sock_fullwrite(s, str->data, str->len)); CALL(discard_request(s)); CALL(discard_body(s)); str = &args->second; NE_DEBUG(NE_DBG_SOCKET, "Serving string: [[[%.*s]]]\n", (int)str->len, str->data); ONN("write failed", ne_sock_fullwrite(s, str->data, str->len)); return OK; }
static int serve_redir(ne_socket *sock, void *ud) { struct redir_args *args = ud; char buf[BUFSIZ]; CALL(discard_request(sock)); ne_snprintf(buf, BUFSIZ, "HTTP/1.0 %d Get Ye Away\r\n" "Content-Length: 0\r\n" "Location: %s\r\n\n", args->code, args->dest); SEND_STRING(sock, buf); return OK; }
/* server function which checks that the request body sent was the * same as the 'data' array. */ static int serve_check_body(ne_socket *sock, void *userdata) { CALL(discard_request(sock)); if (clength != (ssize_t)strlen(data)) { CALL(discard_body(sock)); SEND_STRING(sock, "HTTP/1.0 400 Bad Request Body Length\r\n" "\r\n"); } else { char buf[20]; if (ne_sock_fullread(sock, buf, clength) == 0) { SEND_STRING(sock, "HTTP/1.0 200 OK Then!\r\n\r\n"); } } return 0; }
int serve_file(ne_socket *sock, void *ud) { char buffer[BUFSIZ]; struct stat st; struct serve_file_args *args = ud; ssize_t ret; int fd; CALL(discard_request(sock)); ne_sock_fullread(sock, buffer, clength); fd = open(args->fname, O_RDONLY); if (fd < 0) { SEND_STRING(sock, "HTTP/1.0 404 File Not Found\r\n" "Content-Length: 0\r\n\r\n"); return 0; } ONN("fstat fd", fstat(fd, &st)); SEND_STRING(sock, "HTTP/1.0 200 OK\r\n"); if (args->chunks) { sprintf(buffer, "Transfer-Encoding: chunked\r\n"); } else { sprintf(buffer, "Content-Length: %" NE_FMT_OFF_T "\r\n", st.st_size); } if (args->headers) { strcat(buffer, args->headers); } strcat(buffer, "\r\n"); SEND_STRING(sock, buffer); NE_DEBUG(NE_DBG_HTTP, "Serving %s (%" NE_FMT_OFF_T " bytes).\n", args->fname, st.st_size); if (args->chunks) { char buf[1024]; while ((ret = read(fd, &buf, args->chunks)) > 0) { /* this is a small integer, cast it explicitly to avoid * warnings with printing an ssize_t. */ sprintf(buffer, "%x\r\n", (unsigned int)ret); SEND_STRING(sock, buffer); ONN("writing body", ne_sock_fullwrite(sock, buf, ret)); SEND_STRING(sock, "\r\n"); } SEND_STRING(sock, "0\r\n\r\n"); } else { while ((ret = read(fd, buffer, BUFSIZ)) > 0) { ONN("writing body", ne_sock_fullwrite(sock, buffer, ret)); } } ONN("error reading from file", ret < 0); (void) close(fd); return OK; }