I’m trying to send a file using http in a ruby script of mine. I’ve been
trying to find an answer for this, but haven’t been satisfied with anything
I’ve seen so far.
What I’m doing is this…
I’ve got a file on my host machine (no direct link to it from the web
page–and I don’t want one) and the user is clicking on a link invoking my
ruby script which in turn attempts to send the file to the client.
This is what I have so far…
…
file = File.open(“data.zip”)
puts "Content-type: application/x-zip-compressed\n"
puts “Content-length: “+File.size(“album.zip”).to_s+”\n\n”
ok, now what? How do I send the file data? I can send plain text no
problem, but I don’t know how to efficiently send this file. Any help would
be appreciated.
I’m trying to send a file using http in a ruby script of mine.
A CGI, presumably?
This is what I have so far…
…
file = File.open(“data.zip”)
puts “Content-type: application/x-zip-compressed\n”
puts “Content-length: “+File.size(“album.zip”).to_s+”\n\n”
ok, now what? How do I send the file data?
You should be OK with:
print File.read(“album.zip”)
Or slightly more efficient,
File.open(“album.zip”) do |f|
print f.read
end
because it closes the file immediately, rather than waiting until
garbage-collection time.
If running as a CGI you shouldn’t need to generate a Content-length: header,
just let your webserver deal with it. It can use chunked transfer encoding
if the file is large.
Regards,
Brian.
···
On Tue, Apr 08, 2003 at 02:32:35PM +0900, Andrew wrote:
Yes, this is using CGI. Your code seems to do almost what I want, but it
reads a few (10-20?) bytes and then stops. Is there something in the zip
file that ‘read’ would interpret as an end of file maybe and cause it to
stop?
I’m trying to send a file using http in a ruby script of mine.
A CGI, presumably?
This is what I have so far…
…
file = File.open(“data.zip”)
puts “Content-type: application/x-zip-compressed\n”
puts “Content-length: “+File.size(“album.zip”).to_s+”\n\n”
ok, now what? How do I send the file data?
You should be OK with:
print File.read(“album.zip”)
Or slightly more efficient,
File.open(“album.zip”) do |f|
print f.read
end
because it closes the file immediately, rather than waiting until
garbage-collection time.
If running as a CGI you shouldn’t need to generate a Content-length:
header,
···
On Tue, Apr 08, 2003 at 02:32:35PM +0900, Andrew wrote:
just let your webserver deal with it. It can use chunked transfer encoding
if the file is large.
Yes, this is using CGI. Your code seems to do almost what I want, but it
reads a few (10-20?) bytes and then stops. Is there something in the zip
file that ‘read’ would interpret as an end of file maybe and cause it to
stop?
Oops, my fault:
a = File.read(“/etc/passwd”)
NameError: undefined method `read’ for File:Class
Try:
File.open(“album.zip”).read
If your CGI generates errors like that, you should see them in your
webserver’s error log (e.g. /var/log/apache/logs/error_log or something like
that)
Cheers,
Brian.
···
On Wed, Apr 09, 2003 at 08:37:02AM +0900, Andrew wrote:
a = File.read(“/etc/passwd”)
NameError: undefined method `read’ for File:Class
Try:
File.open(“album.zip”).read
Which reminds me again of the handy little utility methods that I’ve
added to class File (see below).
Are these methods useful enough that we should consider adding them to
the standard Ruby File class, or should I be content with requiring them
class File
# Reads the contents of the specified file_name and returns them as
# a String.
def File.read(file_name)
File.open(file_name) { |f| f.read }
end
# Writes +content+ to the file with the specified +file_name+,
# overwriting any existing content of the file.
def File.write(file_name, content)
File.open(file_name, 'w') { |f| f.write(content) }
end
# Writes +content+ to the file with the specified +file_name+,
# appending to any existing content of the file.
def File.append(file_name, content)
File.open(file_name, 'a') { |f| f.write(content) }
end
# Reads the contents of the file with the specified +file_name+ and
# passes the contents to the provided block. The contents of the
# file are then replaced by whatever is returned from the block.
def File.filter(file_name)
File.write(file_name, yield(File.read(file_name)))
end
end
···
from my ‘tools’ library? matz, your thoughts?
–
Jason Voegele
“There is an essential core at the center of each man and woman that
remains unaltered no matter how life’s externals may be transformed
or recombined. But it’s smaller than we think.”
– Gene Wolfe, The Book of the Long Sun
I’m not getting any errors. The problem is that the whole file isn’t being
read. It reads some and outputs what it reads, but it’s far from reading
everything. I have a 30MB file and it’s only reading a handful of bytes and
then stops (no errors). I want it to read the whole file, not part of it.
This is a binary file that I’m attempting to read, not text, so would that
cause any problems?
Yes, this is using CGI. Your code seems to do almost what I want, but
it
reads a few (10-20?) bytes and then stops. Is there something in the
zip
file that ‘read’ would interpret as an end of file maybe and cause it to
stop?
Oops, my fault:
a = File.read(“/etc/passwd”)
NameError: undefined method `read’ for File:Class
Try:
File.open(“album.zip”).read
If your CGI generates errors like that, you should see them in your
webserver’s error log (e.g. /var/log/apache/logs/error_log or something
like
···
On Wed, Apr 09, 2003 at 08:37:02AM +0900, Andrew wrote:
that)
This is for the poor souls in Windows-land who need mode=‘rb’ or whatever to
stop their O/S mangling the file. Also eliminates the need for a separate
append method.
As for this one:
def File.filter(file_name, readmode='r', writemode='w')
File.write(file_name, yield(File.read(file_name, readmode)), writemode)
end
If we have this then perhaps there should be a line-by-line filter as well -
File.sed ?? But it would have to write a temporary file.
Regards,
Brian.
···
On Wed, Apr 09, 2003 at 10:00:49PM +0900, Jason Voegele wrote:
Are these methods useful enough that we should consider adding them to
the standard Ruby File class, or should I be content with requiring them
from my ‘tools’ library?
Please describe how you know that it is outputting only a few bytes of your
file.
Can you try the following four-liner:
#!/usr/local/bin/ruby
$stdout.binmode
print “Content-Type: application/octet-stream\r\n\r\n”
f = File.open(“/path/to/album.zip”).read
print f
and if that doesn’t work then we can try to narrow it down from there.
Cheers,
Brian.
···
On Thu, Apr 10, 2003 at 10:22:13AM +0900, Andrew wrote:
I’m not getting any errors. The problem is that the whole file isn’t being
read. It reads some and outputs what it reads, but it’s far from reading
everything. I have a 30MB file and it’s only reading a handful of bytes and
then stops (no errors). I want it to read the whole file, not part of it.
I’m not getting any errors. The problem is that the whole file isn’t
being
read. It reads some and outputs what it reads, but it’s far from
reading
everything. I have a 30MB file and it’s only reading a handful of bytes
and
then stops (no errors). I want it to read the whole file, not part of
it.
Please describe how you know that it is outputting only a few bytes of
your
···
On Thu, Apr 10, 2003 at 10:22:13AM +0900, Andrew wrote:
file.
Can you try the following four-liner:
#!/usr/local/bin/ruby
$stdout.binmode
print “Content-Type: application/octet-stream\r\n\r\n”
f = File.open(“/path/to/album.zip”).read
print f
and if that doesn’t work then we can try to narrow it down from there.