[PHP-DEV] Re: [PHP3] PUT script needed From: MANUEL LEMOS (mlemos <email protected>)
Date: 07/30/98

Hello Shane,

> > If you feel is there anything else we can do to spare you
> > some time
> > besides implementing PUT method support, just let us know
> > because I have
> > a project pending on this and for now it is only using C
> > because it
> > couldn't be done with PHP.
>
>
> If your writing PUT handling in C, why dont you just take a little time to
> look through some of the internals in php, and add PUT support to php? If

I did but it was really very confusing. I have no idea of the scope of
the code, what it does, why it does it. it's very hard to get in the
developers mind.

> you went to the developer list, and said 'look, I'm willing to add this and
> test it, but need will need help understanding some things in php' you would
> likely get help from several people. If you know C well enough to implement
> a custom cgi to handle PUT, you know it well enough to add it to PHP. The

I have a script here in C that simply reads the content length of the
file being uploaded with PUT and copies it to a temporary file.

It works fine with Netscape Composer uploads either text files or binary.

For a developers that knows and understands PHP source it would be very
easy to handling the PUT method just by doing the same and then set
global variables with the filename of the temporary file name where the
uploaded file was copied and set another variable to tell where in the
server directory the PUT header meant the file to be stored.

Then an person that would write a PHP script to handle the upload would
determine what to do with it. This would allow a PHP programmer to do
any processing before he would decide to store the file in the server
where the uploader meant it to be stored.

Here follows an example of a PUT upload done by netscape composer, below
follows a script in C that just copies each uploaded file to a unique
temporary file.

With this information I think it is really easy for a PHP developer to
support the PUT method. Please try to do something as a lot of people
would appreciate.

Manuel Lemos

PUT / HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.05 [en] (X11; I; HP-UX A.09.07 9000/715)
Pragma: no-cache
Host: devil.av.it.pt:2000
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Content-Length: 324

<HTML>
<HEAD>
   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
   <META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en] (X11; I; HP-UX A.09.07 9000
/715) [Netscape]">
   <TITLE>oba</TITLE>
<!Script de teste>
</HEAD>
<BODY>

<H1>
Hello World!</H1>

<H2>
Oba! Oba!</H2>

</BODY>
</HTML>

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>

#define LINESIZE 200

main()
{
char line[LINESIZE];
char *line_chr;
char *line_if;
int line_int,i;
unsigned long num_bytes=0;
int error=0;
int last_r_chr;

for(i=0;;)
{
        int line_int;

        if (i==LINESIZE)
        {
                error=4;
                break;
        }
        line_int=getc(stdin);
        if (line_int==EOF)
        {
                if (ferror(stdin))
                error=1;
                break;
        }
        if (line_int=='\n' && last_r_chr==1)
                line_int=0;
        if (line_int=='\r')
                last_r_chr=1;
        else
                last_r_chr=0;

        line[i]=line_int;

        if (line_int=='\0')
        {
                line_chr=strchr(line,':');
                if (line_chr!=NULL)
                {
                        *line_chr='\0';
                        if (strcmp(line,"Content-Length")==0)
                        {
                                unsigned long num_b;
                                
                                num_b=strtoul(line_chr+1,NULL,10);
                                if (num_b==0)
                                {
                                        error=2;
                                        break;
                                }
                                if (num_b==ULONG_MAX && errno==ERANGE)
                                {
                                        error=3;
                                        break;
                                }
                        num_bytes=num_b;
                        }
                        *line_chr=':';
                }
                /* printf("\"%s\" \n",line); */
                if(line[0]=='\r')
                        break;
                i=0;
                continue;
        }
        i++;
}

if (error==0)
{
        if (num_bytes==0)
                error=5;
        else
        {
                char *tmp_name;
        
                tmp_name=tmpnam(NULL);
                if (tmp_name==NULL)
                        error=6;
                else
                {
                        FILE *tmp_file;

                        tmp_file=fopen(tmp_name,"w");
                        /* printf("%s",tmp_name); */
                        if (tmp_file==NULL)
                                error=7;
                        else
                        {
                                int count;
        
                                for(count=0;count<num_bytes;count++)
                                {
                                        int chr_stdin;
                                        chr_stdin=getc(stdin);
                                        if(chr_stdin==EOF)
                                        {
                                                error=8;
                                                break;
                                        }
                                        if (putc(chr_stdin,tmp_file)==EOF)
                                        {
                                                error=9;
                                                break;
                                        }
                                }
                                fclose(tmp_file);
                        }
                }
        }
}
if (error==0)
{
        printf("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n");
}
else printf("Error! %d \n",error);
}