Connection *Connection_create(Server *srv, int fd, int rport, const char *remote, SSL_CTX *ssl_ctx) { Connection *conn = h_calloc(sizeof(Connection), 1); check_mem(conn); conn->server = srv; conn->rport = rport; memcpy(conn->remote, remote, IPADDR_SIZE); conn->remote[IPADDR_SIZE] = '\0'; conn->type = 0; conn->req = Request_create(); check_mem(conn->req); if(ssl_ctx != NULL) { conn->iob = IOBuf_create(BUFFER_SIZE, fd, IOBUF_SSL); check(conn->iob != NULL, "Failed to create the SSL IOBuf."); conn->iob->ssl = ssl_server_new(ssl_ctx, IOBuf_fd(conn->iob)); check(conn->iob->ssl != NULL, "Failed to create new ssl for connection"); } else { conn->iob = IOBuf_create(BUFFER_SIZE, fd, IOBUF_SOCKET); } return conn; error: Connection_destroy(conn); return NULL; }
int connection_http_to_proxy(Connection *conn) { Proxy *proxy = Request_get_action(conn->req, proxy); check(proxy != NULL, "Should have a proxy backend."); int proxy_fd = netdial(1, bdata(proxy->server), proxy->port); check(proxy_fd != -1, "Failed to connect to proxy backend %s:%d", bdata(proxy->server), proxy->port); if(!conn->proxy_iob) { conn->proxy_iob = IOBuf_create(BUFFER_SIZE, proxy_fd, IOBUF_SOCKET); check_mem(conn->proxy_iob); } if(!conn->client) { conn->client = h_calloc(sizeof(httpclient_parser), 1); check_mem(conn->client); hattach(conn->client, conn); } return CONNECT; error: return FAILED; }
Connection *Connection_create(Server *srv, int fd, int rport, const char *remote) { Connection *conn = calloc(sizeof(Connection),1); check_mem(conn); conn->req = Request_create(); conn->proxy_iob = NULL; conn->rport = rport; conn->client = NULL; conn->close = 0; conn->type = 0; conn->filter_state = NULL; memcpy(conn->remote, remote, IPADDR_SIZE); conn->remote[IPADDR_SIZE] = '\0'; conn->handler = NULL; check_mem(conn->req); if(srv != NULL && srv->use_ssl) { conn->iob = IOBuf_create(BUFFER_SIZE, fd, IOBUF_SSL); check(conn->iob != NULL, "Failed to create the SSL IOBuf."); ssl_set_own_cert(&conn->iob->ssl, &srv->own_cert, &srv->rsa_key); ssl_set_dh_param(&conn->iob->ssl, srv->dhm_P, srv->dhm_G); ssl_set_ciphersuites(&conn->iob->ssl, srv->ciphers); } else { conn->iob = IOBuf_create(BUFFER_SIZE, fd, IOBUF_SOCKET); } return conn; error: Connection_destroy(conn); return NULL; }
Connection *fake_conn(const char *file, int mode) { Connection *conn = calloc(sizeof(Connection), 1); assert(conn && "Failed to create connection."); int fd = open(file, mode); assert(fd != -1 && "Failed to open file."); conn->iob = IOBuf_create(10 * 1024, fd, IOBUF_FILE); assert(conn->iob && "Failed to create iobuffer."); conn->type = CONN_TYPE_HTTP; Register_connect(fd, conn); return conn; }
char *test_Dir_serve_file() { int rc = 0; Request *req = NULL; Dir *test = Dir_create( bfromcstr("tests/"), bfromcstr("sample.html"), bfromcstr("test/plain"), 0); Connection conn = {.iob = NULL}; int zero_fd = open("/dev/null", O_WRONLY); conn.iob = IOBuf_create(1024, zero_fd, IOBUF_NULL); req = fake_req("GET", "/", "/sample.json"); rc = Dir_serve_file(test, req, &conn); // TODO: different platforms barf on sendfile for different reasons // mu_assert(req->response_size > -1, "Should serve the /sample.json"); req = fake_req("HEAD", "/", "/sample.json"); rc = Dir_serve_file(test, req, &conn); mu_assert(rc == 0, "Should serve the HEAD of /sample.json"); req = fake_req("POST", "/", "/sample.json"); rc = Dir_serve_file(test, req, &conn); mu_assert(rc == -1, "POST should pass through but send an error."); mu_assert(req->status_code == 405, "POST to file should 405."); req = fake_req("GET", "/tests/", "/test"); rc = Dir_serve_file(test, req, &conn); mu_assert(rc == -1, "GET of path shorter than prefix should 404"); mu_assert(req->status_code == 404, "GET shortpath should 404."); return NULL; }