--- src/ne_basic.c 2020-05-15 13:07:40.646410787 +0200 +++ src/ne_basic.c.new 2020-05-19 09:56:17.761164071 +0200 @@ -107,7 +107,7 @@ ne_lock_using_parent(req, uri); #endif - ne_set_request_body_fd(req, fd, 0, st.st_size); + ne_set_request_body_fd(req, fd, 0, st.st_size, NULL); ret = ne_request_dispatch(req); --- src/ne_request.c 2020-05-15 13:07:40.646410787 +0200 +++ src/ne_request.c.new 2020-05-19 10:19:41.612890009 +0200 @@ -42,6 +42,10 @@ #include #endif +#include //AVM +#include +#include + #include "ne_internal.h" #include "ne_alloc.h" @@ -101,6 +105,7 @@ int fd; ne_off_t offset, length; ne_off_t remain; /* remaining bytes to send. */ + char* path; } file; struct { /* length bytes @ buffer = whole body. @@ -185,7 +190,7 @@ ne_session *sess = req->session; int ret = NE_ERROR; - NE_DEBUG(NE_DBG_HTTP, "Aborted request (%" NE_FMT_SSIZE_T "): %s\n", + NE_DEBUG(NE_DBG_AVM, "Aborted request (%" NE_FMT_SSIZE_T "): %s", code, doing); switch(code) { @@ -199,7 +204,7 @@ } break; case NE_SOCK_TIMEOUT: - ne_set_error(sess, _("%s: connection timed out"), doing); + ne_set_error(sess, _("%s: connection timed out (aborted)"), doing); ret = NE_TIMEOUT; break; case NE_SOCK_ERROR: @@ -216,11 +221,12 @@ return ret; } -static void notify_status(ne_session *sess, ne_session_status status) +static int notify_status(ne_session *sess, ne_session_status status) { if (sess->notify_cb) { - sess->notify_cb(sess->notify_ud, status, &sess->status); + return sess->notify_cb(sess->notify_ud, status, &sess->status); } + return 0; } static void *get_private(const struct hook *hk, const char *id) @@ -394,16 +400,24 @@ } req->session->status.sr.progress = 0; - notify_status(sess, ne_status_sending); + req->session->status.sr.duration = 0; + req->session->status.sr.current = 0; + + if(notify_status(sess, ne_status_sending)){ + NE_DEBUG(NE_DBG_AVM, "Send request body: notify abort"); + ne_close_connection(sess); + return NE_ERROR; + } /* tell the source to start again from the beginning. */ if (req->body_cb(req->body_ud, NULL, 0) != 0) { + NE_DEBUG(NE_DBG_AVM, "Send request body: must start again"); ne_close_connection(sess); return NE_ERROR; } while ((bytes = req->body_cb(req->body_ud, start, buflen)) > 0) { - req->session->status.sr.progress += bytes; + req->session->status.sr.current = bytes; if (chunked) { /* Overwrite the buffer prefix with the appropriate chunk * size; since ne_snprintf always NUL-terminates, the \n @@ -417,9 +431,13 @@ buffer[CHUNK_OFFSET - 1] = '\n'; bytes += CHUNK_OFFSET; } + //AVM + struct timeval start_time; + gettimeofday(&start_time, NULL); ret = ne_sock_fullwrite(sess->socket, buffer, bytes); if (ret < 0) { + NE_DEBUG(NE_DBG_AVM, "Sending request body failed"); int aret = aborted(req, _("Could not send request body"), ret); return RETRY_RET(retry, ret, aret); } @@ -429,11 +447,34 @@ bytes, (int)bytes, buffer); /* invoke progress callback */ - notify_status(sess, ne_status_sending); + struct timeval end_time; + gettimeofday(&end_time, NULL); + req->session->status.sr.duration = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec); + if(notify_status(sess, ne_status_sending)){ + NE_DEBUG(NE_DBG_AVM, "Send request body: notify abort"); + ne_close_connection(sess); + return NE_ERROR; + } + //-AVM +#ifdef NE_LFS +#define ne_stat stat64 +typedef struct stat64 struct_stat; +#else +#define ne_stat stat +typedef struct stat struct_stat; +#endif + struct_stat st; + if (req->body.file.fd>0 && req->body.file.path && ne_stat(req->body.file.path, &st)) { + /* Abort upload, if file is removed in the meantime */ + NE_DEBUG(NE_DBG_AVM, "Send request body: upload aborted, input file is lost"); + ne_close_connection(sess); + return NE_ERROR; + } + //AVM- } if (bytes) { - NE_DEBUG(NE_DBG_HTTP, "Request body provider failed with " + NE_DEBUG(NE_DBG_AVM, "Request body provider failed with " "%" NE_FMT_SSIZE_T "\n", bytes); ne_close_connection(sess); return NE_ERROR; @@ -452,7 +493,7 @@ return RETRY_RET(retry, ret, aret); } } - + NE_DEBUG(NE_DBG_HTTP, "Request body completely sended"); return NE_OK; } @@ -539,6 +580,7 @@ fn(req, hk->userdata, req->method, req->uri); } } + req->body.file.path = NULL; return req; } @@ -574,10 +616,11 @@ } void ne_set_request_body_fd(ne_request *req, int fd, - ne_off_t offset, ne_off_t length) + ne_off_t offset, ne_off_t length, const char* path) { req->body.file.fd = fd; req->body.file.offset = offset; + req->body.file.path = path ? ne_strdup(path) : NULL; req->body.file.length = length; req->body_cb = body_fd_send; req->body_ud = req; @@ -751,6 +794,9 @@ if (req->status.reason_phrase) ne_free(req->status.reason_phrase); + if (req->body.file.path) + ne_free(req->body.file.path); + NE_DEBUG(NE_DBG_HTTP, "Request ends.\n"); ne_free(req); } @@ -860,16 +906,27 @@ size_t readlen = buflen; struct ne_response *const resp = &req->resp; + //AVM + req->session->status.sr.duration = 0; + req->session->status.sr.current = 0; + struct timeval start_time; + gettimeofday(&start_time, NULL); + if (read_response_block(req, resp, buffer, &readlen)) return -1; if (readlen) { + struct timeval end_time; + gettimeofday(&end_time, NULL); + req->session->status.sr.duration = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec); + req->session->status.sr.current = readlen; req->session->status.sr.progress += readlen; notify_status(req->session, ne_status_recving); } for (rdr = req->body_readers; rdr!=NULL; rdr=rdr->next) { if (rdr->use && rdr->handler(rdr->userdata, buffer, readlen) != 0) { + NE_DEBUG(NE_DBG_AVM, "req: Closing connection for non-idempotent request.\n"); ne_close_connection(req->session); return -1; } @@ -1244,7 +1301,7 @@ * do that. */ if (!req->flags[NE_REQFLAG_IDEMPOTENT] && req->session->persisted && !req->session->flags[NE_SESSFLAG_CONNAUTH]) { - NE_DEBUG(NE_DBG_HTTP, "req: Closing connection for non-idempotent " + NE_DEBUG(NE_DBG_AVM, "req: Closing connection for non-idempotent " "request.\n"); ne_close_connection(req->session); } @@ -1255,7 +1312,7 @@ ret = send_request(req, data); /* Retry this once after a persistent connection timeout. */ if (ret == NE_RETRY) { - NE_DEBUG(NE_DBG_HTTP, "Persistent connection timed out, retrying.\n"); + NE_DEBUG(NE_DBG_AVM, "Persistent connection timed out, retrying.\n"); ret = send_request(req, data); } ne_buffer_destroy(data); @@ -1382,6 +1439,8 @@ } req->session->status.sr.progress = 0; + req->session->status.sr.duration = 0; + req->session->status.sr.current = 0; req->session->status.sr.total = req->resp.mode == R_CLENGTH ? req->resp.body.clen.total : -1; notify_status(req->session, ne_status_recving); @@ -1411,8 +1470,10 @@ /* Close the connection if persistent connections are disabled or * not supported by the server. */ - if (!req->session->flags[NE_SESSFLAG_PERSIST] || !req->can_persist) - ne_close_connection(req->session); + if (!req->session->flags[NE_SESSFLAG_PERSIST] || !req->can_persist) { + NE_DEBUG(NE_DBG_AVM, "End Request: close connection"); + ne_close_connection(req->session); + } else req->session->persisted = 1; @@ -1566,9 +1627,9 @@ sess->status.ci.address = host->current; notify_status(sess, ne_status_connecting); #ifdef NE_DEBUGGING - if (ne_debug_mask & NE_DBG_HTTP) { + if (ne_debug_mask & NE_DBG_AVM) { char buf[150]; - NE_DEBUG(NE_DBG_HTTP, "req: Connecting to %s:%u\n", + NE_DEBUG(NE_DBG_AVM, "req: Connecting to %s:%u\n", ne_iaddr_print(host->current, buf, sizeof buf), host->port); } @@ -1578,6 +1639,7 @@ (host->current = resolve_next(host)) != NULL); if (ret) { + NE_DEBUG(NE_DBG_AVM, "Connecting failed: %s\n", ne_sock_error(sess->socket)); const char *msg; if (host->proxy == PROXY_NONE) @@ -1595,6 +1657,7 @@ notify_status(sess, ne_status_connected); sess->nexthop = host; + NE_DEBUG(NE_DBG_AVM, "Connected"); sess->connected = 1; /* clear persistent connection flag. */ @@ -1714,8 +1777,10 @@ if (ret == NE_OK) { ret = ne__negotiate_ssl(sess); - if (ret != NE_OK) + if (ret != NE_OK) { + NE_DEBUG(NE_DBG_AVM, "Opening Connection: Negotiate SSL failed"); ne_close_connection(sess); + } } } #endif --- src/ne_request.h 2020-05-15 13:07:40.646410787 +0200 +++ src/ne_request.h.new 2020-05-19 10:20:23.356883863 +0200 @@ -59,8 +59,7 @@ /* The request body will be taken from 'length' bytes read from the * file descriptor 'fd', starting from file offset 'offset'. */ void ne_set_request_body_fd(ne_request *req, int fd, - ne_off_t offset, ne_off_t length) - ne_attribute((nonnull)); + ne_off_t offset, ne_off_t length, const char* path); /* "Pull"-based request body provider: a callback which is invoked to * provide blocks of request body on demand.