-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathproxy.py
More file actions
68 lines (64 loc) · 2.63 KB
/
proxy.py
File metadata and controls
68 lines (64 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""Proxy logic."""
import copy
from embedUI import embedUI
from datastores import feed_db
from feed2XML import feed2XML
import feedcache
from flask import request, redirect
import logging as log
from ml import score_feed
from werkzeug.http import is_hop_by_hop_header
def proxy(url):
log.info("Processing %s?%s", url, request.query_string)
query_string = request.query_string.decode()
if request.method == "GET":
try:
parsed_feed = feedcache.Cache(feed_db()).fetch(
"?".join(filter(None, [url, query_string])), force_update=False
) # defaults: force_update = False, offline = False
# return content
finally:
feed_db().sync()
status = parsed_feed.get("status", 404)
if status >= 400: # deal with errors
response = ("External error", status, {})
elif status >= 300: # deal with redirects
if status == 301:
log.warn("Permanent redirect from %s to %s", url, parsed_feed.href)
return redirect("/feed/{reurl}".format(reurl=parsed_feed.href))
else:
etag = request.headers.get("IF_NONE_MATCH")
modified = request.headers.get("IF_MODIFIED_SINCE")
if False:
pass
if (etag and etag == parsed_feed.get("etag")) or (
modified and modified == parsed_feed.get("modified")
):
response = ("", 304, {})
else:
if not parsed_feed["bozo"]:
parsed_feed = copy.deepcopy(
parsed_feed
) # if it's bozo copy fails and copy is not cached,
# so we skip
# deepcopy needed to avoid side effects on cache
response = (_process(parsed_feed), 200, {})
if "headers" in parsed_feed: # some header rinsing
for k, v in parsed_feed.headers.items():
# TODO: seems to work with all the hop by hop headers unset
# or to default values, need to look into this
k = k.lower()
if (
not is_hop_by_hop_header(k)
and k != "content-length"
and k != "content-encoding"
and k != ""
):
# let django deal with these headers
response[2][k] = v
return response
else:
return ("POST not allowed for feeds", 405, {})
def _process(parsed_feed):
score = score_feed(parsed_feed) if (len(parsed_feed.entries) > 0) else []
return feed2XML(embedUI(parsed_feed, score))