Partial read from urls with READ/PART or READ/SEEK - rebol

Partial read via HTTP Range header works fine for me:
rebol []
client: open tcp://www.apache.org/
client/awake: func [event /local port] [
port: event/port
switch event/type [
lookup [open port]
connect [
write port rejoin [
{GET / HTTP/1.1} crlf
{User-Agent: curl/7.26.0} crlf
{Host: www.apache.org} crlf
{Accept: */*} crlf
{Range: bytes=0-9} crlf
crlf
]
]
wrote [read port]
read [
probe to-string port/data
probe length? port/data
clear port/data
]
]
false
]
wait [client 3]
close client
print "Done"
I think I could use READ/PART to do the same thing:
length? read/part http://www.apache.org/ 10 ;40195
length? read http://www.apache.org/ ;40195
but it does't work, still get all the bytes. The same with READ/SEEK.
Why was that?
(By the way, it works in Rebol2.)

You can see from the source
https://github.com/rebol/rebol/blob/master/src/mezz/prot-http.r#L424
that the read actor does not have any refinements defined. This doesn't mean they can't be defined but at present no decision has been made on whether it should be done by using refinements, or by using a query dialect.
You can see by setting trace/net on, that it's faking it in Rebol2
>> trace/net on
>> read/part http://www.apache.org 10
URL Parse: none none www.apache.org none none none
Net-log: ["Opening" "tcp" "for" "HTTP"]
connecting to: www.apache.org
Net-log: {GET / HTTP/1.0
Accept: */*
Connection: close
User-Agent: REBOL View 2.7.8.3.1
Host: www.apache.org
}
Net-log: "HTTP/1.1 200 OK"
Net-log: ["low level read of " 2048 "bytes"]
Net-log: ["low level read of " 2048 "bytes"]
.. many lines removed
Net-log: ["low level read of " 2048 "bytes"]
Net-log: ["low level read of " 2048 "bytes"]
Net-log: ["low level read of " 2048 "bytes"]
== "<!DOCTYPE "

It's a safe guess that it's simply not implemented in current version of HTTP scheme. There are other missing parts also like redirection, so I would assume it's not supported yet.

Related

How to concatenate password with mysql:// protocol in Rebol?

I have a password that contains "]" so rebol doesn't accept mysql://user:password
How to concatenate a string with mysql:// ?
You can use the block form to open the port:
my-database: open [
scheme: 'mysql
host: "localhost"
user: "user"
pass: "pass"
path: "/dbpath"
]
You can examine output from the DECODE-URL function to see how Rebol turns a URL into a port specification:
probe decode-url foo://bar:baz#foobar.qux:999/quux

Rebol 2 esmtp cannot decode AUTH parameter

Set set-net with appropriate values, but get this message when trying to send an email using esmtp.r from rebol.org. Any ideas what this means?
OK. I tried and was successful sending a message using Rebol2's built-in 'send function. Here is a transcript of my session:
>> help set-net
USAGE:
SET-NET settings
DESCRIPTION:
Network setup. All values after default are optional. Words OK for server names.
SET-NET is a function value.
ARGUMENTS:
settings -- [email-addr default-server pop-server proxy-server proxy-port-id proxy-type esmtp-user
esmtp-pass] (Type: block)
>> set-net [blechnow#server.net "mail.sonic.net" "mail.sonic.net" none none none "blechnow" "<removed my password>"]
>> help esend
Found these words:
resend function! Relay a message
>> help send
USAGE:
SEND address message /only /header header-obj /attach files /subject subj /show
DESCRIPTION:
Send a message to an address (or block of addresses)
SEND is a function value.
ARGUMENTS:
address -- An address or block of addresses (Type: email block)
message -- Text of message. First line is subject. (Type: any)
REFINEMENTS:
/only -- Send only one message to multiple addresses
/header -- Supply your own custom header
header-obj -- The header to use (Type: object)
/attach -- Attach file, files, or [.. [filename data]]
files -- The files to attach to the message (Type: file block)
/subject -- Set the subject of the message
subj -- The subject line (Type: any)
/show -- Show all recipients in the TO field
>> trace/net on ;This turns on tracing so you can see what is going on at the network level
>> send bo#server.com {Test}
Net-log: ["Opening" "tcp" "for" "esmtp"]
connecting to: mail.sonic.net
Net-log: [none "220"]
Net-log: "220 mail.sonic.net ESMTP [c]"
Net-log: [["EHLO" system/network/host] "250"]
Net-log: {250-c.mail.sonic.net Hello exchange.domain.local [50.255.255.211] (may be forged), pleased to meet you}
Net-log: "250-ENHANCEDSTATUSCODES"
Net-log: "250-PIPELINING"
Net-log: "250-8BITMIME"
Net-log: "250-SIZE 35882577"
Net-log: "250-DSN"
Net-log: "250-ETRN"
Net-log: "250-AUTH PLAIN LOGIN"
Net-log: "250-STARTTLS"
Net-log: "250-DELIVERBY"
Net-log: "250 HELP"
Net-log: ["Supported auth methods:" [plain login]]
Net-log: ["WARNING! Using AUTH LOGIN."]
Net-log: [
"AUTH LOGIN" "334"
]
Net-log: "334 VX******c="
Net-log: ["Ym******U6" "334"]
Net-log: "334 UG******=="
Net-log: ["Mz******Q6" "235"]
Net-log: "235 2.0.0 OK Authenticated"
Net-log: ["MAIL FROM: <blechnow#server.net>" "250"]
Net-log: "250 2.1.0 <blechnow#server.net>... Sender ok"
Net-log: ["RCPT TO: <bo#server.com>" "250"]
Net-log: "250 2.1.5 <bo#server.com>... Recipient ok"
Net-log: ["DATA" "354"]
Net-log: {354 Enter mail, end with "." on a line by itself}
Net-log: [none "250"]
Net-log: {250 2.0.0 u9******49 Message accepted for delivery}
Net-log: ["QUIT" "221"]
Net-log: "221 2.0.0 c.mail.sonic.net closing connection"

Perl not playing video with vlc plugin

I am trying to play the video file with help of vlc-plugin.
Here is my code:-
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
my $file ='/home/abhishek/Videos/lua.mp4';
my $size = -s "$file";
my $begin=0;
my $end=$size;
(my $name, my $dir, my $ext) = fileparse($file, qr/\.[^.]*/);
open (my $fh, '<', $file)or die "can't open $file: $!";
binmode $fh;
print "Content-Type: application/x-vlc-plugin \n";
print "Cache-Control: public, must-revalidate, max-age=0";
print "Pragma: no-cache" ;
print "Accept-Ranges: bytes";
print "Content-Length: $end - $begin\n\n";
print "Content-Range: bytes $begin'-'$end'/'$size";
print "Content-Disposition: inline; filename=\"$name$ext\"\n";
print "Content-Transfer-Encoding: binary";
print "Connection: close";
my $cur=$begin;
seek($fh,$begin,0);
while(!eof($fh) && $cur < $end)
{
my $buf=1024*16;
read $fh, $buf, $end-$cur;
$cur+=1024*16;
}
close $fh;
And here is my access log is writing
127.0.0.1 - - [29/Dec/2015:11:39:31 +0530] "GET /cgi-bin/download.cgi HTTP/1.1" 200 484 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:43.0) Gecko/20100101 Firefox/43.0"
127.0.0.1 - - [29/Dec/2015:11:39:32 +0530] "GET /cgi-bin/download.cgi HTTP/1.1" 200 447 "-" "(null)"
As I checked what does this mean from apache site,here is what i got
If no content was returned to the client, this value will be "-". To log "0" for no content, use %B instead.
No content is returning to the client.It is returning null.
I am not able to figure out what is going wrong. Any help what will be grateful.
And please suggest me what should i do to play the video and I am not sure is this the correct way to do?
Thanks in advance
I see numerous major problems with the headers you are printing:
print "Content-Type: application/x-vlc-plugin \n";
This MIME type is primarily used in an <embed> tag to invoke VLC. The correct MIME type for this file type is probably video/mp4.
print "Cache-Control: public, must-revalidate, max-age=0";
print "Pragma: no-cache" ;
These headers, and a number of the other ones following, are missing terminal newlines (\n). This will cause them to run together, causing unexpected results.
print "Accept-Ranges: bytes";
Along with not having a newline, this header is telling the browser that this resource supports range requests. Your script doesn't actually implement this, though, which will cause browsers to get very confused.
print "Content-Length: $end - $begin\n\n";
Content-Length must be a single number representing the total length of the resource (e.g, Content-Length: $size). Also, you've got two newlines here, which will cause all the following headers to be treated as part of the content.
print "Content-Range: bytes $begin'-'$end'/'$size";
This header would normally be used with range requests, but you haven't fully implemented this feature, so this header will just confuse matters.
print "Content-Transfer-Encoding: binary";
This header is meaningless here — it's primarily used in email. Leave it out.
print "Connection: close";
This header will be set as needed by the web server. CGI scripts shouldn't generate it.
You're also missing the double newline that needs to follow the last header.
I am too lazy to get it fully working, Here is a few suggestions
which does not fit into comments
Definitely will move you forward.
# format is in the detail
my $content_length = $end - $begin;
print "Content-Type: text/html\r\n";
print "Content-Type: application/x-vlc-plugin\r\n";
print "Cache-Control: public, must-revalidate, max-age=0\r\n";
print "Pragma: no-cache\r\n" ;
print "Accept-Ranges: bytes\r\n";
print "Content-Length: $content_length", "\r\n";
print "Content-Range: bytes ${begin}-${end}/${size}\r\n";
print "Content-Disposition: inline; filename=\"$name$ext\"\r\n";
print "Content-Transfer-Encoding: binary\r\n";
print "Connection: close\r\n";
print "\r\n";
################################
#
# flush is needed
#
# ##############################
use IO::Handle;
STDOUT->autoflush;
my $cur=$begin;
seek($fh,$begin,0);
while(!eof($fh) && $cur < $end)
{
my $buf=1024*16;
read $fh, $buf, $end-$cur;
$cur+=1024*16;
##############################
# I suspect you will need this
#
###############################
print $buf;
}
close $fh;

How to open/write/read port in REBOL3?

I have this code in REBOL2:
port: open/direct tcp://localhost:8080
insert port request
result: copy port
close port
What would be equivalent in REBOL3?
REBOL3 networking is async by default, so the code in REBOL3 must look like:
client: open tcp://localhost:8080
client/awake: func [event /local port] [
port: event/port
switch event/type [
lookup [open port]
connect [write port to-binary request]
read [
result: to-string port/data
close port
return true
]
wrote [read event/port]
]
false
]
wait [client 30] ;the number is a timeout in seconds
close client
Based on: http://www.rebol.net/wiki/TCP_Port_Examples
EDIT: above link does not exists anymore, but here is it transferred to GitHub's wiki: https://github.com/revault/rebol-wiki/wiki/TCP-Port-Examples

rebol open has no refinement called async

I tried the example http://www.rebol.net/docs/async-examples.html but it doesn't work.
port-spec: tcp://www.rebol.net:80
http-request: {GET /
User-Agent: REBOL/Core
Connection: close
}
client: context [
data: make binary! 10000
handler: func [port action arg] [
switch action [
read [
append data copy/part port arg
print ["-- read" arg "bytes" length? data "total"]
]
write [print "-- writing (sending)"]
write-done [print "-- done with write"]
close [
print ["-- done with read" length? data]
close port
print ["-- closed port, press RETURN to quit"]
]
init [print "-- port initialized"]
open [print "-- opened" insert port http-request]
address [print ["-- address lookup:" arg]]
error [print ["-- error:" mold disarm :arg] close port]
]
]
]
p: open/direct/binary/async port-spec get in client 'handler
input ; (wait for user console input before closing)
attempt [close p]
The /async was removed a while ago. If you want to use async, you'll have to use Gabriele and others' async protocols.