/*
DBOX Module
Copyright (C) 1994-2000 Daniel Kroening <kroening@handshake.de>
Purpose:
*/
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <general.h>
#include <base64.h>
#include <stringtools.h>
#include "http.h"
#include <logf.h>
void httpt::parse_command()
{
char *t1, *t2, old;
method=UNKNOWN;
if(command=="")
{
url=version="";
return;
}
//
// Methode
//
char *c=strdup(command.c_str());
t2=c;
while(*t2!=' ' && *t2!='\t' && *t2!=0) t2++;
old=*t2;
*t2=0;
if(stringcasecmp(command, "GET")==0)
method=GET;
else if(stringcasecmp(command, "PUT")==0)
method=PUT;
else if(stringcasecmp(command, "POST")==0)
method=POST;
*t2=old;
while(*t2==' ' || *t2=='\t') t2++;
t1=t2;
if(t1[0]==0)
{
url=version="";
free((void *)c);
return;
}
//
// URL
//
while(*t2!=' ' && *t2!='\t' && *t2!=0 && *t2!='?') t2++;
old=*t2;
*t2=0;
url=t1;
decode_url(url);
*t2=old;
if(old=='?')
{
t1=t2+1;
while(*t2!=' ' && *t2!='\t' && *t2!=0) t2++;
old=*t2;
*t2=0;
parse_parameter(t1);
*t2=old;
}
while(*t2==' ' || *t2=='\t') t2++;
t1=t2;
if(t1[0]==0)
{
version="";
free(c);
return;
}
//
// Version
//
version=t1;
free(c);
}
void httpt::parse_parameter(char *str)
{
char *t;
parametert p;
if(str==NULL) return;
t=str;
while(*t!=0)
{
if(*t==-1)
*t=' ';
t++;
}
while(str[0]!=0)
{
t=strchr(str, '=');
if(t==NULL) return;
*t=0;
p.n=parameter;
string _name=str;
decode_url(_name);
p.name=strdup(_name.c_str());
*t='=';
str=t+1;
string _inhalt;
t=strchr(str, '&');
if(t==NULL)
{
_inhalt=str;
str="";
}
else
{
*t=0;
_inhalt=str;
*t='&';
str=t+1;
}
decode_url(_inhalt);
p.inhalt=strdup(_inhalt.c_str());
parameter=new parametert;
*parameter=p;
}
}
const char *httpt::getparameter(const char *name)
{
return get_parameterfromlist(name, parameter);
}
const char *httpt::get_parameter(const string &name)
{
return get_parameterfromlist(name.c_str(), parameter);
}
const char *httpt::get_header(const char *name)
{
return get_parameterfromlist(name, header);
}
const char *httpt::get_parameterfromlist(const char *name, parametert *list)
{
parametert *p;
p=list;
while(p!=NULL)
{
if(stricmp(name, p->name)==0)
return p->inhalt;
p=p->n;
}
return NULL;
}
httpt::httpt()
{
parameter=header=NULL;
method=UNKNOWN;
}
void httpt::clear()
{
command=url=version="";
if(parameter!=NULL)
{
parametert *p;
while(parameter!=NULL)
{
p=parameter->n;
free(parameter->name);
free(parameter->inhalt);
delete parameter;
parameter=p;
}
}
}
void httpt::basic_auth(char *username, char *password, int maxlen)
{
const char *header;
char buffer[1000], *tptr;
int len;
username[0]=password[0]=0;
header=get_header("Authorization");
if(header==NULL) return;
if(strncmp(header, "Basic ", 6)!=0) return;
header+=6;
len=base64_decode(header, buffer, 999);
buffer[len]=0;
tptr=strchr(buffer, ':');
if(tptr==NULL) return;
*(tptr++)=0;
strmaxcpy(username, buffer, maxlen-1);
strmaxcpy(password, tptr, maxlen-1);
}
httpt::~httpt()
{
clear();
}
void httpt::decode_url(string &url)
{
char mime_data=0;
int status=0;
const string buffer=url;
url="";
for(unsigned i=0; i<buffer.size(); i++)
{
char data=buffer[i];
switch(data)
{
case '\n':
case '\r':
case 0:
return;
case '%':
status=1;
break;
case '+':
url+=' ';
break;
default:
switch(status)
{
case 0:
url+=data;
break;
case 1:
status++;
if(isascii(data) && isxdigit(data))
{
if(isdigit(data))
mime_data=(data-'0')<<4;
else
mime_data=(tolower(data)-'a'+10)<<4;
}
else if(data=='%')
url+=data;
break;
case 2:
status=0;
if(isascii(data) && isxdigit(data))
{
if(isdigit(data))
mime_data|=data-'0';
else
mime_data|=tolower(data)-'a'+10;
url+=mime_data;
}
break;
default:
abort();
}
}
}
}
void cgi_httpt::cgi_parse()
{
}
void handle_httpt::read_header()
{
string buffer;
parametert p;
while(TRUE)
{
read_line(buffer);
if(buffer=="") return;
char *tptr=strchr(buffer.data(), ':');
if(tptr==NULL) return;
*tptr=0;
tptr++;
while(*tptr==' ' || *tptr=='\t') tptr++;
if(buffer[0]!=0)
{
p.n=header;
p.name=strdup(buffer.c_str());
p.inhalt=strdup(tptr);
header=new parametert;
*header=p;
}
}
}
void handle_httpt::read_request(int _handle)
{
handle=_handle;
read_command();
parse_command();
if(version!="")
read_header();
}
void handle_httpt::read_line(string &buffer)
{
buffer="";
while(TRUE)
{
char data;
if(read(handle, &data, 1)!=1)
return;
switch(data)
{
case '\n':
case 0:
return;
case '\r':
break;
default:
buffer+=data;
}
}
}
void handle_httpt::read_command()
{
read_line(command);
}
void get_url_httpt::parse_get_url(const string &_url)
{
command="GET "+_url;
parse_command();
}
void mkrfc1123(time_t t, char *s)
{
struct tm *gmt;
gmt=gmtime(&t);
s[0]=0;
strftime(s, 99, "%a, %d %b %Y %H:%M:%S GMT", gmt);
}
syntax highlighted by Code2HTML, v. 0.9.1