/* Pass invalid file descriptor to sw_close. */ static void close_invalid_descriptor(void) { int rc; rc = sw_close(-1); test(rc < 0 && errno == EBADF); }
//------------------------------------------------------------------------- void destroyServer(HTTPServer *server) { if (!server) return; if (server->lst) { sw_close(server->lst); server->lst = NULL; } if (server->thread) pthread_join(server->thread, NULL); if (server->dw) server->dw->destroy(); free(server); return; }
/* Pass a non-bound socket. */ static void close_ok_descriptor_is_not_bound(void) { int s; int rc; s = sw_socket(PF_INET, SOCK_DGRAM, IPPROTO_SWIFT); DIE(s < 0, "sw_socket"); rc = sw_close(s); test(rc == 0); }
/* Pass a duplicate of standard output to sw_close. */ static void close_descriptor_is_not_a_socket(void) { int fd; int rc; fd = dup(STDOUT_FILENO); DIE(fd < 0, "dup"); rc = sw_close(fd); test(rc < 0 && errno == EBADF); close(fd); }
//------------------------------------------------------------------------- HTTPServer* createServer(const char *device, std::vector<FMFileInfo> fileList) { fprintf(stderr, "createServer device: %s\n", (device ? device : "null")); if (!device) return NULL; //---------------- IFileAccess *dw = IFileAccess::createCached(IFileAccess::createCSS(device, fileList)); fprintf(stderr, "createServer IFileAccess: %p\n", dw); if (!dw) return NULL; //---------------- sw_socket *lst; int port = gListeningPort; int tryCount = 100; while(tryCount > 0) { lst = sw_listen(port); if (lst) break; port++; tryCount--; } fprintf(stderr, "createServer socket: %p\n", lst); if (!lst) { fprintf(stderr, "No available ports...\n"); dw->destroy(); return NULL; } //---------------- HTTPServer *server = (HTTPServer *) malloc( sizeof(HTTPServer) ); fprintf(stderr, "createServer server: %p\n", server); if (!server) { sw_close(lst); dw->destroy(); return NULL; } server->lst = lst; server->port = port; server->dw = dw; pthread_create(&server->thread, 0, (void *(*)(void*))acceptSocket, server); return server; }
/* Pass a bound socket. */ static void close_ok_descriptor_is_bound(void) { int s; int rc; struct sockaddr_sw addr; s = sw_socket(PF_INET, SOCK_DGRAM, IPPROTO_SWIFT); DIE(s < 0, "sw_socket"); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; rc = sw_bind(s, (struct sockaddr *) &addr, sizeof(addr)); DIE(rc < 0, "sw_bind"); rc = sw_close(s); test(rc == 0); }
//------------------------------------------------------------------------- static void serveSocket(Connection *c) { sw_socket *s = c->s; IFileAccess *dw = c->dw; free(c); byte *header; char url[1024]; int length, method; bool hasRange; int64 rangeStart, rangeLength; header = (byte*) malloc(gBufferSize); while(1) { // printf("==== Waiting for request...\n"); // get the request length = getHeader(s, header, gBufferSize - 1); if (length <= 0) break; header[length] = 0; // check kind of request method = getMethod(header); if (method != METHOD_HEAD && method != METHOD_GET) { sendError(s, ERR_BAD_METHOD); continue; } // get url, host and port parseRequest((char*)header, url, &hasRange, &rangeStart, &rangeLength); if (rangeLength > 1024*1024*256) rangeLength = 1024*1024*256; #if 0 { printf("================================================\n"); printf("header:\n%s\n", header); printf("= = = = = = = = = = = = = = = = = = = = = = = = \n"); printf("url: %s\n", url); if (hasRange) printf("range: %lld - %lld (%lld)\n", rangeStart, rangeStart + rangeLength - 1, rangeLength); printf("\n"); } #endif const char *path = "/dvd.iso"; if (strcmp(url, path) != 0) { sendError(s, ERR_NOT_FOUND); continue; } int64 fileSize = dw->size(); int64 requestSize = (hasRange) ? rangeLength : fileSize; byte *data = NULL; if (method == METHOD_GET) { data = dw->lock(rangeStart, requestSize); if (!data) { fprintf(stderr, "Data read error\n"); sendError(s, ERR_NOT_FOUND); continue; } } sendHead(s, path, fileSize, hasRange, rangeStart, rangeLength); if (data) { sendRawToSocket(s, data, requestSize); dw->unlock(); } } sw_close(s); free(header); }