On Jul 31, 2:52 am, Graham Dumpleton <graham.dumple...@gmail.com>
wrote:
> 2009/7/31 gert <gert.cuyk...@gmail.com>:
>
> > On Jul 31, 2:19 am, Graham Dumpleton <graham.dumple...@gmail.com>
> > wrote:
> >> 2009/7/31 gert <gert.cuyk...@gmail.com>:
>
> >> > On Jul 31, 1:04 am, Graham Dumpleton <graham.dumple...@gmail.com>
> >> > wrote:
> >> >> 2009/7/31 gert <gert.cuyk...@gmail.com>:
>
> >> >> > On Jul 28, 5:50 am, Graham Dumpleton <graham.dumple...@gmail.com>
> >> >> > wrote:
> >> >> >> 2009/7/28 gert <gert.cuyk...@gmail.com>:
>
> >> >> >> > On Jul 26, 1:59 am, gert <gert.cuyk...@gmail.com> wrote:
> >> >> >> >> On Jul 26, 1:25 am, Graham Dumpleton <graham.dumple...@gmail.com>
> >> >> >> >> wrote:
>
> >> >> >> >> > 2009/7/25 gert <gert.cuyk...@gmail.com>:
>
> >> >> >> >> > > On Jul 25, 3:42 am, Graham Dumpleton 
> >> >> >> >> > > <graham.dumple...@gmail.com>
> >> >> >> >> > > wrote:
> >> >> >> >> > >> 2009/7/25 gert <gert.cuyk...@gmail.com>:
>
> >> >> >> >> > >> > On Jul 24, 1:22 am, Graham Dumpleton 
> >> >> >> >> > >> > <graham.dumple...@gmail.com>
> >> >> >> >> > >> > wrote:
> >> >> >> >> > >> >> 2009/7/24 gert <gert.cuyk...@gmail.com>:
> >> >> >> >> > >> >> > On Jul 23, 9:27 pm, gert <gert.cuyk...@gmail.com> wrote:
> >> >> >> >> > >> >> >> On Jul 23, 7:28 pm, gert <gert.cuyk...@gmail.com> 
> >> >> >> >> > >> >> >> wrote:
>
> >> >> >> >> > >> >> >> > wsgi file downloads
> >> >> >> >> > >> >> >> > ------------------------------
> >> >> >> >> > >> >> >> > class FileWrapper(object):
> >> >> >> >> > >> >> >> >     def __init__(self, fp, blksize=8192):
> >> >> >> >> > >> >> >> >         self.fp = fp
> >> >> >> >> > >> >> >> >         self.blksize=blksize
> >> >> >> >> > >> >> >> >     def __getitem__(self, key):
> >> >> >> >> > >> >> >> >         data = self.fp.read(self.blksize)
> >> >> >> >> > >> >> >> >         if data: return data
> >> >> >> >> > >> >> >> >         raise IndexError
> >> >> >> >> > >> >> >> >     def close(self):
> >> >> >> >> > >> >> >> >         self.fp.close()
>
> >> >> >> >> > >> >> >> > def application(environ, response):
> >> >> >> >> > >> >> >> >         import os
> >> >> >> >> > >> >> >> >         
> >> >> >> >> > >> >> >> > f=open(os.path.join(os.path.dirname(__file__),'../www/bin/
> >> >> >> >> > >> >> >> > picture.png'), 'rb')
> >> >> >> >> > >> >> >> >         l = os.fstat(f.fileno()).st_size
> >> >> >> >> > >> >> >> >         response('200 OK', [('Content-type', 
> >> >> >> >> > >> >> >> > 'image/png'), ('Content-
> >> >> >> >> > >> >> >> > Length', str(l))])
> >> >> >> >> > >> >> >> >         if 'wsgi.file_wrapper' in environ: return 
> >> >> >> >> > >> >> >> > environ
> >> >> >> >> > >> >> >> > ['wsgi.file_wrapper'](f, 8192)
> >> >> >> >> > >> >> >> >         else: return FileWrapper(f, 8192)
>
> >> >> >> >> > >> >> >> > wsgi file uploads
> >> >> >> >> > >> >> >> > -------------------------
> >> >> >> >> > >> >> >> > from re import search,DOTALL
>
> >> >> >> >> > >> >> >> > def application(environ, response):
> >> >> >> >> > >> >> >> >     t = environ['wsgi.input'].read(int(environ
> >> >> >> >> > >> >> >> > ['CONTENT_LENGTH'])).decode('latin1')
> >> >> >> >> > >> >> >> >     b = environ['CONTENT_TYPE'].split('boundary=')[1]
> >> >> >> >> > >> >> >> >     p = search(b+r'.*?Content-Type: 
> >> >> >> >> > >> >> >> > application/octet-stream\r\n\r\n
> >> >> >> >> > >> >> >> > (.*?)\r\n--'+b,t,DOTALL).group(1)
> >> >> >> >> > >> >> >> >     p = p.encode('latin1')
> >> >> >> >> > >> >> >> >     response('200 OK', [('Content-type', 
> >> >> >> >> > >> >> >> > 'text/plain;charset=utf-8'),
> >> >> >> >> > >> >> >> > ('Content-Length', str(len(j))) ])
> >> >> >> >> > >> >> >> >     return ['complete']
>
> >> >> >> >> > >> >> >> > How would you chunk up the reading part to save 
> >> >> >> >> > >> >> >> > memory ?
>
> >> >> >> >> > >> >> >> def application(environ, response):
> >> >> >> >> > >> >> >>     with open('/usr/httpd/logs/wsgiTemp') as f:
> >> >> >> >> > >> >> >>         while True:
> >> >> >> >> > >> >> >>             chunk = environ['wsgi.input'].read(8192)
> >> >> >> >> > >> >> >>             if not chunk: break
> >> >> >> >> > >> >> >>             f.write(chunk)
> >> >> >> >> > >> >> >>     response('200 OK')
> >> >> >> >> > >> >> >>     return ['complete']
>
> >> >> >> >> > >> >> >> hmm it keeps on telling me its not writeble aldo it is 
> >> >> >> >> > >> >> >> chmod 777
>
> >> >> >> >> > >> >> > woops :)
>
> >> >> >> >> > >> >> > def application(environ, response):
> >> >> >> >> > >> >> >    with open('/usr/httpd/logs/wsgiTemp','w') as f:
> >> >> >> >> > >> >> >        while True:
> >> >> >> >> > >> >> >            chunk = 
> >> >> >> >> > >> >> > environ['wsgi.input'].read(8192).decode('latin1')
> >> >> >> >> > >> >> >            if not chunk: break
> >> >> >> >> > >> >> >            f.write(chunk)
> >> >> >> >> > >> >> >    response('200 OK',[])
> >> >> >> >> > >> >> >    return ['complete']
>
> >> >> >> >> > >> >> That is not portable WSGI code. It may work on mod_wsgi 
> >> >> >> >> > >> >> but not on
> >> >> >> >> > >> >> other WSGI servers. This is because WSGI specification 
> >> >> >> >> > >> >> requires that
> >> >> >> >> > >> >> you not read more than CONTENT_LENGTH bytes from input 
> >> >> >> >> > >> >> stream. It only
> >> >> >> >> > >> >> works for mod_wsgi because it returns a proper EOF 
> >> >> >> >> > >> >> sentinel when input
> >> >> >> >> > >> >> is exhausted, but WSGI specification doesn't specifically 
> >> >> >> >> > >> >> require
> >> >> >> >> > >> >> that. Where the code can thus fail is where client 
> >> >> >> >> > >> >> requests keep alive
> >> >> >> >> > >> >> for connection.
>
> >> >> >> >> > >> > How do I make sure a chunk doesn't cut the boundary in 
> >> >> >> >> > >> > half ? So i can
> >> >> >> >> > >> > figure out what chunks are binary data ?
>
> >> >> >> >> > >> You have to internally buffer data within the component. 
> >> >> >> >> > >> This is what
> >> >> >> >> > >> cgi.FieldStorage does, so perhaps have a look at it.
>
> >> >> >> >> > >> Better still have a look at equivalent to cgi.FieldStorage 
> >> >> >> >> > >> in Werkzeug
> >> >> >> >> > >> as it is WSGI 1.0 compliant where as cgi.FieldStorage isn't.
>
> >> >> >> >> > > Can mod_wsgi handle PUT request ? Or do i need a separate 
> >> >> >> >> > > apache
> >> >> >> >> > > module for this ?
> >> >> >> >> > > Seems PUT is the only possible way to resume file uploads ?
>
> >> >> >> >> > All HTTP methods except maybe CONNECT and TRACE should get 
> >> >> >> >> > through to mod_wsgi.
>
> >> >> >> >> > Whether resumable uploads is possible is probably more a 
> >> >> >> >> > feature of
> >> >> >> >> > your WSGI application and cannot see why it would be restricted 
> >> >> >> >> > to PUT
> >> >> >> >> > except by convention. Of course your client needs to support 
> >> >> >> >> > uploads
> >> >> >> >> > for byte ranges.
>
> >> >> >> >> I tested it with curl -T bigfile 
> >> >> >> >> http://gert:pas...@192.168.2.17/upload.wsgi
> >> >> >> >> and indeed it just dumps the file on my disk, which is good news 
> >> >> >> >> :)
>
> >> >> >> >> The I could have guest it news is that curl -C bigfile
> >> >> >> >> http://gert:pas...@192.168.2.17/upload.wsgi results into a empty 
> >> >> >> >> file.
> >> >> >> >> So curl is expecting something back before it sends anything, 
> >> >> >> >> which
> >> >> >> >> makes it a bit complicated, actually allot. Has anybody already 
> >> >> >> >> made
> >> >> >> >> this kind of wsgi for curl handshaking ?
>
> >> >> >> > It seems that you have to tell curl where it needs to start 
> >> >> >> > uploading
> >> >> >> > manually, there is no such thing as server communication to do so
> >> >> >> > automatically. Example
> >> >> >> > curl -C 1024 bigfile http://gert:pas...@192.168.2.17/upload.wsgi
>
> >> >> >> > That makes me wonder if the download wsgi.file_wrapper can actually
> >> >> >> > resume downloads, I always took it for granted it could do so ? 
> >> >> >> > And if
> >> >> >> > not where does the offset get stored in the headers ?
>
> >> >> >> Would expect that that would also require WSGI application to be
> >> >> >> knowledgeable about byte range requests. So, WSGI application would
> >> >> >> need to see it is a request for partial data, open the file, seek to
> >> >> >> start position, plus set status and response headers indicating
> >> >> >> partial response, and set Content-Length to amount of data to be
> >> >> >> returned from the seek position in file.
>
> >> >> >> Note that this code wouldn't be portable as mod_wsgi is I believe 
> >> >> >> only
> >> >> >> implementation which pays attention to Content-Length when
> >> >> >> wsgi.file_wrapper is used to ensure only part of a file is returned.
>
> >> >> >> Can't help much more than that as don't know about how HTTP handles
> >> >> >> partial byte range requests etc.
>
> >> >> >http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16
>
> >> >> > So how do i tell the filewrapper to do this ?
>
> >> >> > Content-Range: bytes 21010-47021/47022
> >> >> > Content-Length: 26012
>
> >> >> I am not sure what all the values in the Content-Range mean so you
> >> >> will have to explain. And no I don't have time to go read the RFC.
>
> >> >> If it is returning just a single range within the file, then do the 
> >> >> following.
>
> >> >> Open file. Seek to position 21010. Set returned Content-Length header
> >> >> to length from that seek point onwards that want to return, possible
> >> >> 26012, and then return wsgi.file_wrapper() for open file object.
>
> >> > I hate RFC's they always make it sound so complicated
>
> >> > Content-Range: bytes 21010-47021/47022
> >> > Content-Length: 26012
>
> >> > html 1.1 only support bytes so all numbers represent bytes
> >> > (first number is te start byte) - (second the end byte) / (third
> >> > number is the total byte count of the complete file or * if unkown,
> >> > example 0 1 2 = 3 bytes)
> >> > content length is the number of bytes that wil get sent.
>
> >> > take note that this could be used to download different parts from
> >> > several servers
>
> >> > So how do i tell the environ['wsgi.file_wrapper'](f, 8192) that f is
> >> > just the 500 bytes in the middle of a file ?
>
> >> I have already told you that twice. :-(
>
> >> What don't you understand about:
>
> >> """
> >> Open file. Seek to position 21010. Set returned Content-Length header
> >> to length from that seek point onwards that want to return, possible
> >> 26012, and then return wsgi.file_wrapper() for open file object.
> >> """
>
> >> I suggest you go read about the seek() method file objects in Python
> >> documentation.
>
> > I know but your first question was
> > "I am not sure what all the values in the Content-Range mean so you
> > will have to explain."
> > So i did what you asked me to do, explaining :)
>
> I was only referring to your question:
>
> """
> So how do i tell the environ['wsgi.file_wrapper'](f, 8192) that f is
> just the 500 bytes in the middle of a file ?
> """

That would be a explanation question of the previous question :)

> and I had already answered that twice.

You are going to love my next "GET someURL\r\n Range:
bytes=4096-8191,0-4095" question :)
and how the hell do i generate a boundary --46228a661764c4210

> Code example below:
>
> import os
>
> def application(environ, start_response):
>     status = '200 OK'
>     handle  = file('/etc/passwd', 'rb')
>
>     # Seek to start position 10 bytes into file.
>     handle.seek(10, os.SEEK_SET)
>
>     # Set content length so only 6 bytes from set position of file is sent.
>     response_headers = [('Content-type', 'text/plain'),('Content-Length', 
> '6')]
>
>     start_response(status, response_headers)
>
>     return environ['wsgi.file_wrapper'](handle)
>
> Remember that this likely will not work on other WSGI implementations
> as I believe that only mod_wsgi pays attentions to response
> Content-Length and ensures that applications only return as much data
> as they indicate should be.
>

ok thanks going to experiment with it a bit need to look up what
os.SEEK_SET does.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"modwsgi" group.
To post to this group, send email to modwsgi@googlegroups.com
To unsubscribe from this group, send email to 
modwsgi+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/modwsgi?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to