diff options
Diffstat (limited to 'src/gmrequest.c')
-rw-r--r-- | src/gmrequest.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/src/gmrequest.c b/src/gmrequest.c index b51d3b1f..572e6a5c 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c | |||
@@ -25,6 +25,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
25 | #include "gmcerts.h" | 25 | #include "gmcerts.h" |
26 | #include "gopher.h" | 26 | #include "gopher.h" |
27 | #include "app.h" /* dataDir_App() */ | 27 | #include "app.h" /* dataDir_App() */ |
28 | #include "mimehooks.h" | ||
28 | #include "feeds.h" | 29 | #include "feeds.h" |
29 | #include "ui/text.h" | 30 | #include "ui/text.h" |
30 | #include "embedded.h" | 31 | #include "embedded.h" |
@@ -131,7 +132,8 @@ struct Impl_GmRequest { | |||
131 | iTlsRequest * req; | 132 | iTlsRequest * req; |
132 | iGopher gopher; | 133 | iGopher gopher; |
133 | iGmResponse * resp; | 134 | iGmResponse * resp; |
134 | iBool respLocked; | 135 | iBool isRespLocked; |
136 | iBool isRespFiltered; | ||
135 | iAtomicInt allowUpdate; | 137 | iAtomicInt allowUpdate; |
136 | iAudience * updated; | 138 | iAudience * updated; |
137 | iAudience * finished; | 139 | iAudience * finished; |
@@ -164,13 +166,10 @@ static void checkServerCertificate_GmRequest_(iGmRequest *d) { | |||
164 | } | 166 | } |
165 | } | 167 | } |
166 | 168 | ||
167 | static void readIncoming_GmRequest_(iGmRequest *d, iTlsRequest *req) { | 169 | static int processIncomingData_GmRequest_(iGmRequest *d, const iBlock *data) { |
168 | iBool notifyUpdate = iFalse; | 170 | iBool notifyUpdate = iFalse; |
169 | iBool notifyDone = iFalse; | 171 | iBool notifyDone = iFalse; |
170 | lock_Mutex(d->mtx); | 172 | iGmResponse *resp = d->resp; |
171 | iGmResponse *resp =d->resp; | ||
172 | iAssert(d->state != finished_GmRequestState); /* notifications out of order? */ | ||
173 | iBlock *data = readAll_TlsRequest(req); | ||
174 | if (d->state == receivingHeader_GmRequestState) { | 173 | if (d->state == receivingHeader_GmRequestState) { |
175 | appendCStrN_String(&resp->meta, constData_Block(data), size_Block(data)); | 174 | appendCStrN_String(&resp->meta, constData_Block(data), size_Block(data)); |
176 | /* Check if the header line is complete. */ | 175 | /* Check if the header line is complete. */ |
@@ -208,6 +207,9 @@ static void readIncoming_GmRequest_(iGmRequest *d, iTlsRequest *req) { | |||
208 | resp->statusCode = code; | 207 | resp->statusCode = code; |
209 | d->state = receivingBody_GmRequestState; | 208 | d->state = receivingBody_GmRequestState; |
210 | notifyUpdate = iTrue; | 209 | notifyUpdate = iTrue; |
210 | if (willTryFilter_MimeHooks(mimeHooks_App(), &resp->meta)) { | ||
211 | d->isRespFiltered = iTrue; | ||
212 | } | ||
211 | } | 213 | } |
212 | checkServerCertificate_GmRequest_(d); | 214 | checkServerCertificate_GmRequest_(d); |
213 | iRelease(metaPattern); | 215 | iRelease(metaPattern); |
@@ -217,10 +219,21 @@ static void readIncoming_GmRequest_(iGmRequest *d, iTlsRequest *req) { | |||
217 | append_Block(&resp->body, data); | 219 | append_Block(&resp->body, data); |
218 | notifyUpdate = iTrue; | 220 | notifyUpdate = iTrue; |
219 | } | 221 | } |
222 | return (notifyUpdate ? 1 : 0) | (notifyDone ? 2 : 0); | ||
223 | } | ||
224 | |||
225 | static void readIncoming_GmRequest_(iGmRequest *d, iTlsRequest *req) { | ||
226 | lock_Mutex(d->mtx); | ||
227 | iGmResponse *resp = d->resp; | ||
228 | iAssert(d->state != finished_GmRequestState); /* notifications out of order? */ | ||
229 | iBlock * data = readAll_TlsRequest(req); | ||
230 | const int ubits = processIncomingData_GmRequest_(d, data); | ||
231 | iBool notifyUpdate = (ubits & 1) != 0; | ||
232 | iBool notifyDone = (ubits & 2) != 0; | ||
220 | initCurrent_Time(&resp->when); | 233 | initCurrent_Time(&resp->when); |
221 | delete_Block(data); | 234 | delete_Block(data); |
222 | unlock_Mutex(d->mtx); | 235 | unlock_Mutex(d->mtx); |
223 | if (notifyUpdate) { | 236 | if (notifyUpdate && !d->isRespFiltered) { |
224 | const iBool allowed = exchange_Atomic(&d->allowUpdate, iFalse); | 237 | const iBool allowed = exchange_Atomic(&d->allowUpdate, iFalse); |
225 | if (allowed) { | 238 | if (allowed) { |
226 | iNotifyAudience(d, updated, GmRequestUpdated); | 239 | iNotifyAudience(d, updated, GmRequestUpdated); |
@@ -247,7 +260,18 @@ static void requestFinished_GmRequest_(iGmRequest *d, iTlsRequest *req) { | |||
247 | set_String(&d->resp->meta, errorMessage_TlsRequest(req)); | 260 | set_String(&d->resp->meta, errorMessage_TlsRequest(req)); |
248 | } | 261 | } |
249 | checkServerCertificate_GmRequest_(d); | 262 | checkServerCertificate_GmRequest_(d); |
250 | unlock_Mutex(d->mtx); | 263 | /* Check for mimehooks. */ |
264 | if (d->isRespFiltered && d->state == finished_GmRequestState) { | ||
265 | iBlock *xbody = tryFilter_MimeHooks(mimeHooks_App(), &d->resp->meta, &d->resp->body); | ||
266 | if (xbody) { | ||
267 | clear_String(&d->resp->meta); | ||
268 | clear_Block(&d->resp->body); | ||
269 | d->state = receivingHeader_GmRequestState; | ||
270 | processIncomingData_GmRequest_(d, xbody); | ||
271 | d->state = finished_GmRequestState; | ||
272 | } | ||
273 | } | ||
274 | unlock_Mutex(d->mtx); | ||
251 | iNotifyAudience(d, finished, GmRequestFinished); | 275 | iNotifyAudience(d, finished, GmRequestFinished); |
252 | } | 276 | } |
253 | 277 | ||
@@ -425,7 +449,8 @@ static void beginGopherConnection_GmRequest_(iGmRequest *d, const iString *host, | |||
425 | void init_GmRequest(iGmRequest *d, iGmCerts *certs) { | 449 | void init_GmRequest(iGmRequest *d, iGmCerts *certs) { |
426 | d->mtx = new_Mutex(); | 450 | d->mtx = new_Mutex(); |
427 | d->resp = new_GmResponse(); | 451 | d->resp = new_GmResponse(); |
428 | d->respLocked = iFalse; | 452 | d->isRespLocked = iFalse; |
453 | d->isRespFiltered = iFalse; | ||
429 | set_Atomic(&d->allowUpdate, iTrue); | 454 | set_Atomic(&d->allowUpdate, iTrue); |
430 | init_String(&d->url); | 455 | init_String(&d->url); |
431 | init_Gopher(&d->gopher); | 456 | init_Gopher(&d->gopher); |
@@ -623,16 +648,16 @@ void cancel_GmRequest(iGmRequest *d) { | |||
623 | } | 648 | } |
624 | 649 | ||
625 | iGmResponse *lockResponse_GmRequest(iGmRequest *d) { | 650 | iGmResponse *lockResponse_GmRequest(iGmRequest *d) { |
626 | iAssert(!d->respLocked); | 651 | iAssert(!d->isRespLocked); |
627 | lock_Mutex(d->mtx); | 652 | lock_Mutex(d->mtx); |
628 | d->respLocked = iTrue; | 653 | d->isRespLocked = iTrue; |
629 | return d->resp; | 654 | return d->resp; |
630 | } | 655 | } |
631 | 656 | ||
632 | void unlockResponse_GmRequest(iGmRequest *d) { | 657 | void unlockResponse_GmRequest(iGmRequest *d) { |
633 | if (d) { | 658 | if (d) { |
634 | iAssert(d->respLocked); | 659 | iAssert(d->isRespLocked); |
635 | d->respLocked = iFalse; | 660 | d->isRespLocked = iFalse; |
636 | set_Atomic(&d->allowUpdate, iTrue); | 661 | set_Atomic(&d->allowUpdate, iTrue); |
637 | unlock_Mutex(d->mtx); | 662 | unlock_Mutex(d->mtx); |
638 | } | 663 | } |