File::Temp: opening the temp. file in "r+" mode? Also "man in the middle"

Discussion in 'Perl Misc' started by A. Farber, Mar 2, 2004.

  1. A. Farber

    A. Farber Guest

    Hi,

    I'm working at a CGI-script which would receive a 20 MB
    big file via HTTP-upload, then change few bytes in it,
    then calculate an MD5 hash over a region of that file
    and save that value into the file as well.

    At the moment I do the first task (change few bytes) like
    this (the $flash is coming from the CGI.pm's filefield):

    my ($fh, $filename) = tempfile(DIR => UPLOADDIR);

    while (sysread $flash, $chunk, KEYSIZE) {
    $both = $prev . $chunk;
    if ($both =~ s/$SEARCH/$REPLACE/o) {
    print $fh $both;
    undef $prev;
    } else {
    print $fh $prev;
    $prev = $chunk;
    }
    }
    # don't forget to print the last line
    print $fh $prev;

    Now I need to calculate the MD5 value and store it
    in the file. Is there a safe way to reuse the $fh ?
    Maybe somehow by using:

    open(FILEHANDLE, "<&=$fh")

    ? But how do I specify the mode above? I need "rb+"
    so that I can store the MD5 hash into the temp.file.

    Also do I really need the new temp.file or is there
    a nice way to work with CGI.pm's temp files?

    And also actually the whole task I'm trying to solve
    is that the file is being sent by TCP-connection to
    a daemon. I'm looking for a way to intercept that
    connection and to insert the bytes and the MD5 hash
    there (kind of "man in the middle attack", but it's
    not an attack :) I could find the way to do it sofar,
    that's why I stick with a CGI-script at the moment.

    Regards
    Alex
     
    A. Farber, Mar 2, 2004
    #1
    1. Advertising

  2. A. Farber

    Ben Morrow Guest

    (A. Farber) wrote:
    >
    > I'm working at a CGI-script which would receive a 20 MB
    > big file via HTTP-upload, then change few bytes in it,
    > then calculate an MD5 hash over a region of that file
    > and save that value into the file as well.
    >
    > At the moment I do the first task (change few bytes) like
    > this (the $flash is coming from the CGI.pm's filefield):
    >
    > my ($fh, $filename) = tempfile(DIR => UPLOADDIR);
    >
    > while (sysread $flash, $chunk, KEYSIZE) {
    > $both = $prev . $chunk;
    > if ($both =~ s/$SEARCH/$REPLACE/o) {
    > print $fh $both;
    > undef $prev;
    > } else {
    > print $fh $prev;
    > $prev = $chunk;
    > }
    > }
    > # don't forget to print the last line
    > print $fh $prev;
    >
    > Now I need to calculate the MD5 value and store it
    > in the file. Is there a safe way to reuse the $fh ?
    > Maybe somehow by using:
    >
    > open(FILEHANDLE, "<&=$fh")
    >
    > ? But how do I specify the mode above? I need "rb+"
    > so that I can store the MD5 hash into the temp.file.


    Why do you need to dup the filehandle at all? Why can't you just use
    $fh?

    Anyway, the answer is

    open my $NEWFH, '+<&=', $fh;

    or, pre-5.8,

    open my $NEWFH, '+<&=' . fileno $fh;

    > Also do I really need the new temp.file or is there
    > a nice way to work with CGI.pm's temp files?


    If the $SEARCH and $REPLACE are the same length then you can run through
    the file and simply overwrite chunks that change with syswrite. If they
    are not then you have to make a copy.

    Ben

    --
    It will be seen that the Erwhonians are a meek and long-suffering people,
    easily led by the nose, and quick to offer up common sense at the shrine of
    logic, when a philosopher convinces them that their institutions are not based
    on the strictest morality. [Samuel Butler, paraphrased]
     
    Ben Morrow, Mar 2, 2004
    #2
    1. Advertising

  3. A. Farber

    A. Farber Guest

    Ben Morrow <> wrote in message news:<c22ka9$3en$>...
    > (A. Farber) wrote:
    > >
    > > I'm working at a CGI-script which would receive a 20 MB
    > > big file via HTTP-upload, then change few bytes in it,
    > > then calculate an MD5 hash over a region of that file
    > > and save that value into the file as well.


    > If the $SEARCH and $REPLACE are the same length then you can run through
    > the file and simply overwrite chunks that change with syswrite. If they
    > are not then you have to make a copy.


    Thank you, yes they are equal size. I haven't thought
    about just running syswrite. What I still don't know though,
    which buffer size to use while copying the uploaded file:

    ($fh, $filename) = tempfile(DIR => UPLOADDIR);

    while (<$upload>) {
    print $fh $_;
    }

    - is bad choice, because it's a binary file.
    And if I use sysread/syswrite, then what $buffer
    size should I use? Should I use PIPE_BUF?

    while (sysread $upload, $buffer, $buf_size) {
    die "syswrite failed: $!"
    unless length $buffer == syswrite $fh, $buffer;
    }
     
    A. Farber, Mar 3, 2004
    #3
  4. A. Farber

    Ben Morrow Guest

    (A. Farber) wrote:
    > Ben Morrow <> wrote in message news:<c22ka9$3en$>...
    > > (A. Farber) wrote:
    > > >
    > > > I'm working at a CGI-script which would receive a 20 MB
    > > > big file via HTTP-upload, then change few bytes in it,
    > > > then calculate an MD5 hash over a region of that file
    > > > and save that value into the file as well.

    >
    > > If the $SEARCH and $REPLACE are the same length then you can run through
    > > the file and simply overwrite chunks that change with syswrite. If they
    > > are not then you have to make a copy.

    >
    > Thank you, yes they are equal size. I haven't thought
    > about just running syswrite. What I still don't know though,
    > which buffer size to use while copying the uploaded file:
    >
    > ($fh, $filename) = tempfile(DIR => UPLOADDIR);
    >
    > while (<$upload>) {
    > print $fh $_;
    > }


    Why are you copying it at all? Can you not simply edit the uploaded file
    directly?

    > - is bad choice, because it's a binary file.
    > And if I use sysread/syswrite, then what $buffer
    > size should I use? Should I use PIPE_BUF?


    You can make <> read be chunks by setting it to, e.g., \4096. This is
    better than using sys{read,write}, as perlio will use the right buffer
    size for you.

    > while (sysread $upload, $buffer, $buf_size) {
    > die "syswrite failed: $!"
    > unless length $buffer == syswrite $fh, $buffer;
    > }


    Ben

    --
    Musica Dei donum optimi, trahit homines, trahit deos. |
    Musica truces molit animos, tristesque mentes erigit. |
    Musica vel ipsas arbores et horridas movet feras. |
     
    Ben Morrow, Mar 3, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    597
    Mark P
    May 9, 2005
  2. John J Lee
    Replies:
    3
    Views:
    550
    bruno at modulix
    Dec 1, 2005
  3. Edward Loper
    Replies:
    0
    Views:
    523
    Edward Loper
    Aug 7, 2007
  4. manu
    Replies:
    11
    Views:
    1,688
    Default User
    Jan 5, 2009
  5. PerlFAQ Server
    Replies:
    0
    Views:
    282
    PerlFAQ Server
    Apr 26, 2011
Loading...

Share This Page