My folder structure inside the app:
pwa->static->pwa->serviceworker.js
and
pwa->templates->indexPWA.html
How can I refer to the indexPWA.html inside the serviceworker.js?
var filesToCache = ["indexPWA.html"] doesn't work, cause it's not the right path, but what is the right one?
You can use the path in which you address the indexPWA.html page in the browser.
Example:
var filesToCache = ["/indexPWA.html"]
var filesToCache = ["/"]
You can check the correct path by opening indexPWA.html in the browser and check for the words which are after 127.0.0.1:8000/ in the url bar.
Related
I'm a computer science student. Recently we were tasked to develop a static HTTP server from scratch without using any HTTP modules, solely depending on socket programming. So this means that I had to write all the logic for HTTP message parsing, extracting headers, parsing URLs, etc.
However, I'm stuck with some confusion. As I'm somewhat experienced in web development before, I'm used to using URLs in places like anchor tags like this "/about", and "/articles/article-1".However, I've seen people sometimes people to relative paths according to their folder structure like this. "./about.html", "../contact.html".This always seemed to be a bad idea to me. However, I realized that even though in my code I'm not supporting these kinds of URLs explicitly, it seems to work anyhow.
Following is the python code I'm using to get the path from the HTTP message and then get the corresponding path in the file system.
def get_http_url(self, raw_request_headers: list[str]):
"""
Method to get HTTP url by parsing request headers
"""
if len(raw_request_headers) > 0:
method_and_path_header = raw_request_headers[0]
method_and_path_header_segments = method_and_path_header.split(" ")
if len(method_and_path_header_segments) >= 2:
"""
example: GET / HTTP/1.1 => ['GET', '/', 'HTTP/1.1] => '/'
"""
url = method_and_path_header_segments[1]
return url
return False
def get_resource_path_for_url(self, path: str | Literal[False]):
"""
Method to get the resource path based on url
"""
if not path:
return False
else:
if path.endswith('/'):
# Removing trailing '/' to make it easy to parse the url
path = path[0:-1]
# Split to see if the url also includes the file extension
parts = path.split('.')
if path == '':
# if the requested path is "/"
path_to_resource = os.path.join(
os.getcwd(), "htdocs", "index.html")
else:
# Assumes the user entered a valid url with resources file extension as well, ex: http://localhost:2728/pages/about.html
if len(parts) > 1:
path_to_resource = os.path.join(
os.getcwd(), "htdocs", path[1:]) # Get the abslute path with the existing file extension
else:
# Assumes user requested a url without an extension and as such is hoping for a html response
path_to_resource = os.path.join(
os.getcwd(), "htdocs", f"{path[1:]}.html") # Get the absolute path to the corresponding html file
return path_to_resource
So in my code, I'm not explicitly adding any logic to handle that kind of relative path. But somehow, when I use things like ../about.html in my test HTML files, it somehow works?
Is this the expected behavior? As of now (I would like to know where this behavior is implemented), I'm on Windows if that matters. And if this is expected, can I depend on this behavior and conclude that it's safe to refer to HTML files and other assets with relative paths like this on my web server?
Thanks in advance for any help, and I apologize if my question is not clear or well-formed.
I'm using the Django sendfile module to serve files to the user. Docs:
https://github.com/johnsensible/django-sendfile
I used the simple backend. More precisely, I put SENDFILE_BACKEND = 'sendfile.backends.simple' in my settings.py.
I have checked and doucle-checked that the files are there. This is my code (I think only the request function is relevant but I'm including the whole function because I use pk in urls.py):
def permit(request, pk)
if int(request.user.id) == int(pk) and int(request.user.id) >= 1:
return sendfile(request, request.path)
else:
return render_to_response('forbidden.html')
return HttpResponseRedirect('/notendur/list')
user is a Django User object. pk is the regular expression taken from urls.py.
And the error I get is
404: [path to file] does not exist.
This is the relevant entry in project/urls.py:
url(r'^media/uploads/(?P<pk>[^/]+)', 'notendur.views.permit')
As you can see, the urls.py redirects the user to the permit function if the regx matches. If the user's ID is equal to the directory name (I name the directories by user ID) then the user is allowed to download the file, otherwise not.
I have confirmed that this error is due to the sendfile module because the download works fine if I serve the file directly, without the sendfile module.
Firstly a big warning, what you are doing is dangerous. You are trusting your user to give you a path. You must always sanitize this!
Now to your issue: rather than giving a relative file to the current directory, it is better practice to give an absolute file based on some root media path set in your settings file then do:
sanitized_path = sanitize(request.path) # you'll have to write a sanitize function
media_path = "%s%s" (settings.MEDIA_ROOT, sanitized_path)
if not path.exists(media_path): # Don't trust your visitors too much!
# raise 404
return sendfile(request, media_path)
I'm new to web.py, and use a lot of hardcoded url in my code for href in tag a,like
/loginor/?type=example.
The problem is,
when I set my application running under a certain path, not the root of a URL, like
http://example.com/appname/
The link will direct me to some place like
http://example.com/login
While the expected/wanted one is
http://example.com/appname/login
How do I handle this?
Make web.ctx.homepath available in your template globals, and output it before your paths.
From http://webpy.org/cookbook/ctx
homepath – The part of the path requested by the user which was
trimmed off the current app. That is homepath + path = the path
actually requested in HTTP by the user. E.g. /admin This seems to be
derived during startup from the environment variable REAL_SCRIPT_NAME.
It affects what web.url() will prepend to supplied urls. This in turn
affects where web.seeother() will go, which might interact badly with
your url rewriting scheme (e.g. mod_rewrite)
template_globals = {
'app_path': lambda p: web.ctx.homepath + p,
}
render = template.render(my_template_dir, globals=template_globals, base="mylayout")
Then you should be able to output app_path in your templates
Login
So I have successfully deployed an app using webapp2/jinja2 and a Paste server, but am having trouble serving static stylesheets.
I have had luck accessing static files via this method, as well as implementing a StaticFileHandler I found with some google-fu:
import os
import mimetypes
import webapp2
import logging
class StaticFileHandler(webapp2.RequestHandler):
def get(self, path):
abs_path = os.path.abspath(os.path.join(self.app.config.get('webapp2_static.static_file_path', 'static'), path))
if os.path.isdir(abs_path) or abs_path.find(os.getcwd()) != 0:
self.response.set_status(403)
return
try:
f = open(abs_path, 'r')
self.response.headers.add_header('Content-Type', mimetypes.guess_type(abs_path)[0])
self.response.out.write(f.read())
f.close()
except:
self.response.set_status(404)
where my main app routing looks like:
app = webapp2.WSGIApplication([('/', HelloWorld),
(r'/display', DisplayHandler),
(r'/static/(.+)', StaticFileHandler)
], debug=True)
My css files are in a folder under the app root: /static/css/main.css
I can access the file via direct url, and even link it as a stylesheet, but the styles won't apply. Any ideas? Is there another way to serve stylesheets? Some way to implement an app.yaml similar to GAE?
you dont need a static file handler.
upload the app with the static file folder by adding this to your app.yaml
- url: /static/
static_dir: static
docs are here: https://developers.google.com/appengine/docs/python/config/appconfig#Static_Directory_Handlers
edit:
see answer below in comments
#Mnemon, hats off to you for solving my problem. I would upvote you but I'm not allowed to do that. You convinced me that if it's not the only webapp2 way without GAE, it's at least a way that will work.
But also I can contribute that your solution is now installable as "pip install webapp2_static", from pipi--- by an author who seems to be using his real name... you I'm sure. Other webapp2 docs that I found helpful are available here.
I'm implementing your code on a Linux desktop development server, using paste, which you also used:
def main():
from paste import httpserver
httpserver.serve(app, host='127.0.0.1', port='8080')
But with the code as you have it above (which appears to be utterly identical to that of webapp2_static.py file), I don't find that putting my css files in a folder named static in the app root works as you said.
For example, I have /home/user/proj/public_html/app/app.py, where the py file contains your code plus other "views" for my ultra-simple site. (I don't know how paste really works, so maybe for now the public_html is just in there for reference so that I don't become confused when I'm uploading stuff onto the production server.)
So if I put the css stylesheets into a folder named /static, then, if I put /static in as either a subdirectory of /app or of /public_html I find that neither location works; I must instead make it a subdirectory of /proj.
I wasn't expecting that, but the cure for me is to change the default 'static' in your app.configure.get(..., 'static') call, to 'public_html/app/static'. Then it works, with the /static folder inside /app.
Similarly using the pipi code with './app/static/ in place of the default 'static' doesn't work; I found that I need ./public_html/app/static instead (or maybe it was just /public_html/app/static or even public_html/app/static... I forgot... one of those worked).
I tested how your computation of abs_path works and have reworked it in the code below, in which I have junked your approach in favor of something more Djangoesque. To wit, in my one app py file I put at the top the following:
STATIC_DIR = os.sep + 'tostatic' + os.path.abspath(os.path.dirname(__file__)) + os.sep + 'static'
Then in the page to which I want to add css, my Home page in my case, I put a very readable:
<link href="{{STATIC_DIR}}/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
For the "view" that generates my Home page I have (env is a jinja2 Environment object that takes a template loader as an argument):
class Home(webapp2.RequestHandler):
def get(self):
template = env.get_template('index.html')
template_values = {'STATIC_DIR': STATIC_DIR }
self.response.write(template.render(template_values))
And finally the URL routing is as in:
app = webapp2.WSGIApplication(
[
(r'/', Home),
(r'/tostatic/(.+)', StaticView),
], debug=True)
The view for the static file serving is now:
class StaticView(webapp2.RequestHandler):
def get(self, path):
path = os.sep + path
try:
f = open(path, 'r')
self.response.headers.add_header('Content-Type', mimetypes.guess_type(path)[0])
self.response.out.write(f.read())
f.close()
except Exception, e:
print 'Problem in StaticView:', e
self.response.set_status(404)
To finally close, the problem that I had with your approach is the one that I and other near noobs have with the departure of URLs from the legacy association with the file system. In your approach "static" is both a sub-directory and a string between slashes at the front of the URL that tells the interpreter which view (which webapp2.RequestHandler subclass) to run. You take the /static from the rest of the URL and then later hard-code it back on. And when it comes time to decide what to put in for href in the tag the HTML page coder has to remember that duplicity. With the {{STATIC_DIR}} template variable approach it's clear what to do. And it's easy to redefine the location of the static files--- only the STATIC_DIR declaration has to be changed.
I found that self.response.set_status(404) shows up in Firebug, but not Firefox. Evidently with webapp2 you must provide and serve your own HTTP status code pages.
self.response.headers.add_header('Content-Type', mimetypes.guess_type(abs_path)[0])
self.response.headers['Content-Type'] = mimetypes.guess_type(abs_path)[0]
Introduction
I Got a question about localeURL usage.
Everything works great for me with url like this :
http://www.example.com/
If I type http://www.example.com/ in address bar, it turns correctly in http://www.example.com/en/ for example.
If I use the view change_locale, it's also all right (ie change www.example.com/en/ in www.example.com/fr/).
problem
But my application use apache as server, with mod_wsgi. The httpd.conf script contains this line :
WSGIScriptAlias /MY_PREFIX /path/to/django/app/apache/django.wsgi
that gives url like this :
http://www.example.com/MY_PREFIX/
If I type http://www.example.com/MY_PREFIX/ in the address bar, the adress turns into http://www.example.com/en/ when the expected result should be http://www.example.com/MY_PREFIX/en/
The same problem occurred with the change_locale view. I modified this code in order to manage this prefix (store in settings.SERVER_PREFIX):
def change_locale(request) :
"""
Redirect to a given url while changing the locale in the path
The url and the locale code need to be specified in the
request parameters.
O. Rochaix; Taken from localeURL view, and tuned to manage :
- SERVER_PREFIX from settings.py
"""
next = request.REQUEST.get('next', None)
if not next:
next = request.META.get('HTTP_REFERER', None)
if not next:
next = settings.SERVER_PREFIX + '/'
next = urlsplit(next).path
prefix = False
if settings.SERVER_PREFIX!="" and next.startswith(settings.SERVER_PREFIX) :
prefix = True
next = "/" + next.lstrip(settings.SERVER_PREFIX)
_, path = utils.strip_path (next)
if request.method == 'POST':
locale = request.POST.get('locale', None)
if locale and check_for_language(locale):
path = utils.locale_path(path, locale)
if prefix :
path = settings.SERVER_PREFIX + path
response = http.HttpResponseRedirect(path)
return response
with this customized view, i'm able to correctly change language, but i'm not sure that's the right way of doing stuff.
Question
when, in httpd.conf you use WSGIScriptAlias with /PREFIX (ie "/Blog"), do we need, on python side to use a variable (here settings.SERVER_PREFIX) that match WSGIScriptAlias ? i use it for MEDIA_URL and other stuff, but maybe there is some configuration to do in order to make it work "automatically" without having to manage this on python side
Do you think that this customized view (change_locale) is the right way to manage this issue ? Or is there some kind of automagic stuff as for 1. ?
It doesn't solve the problem if I type the address (http://www.example.com/MY_PREFIX/) in address bar. If customization is the way to go, i will change this as well, but I think there is a better solution!
You should not be hard wiring SERVER_PREFIX in settings. The mount prefix for the site is available as SCRIPT_NAME in the WSGI environ dictionary. Thus from memory is available as request.META.get('SCRIPT_NAME').
try this (I am not sure whether it will work though):
WSGIScriptAliasMatch ^/MY_PREFIX(/.*)?$ /path/to/django/app/apache/django.wsgi$1
basically the idea s to make django believe that there is no prefix
but you need to make sure django emits the correct URLs in its HTML output.