summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/IO/IO.c7
-rw-r--r--src/IO/http.c11
-rw-r--r--src/cache.c52
-rw-r--r--src/cache.h4
-rw-r--r--src/capi.c6
5 files changed, 52 insertions, 28 deletions
diff --git a/src/IO/IO.c b/src/IO/IO.c
index 139cf667..4312fddb 100644
--- a/src/IO/IO.c
+++ b/src/IO/IO.c
@@ -285,6 +285,10 @@ static void IO_fd_read_cb(int fd, void *data)
} else {
if (IO_callback(io) == 0)
a_IOwatch_remove_fd(fd, DIO_READ);
+ if ((io = IO_get(io_key)) && io->Status) {
+ /* check io because IO_read OpSend could trigger abort */
+ a_IO_ccc(OpAbort, 2, FWD, io->Info, io, NULL);
+ }
}
}
@@ -443,7 +447,8 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info,
dFree(dbuf);
break;
case OpEnd:
- a_Chain_fcb(OpEnd, Info, NULL, NULL);
+ case OpAbort:
+ a_Chain_fcb(Op, Info, NULL, NULL);
IO_close_fd(io, IO_StopRdWr); /* IO_StopRd would leak FDs */
IO_free(io);
dFree(Info);
diff --git a/src/IO/http.c b/src/IO/http.c
index 379d51c1..15cd173c 100644
--- a/src/IO/http.c
+++ b/src/IO/http.c
@@ -911,6 +911,17 @@ void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info,
}
dFree(Info);
break;
+ case OpAbort:
+ if (sd->https_proxy_reply) {
+ MSG("CONNECT through proxy failed. "
+ "Full reply not received:\n%s\n",
+ sd->https_proxy_reply->len ? sd->https_proxy_reply->str :
+ "(nothing)");
+ }
+ Http_socket_free(SKey);
+ a_Chain_fcb(OpAbort, Info, NULL, "Both");
+ dFree(Info);
+ break;
default:
MSG_WARN("Unused CCC 2F Op %d\n", Op);
break;
diff --git a/src/cache.c b/src/cache.c
index ec3a04bd..3929ca33 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -206,7 +206,7 @@ static void Cache_entry_init(CacheEntry_t *NewEntry, const DilloUrl *Url)
NewEntry->CharsetDecoder = NULL;
NewEntry->ExpectedSize = 0;
NewEntry->TransferSize = 0;
- NewEntry->Flags = CA_IsEmpty | CA_KeepAlive;
+ NewEntry->Flags = CA_IsEmpty | CA_InProgress | CA_KeepAlive;
}
/*
@@ -270,7 +270,7 @@ static void Cache_entry_inject(const DilloUrl *Url, Dstr *data_ds)
if (!(entry = Cache_entry_search(Url)))
entry = Cache_entry_add(Url);
- entry->Flags |= CA_GotData + CA_GotHeader + CA_GotLength + CA_InternalUrl;
+ entry->Flags |= CA_GotHeader + CA_GotLength + CA_InternalUrl;
if (data_ds->len)
entry->Flags &= ~CA_IsEmpty;
dStr_truncate(entry->Data, 0);
@@ -847,7 +847,7 @@ static int Cache_get_header(CacheEntry_t *entry,
static void Cache_finish_msg(CacheEntry_t *entry)
{
- if (entry->Flags & CA_GotData) {
+ if (!(entry->Flags & CA_InProgress)) {
/* already finished */
return;
}
@@ -858,13 +858,10 @@ static void Cache_finish_msg(CacheEntry_t *entry)
}
if ((entry->Flags & CA_GotLength) &&
(entry->ExpectedSize != entry->TransferSize)) {
- MSG_HTTP("Content-Length does NOT match message body at\n"
- "%s\n", URL_STR_(entry->Url));
- MSG("Expected size: %d, Transfer size: %d\n",
- entry->ExpectedSize, entry->TransferSize);
+ MSG_HTTP("Content-Length (%d) does NOT match message body (%d) for %s\n",
+ entry->ExpectedSize, entry->TransferSize, URL_STR_(entry->Url));
}
- entry->Flags |= CA_GotData;
- entry->Flags &= ~CA_Stopped; /* it may catch up! */
+ entry->Flags &= ~CA_InProgress;
if (entry->TransferDecoder) {
a_Decode_transfer_free(entry->TransferDecoder);
entry->TransferDecoder = NULL;
@@ -963,16 +960,22 @@ bool_t a_Cache_process_dbuf(int Op, const char *buf, size_t buf_size,
} else if (Op == IOClose) {
Cache_finish_msg(entry);
} else if (Op == IOAbort) {
- int i;
- CacheClient_t *Client;
+ entry->Flags |= CA_Aborted;
+ if (entry->Data->len) {
+ MSG("Premature close for %s\n", URL_STR(entry->Url));
+ Cache_finish_msg(entry);
+ } else {
+ int i;
+ CacheClient_t *Client;
- for (i = 0; (Client = dList_nth_data(ClientQueue, i)); ++i) {
- if (Client->Url == entry->Url) {
- DilloWeb *web = (DilloWeb *)Client->Web;
+ for (i = 0; (Client = dList_nth_data(ClientQueue, i)); ++i) {
+ if (Client->Url == entry->Url) {
+ DilloWeb *web = (DilloWeb *)Client->Web;
- a_Bw_remove_client(web->bw, Client->Key);
- Cache_client_dequeue(Client);
- --i; /* Keep the index value in the next iteration */
+ a_Bw_remove_client(web->bw, Client->Key);
+ Cache_client_dequeue(Client);
+ --i; /* Keep the index value in the next iteration */
+ }
}
}
}
@@ -1184,7 +1187,7 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
st = a_Misc_get_content_type_from_data(
entry->Data->str, entry->Data->len, &Type);
_MSG("Cache: detected Content-Type '%s'\n", Type);
- if (st == 0 || entry->Flags & CA_GotData) {
+ if (st == 0 || !(entry->Flags & CA_InProgress)) {
if (a_Misc_content_type_check(entry->TypeHdr, Type) < 0) {
MSG_HTTP("Content-Type '%s' doesn't match the real data.\n",
entry->TypeHdr);
@@ -1289,7 +1292,7 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
}
/* Remove client when done */
- if (entry->Flags & CA_GotData) {
+ if (!(entry->Flags & CA_InProgress)) {
/* Copy flags to a local var */
int flags = ClientWeb->flags;
@@ -1299,12 +1302,17 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
}
/* We finished sending data, let the client know */
(Client->Callback)(CA_Close, Client);
- if (ClientWeb->flags & WEB_RootUrl)
+ if (ClientWeb->flags & WEB_RootUrl) {
+ if (entry->Flags & CA_Aborted) {
+ a_UIcmd_set_msg(Client_bw, "ERROR: Connection closed early, "
+ "read not complete.");
+ }
a_UIcmd_set_page_prog(Client_bw, 0, 0);
+ }
Cache_client_dequeue(Client);
--i; /* Keep the index value in the next iteration */
- /* within CA_GotData, we assert just one redirect call */
+ /* we assert just one redirect call */
if (entry->Flags & CA_Redirect)
Cache_redirect(entry, flags, Client_bw);
}
@@ -1327,7 +1335,7 @@ static CacheEntry_t *Cache_process_queue(CacheEntry_t *entry)
}
}
a_Url_free(url);
- } else if (entry->Auth && (entry->Flags & CA_GotData)) {
+ } else if (entry->Auth && !(entry->Flags & CA_InProgress)) {
Cache_auth_entry(entry, Client_bw);
}
diff --git a/src/cache.h b/src/cache.h
index f3b064f2..833e4394 100644
--- a/src/cache.h
+++ b/src/cache.h
@@ -22,12 +22,12 @@ extern "C" {
#define CA_GotHeader 0x1 /* True after header is completely got */
#define CA_GotContentType 0x2 /* True after Content-Type is known */
#define CA_GotLength 0x4 /* True if Content-Length is known */
-#define CA_GotData 0x8 /* True if we have all Data in cache */
+#define CA_InProgress 0x8 /* True if we are getting data */
#define CA_Redirect 0x10 /* Data actually points to a redirect */
#define CA_ForceRedirect 0x20 /* Unconditional redirect */
#define CA_TempRedirect 0x40 /* Temporary redirect */
#define CA_NotFound 0x80 /* True if remote server didn't find the URL */
-#define CA_Stopped 0x100 /* True if the entry has been stopped */
+#define CA_Aborted 0x100 /* Aborted before getting full data */
#define CA_MsgErased 0x200 /* Used to erase the bw's status bar */
#define CA_RedirectLoop 0x400 /* Redirect loop */
#define CA_InternalUrl 0x800 /* URL content is generated by dillo */
diff --git a/src/capi.c b/src/capi.c
index 0e561b77..43fd8a16 100644
--- a/src/capi.c
+++ b/src/capi.c
@@ -502,10 +502,10 @@ static int Capi_map_cache_flags(uint_t flags)
status |= CAPI_IsCached;
if (flags & CA_IsEmpty)
status |= CAPI_IsEmpty;
- if (flags & CA_GotData)
- status |= CAPI_Completed;
- else
+ if (flags & CA_InProgress)
status |= CAPI_InProgress;
+ else
+ status |= CAPI_Completed;
/* CAPI_Aborted is not yet used/defined */
}