#include "types.h"
#include "main.h"
#include "resource.h"
#include "html.h"
// --------------------------------------------------------------------------------
// *** SOCKET FUNCTIONS ***
// Low level socket writing function - strings
void prints(connection * conn, char * string)
{
if (lstrlen(conn->output) + lstrlen(string) >= BUF_LEN)
flush(conn);
lstrcat(conn->output, string);
}
// Write full buffer down the socket
void flush(connection * conn)
{
int i = lstrlen(conn->output);
if (send(conn->socket,conn->output,i,0) == SOCKET_ERROR)
{
//MessageBox(NULL,"Socket send() error!","gen_httpsrv error",MB_OK);
}
// Clear buffer - set first char to null character
conn->output[0] = 0;
}
// Low level socket writing function - integers
void printsi(connection * conn,int number)
{
char buffer[256];
wsprintf(buffer,"%d",number); // Stick it in a string and call prints()
prints(conn,(char*)&buffer);
}
// Report an error to the client
void ReportError(connection * conn, char * errstring)
{
OpenHTTPHeader(conn,"text/html",0,NULL);
OpenHtmlHeader(conn);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"Error!
\n");
prints(conn,errstring);
prints(conn,"Back to main page
\n");
}
// 400 Bad Request error
void Send400(connection * conn)
{
prints(conn,"HTTP/1.0 400 Bad Request\nConnection: close\nContent-type: \"text/html\"\n\n");
OpenHtmlHeader(conn);
Style(conn);
CloseHeader(conn);
OpenPageBody(conn);
prints(conn,"403 Bad Request
\n");
prints(conn,"Your browser sent a request that this server could not understand.
\n");
prints(conn,"Invalid URI in request ");
prints(conn,conn->http.request);
prints(conn," ");
prints(conn,conn->http.file);
prints(conn," ");
prints(conn,conn->http.http_version);
prints(conn,"
\n
\nWawi - Winamp HTTP Server\n");
CloseBody(conn);
};
// --------------------------------------------------------------------------------
// Receives HTTP header and puts relevant information into http_request structure
bool GetRequest(connection * conn)
{
char buffer[2048];
int buffer_len;
int buffer_filled = 0;
int buffer_left;
bool complete = false;
while(true)
{
// receive data
buffer_len = sizeof(buffer);
buffer_left = buffer_len-buffer_filled;
if (buffer_left <= 0)
buffer_len = 0;
else
buffer_len = recv(conn->socket,buffer + buffer_filled,buffer_len-buffer_filled,0);
if (buffer_len != SOCKET_ERROR && buffer_len != 0)
{
buffer_filled += buffer_len;
// scan for end of header
for (int i=0;i<=buffer_filled;i++)
if (buffer[i]=='\n' && (buffer[i+1]=='\n' || buffer[i+2]=='\n'))
{
buffer[i+1] = 0;
//MessageBox(NULL,buffer,"gen_httpsrv debug", MB_OK);
char * chptr = (char*)&buffer;
chptr = GetAString(chptr,conn->http.request);
chptr = GetAString(chptr,conn->http.file);
chptr = GetAString(chptr,conn->http.http_version);
FindBasicAuth(conn,chptr);
if (StrComp(conn->http.request,"HEAD"))
conn->http.reqID = RID_HEAD;
else
conn->http.reqID = RID_GET;
if (!DecodeUrl(conn))
return false;
//ListArgs(conn);
return true;
}
}
else
{
return false;
}
}
}
// --------------------------------------------------------------------------------
// Faffs around with the URL; splits 'page' from 'file' and places args in array
bool DecodeUrl(connection * conn)
{
lstrcpy(conn->http.page,conn->http.file); // make page = file
conn->http.num_args = 0;
char * chptr = conn->http.file;
while (chptr[0] != '?') // skip past '?' url?name=value
{
if (chptr[0] == 0)
{
//MessageBox(NULL,"No args","decodeurl",MB_TOPMOST | MB_OK);
return true; // no '?', no arguments
}
chptr++;
}
chptr[0] = 0;
lstrcpy(conn->http.page,conn->http.file); // alter page to remove arguments
chptr[0] = '?';
chptr++;
//char temp[100];
int x=0;
while(x < 50) // max name/value pairs; usually stopped by return in loop
{
chptr = GetDelimitedString(chptr,'=',conn->http.pairs[x].name,30);
if (chptr == NULL)
{
//MessageBox(NULL,"no value","decodeurl",MB_TOPMOST | MB_OK);
return false;
}
chptr++;
chptr = GetDelimitedString(chptr,'&',conn->http.pairs[x].value,128);
if (chptr == NULL)
{
//MessageBox(NULL,"All args","decodeurl",MB_TOPMOST | MB_OK);
conn->http.num_args = x+1;
return true;
}
chptr++;
//wsprintf(temp,"name: %s\nvalue: %s",conn->http.pairs[x].name,conn->http.pairs[x].value);
//MessageBox(NULL,temp,"arg",MB_OK | MB_TOPMOST);
x++;
}
return false;
}
// --------------------------------------------------------------------------------
// Test function to list the arguments retrieved from the requested URL
void ListArgs(connection * conn)
{
int x=0;
char string[100];
while (conn->http.pairs[x].name[0] != 0)
{
wsprintf(string,"Name: %s\nValue: %s",conn->http.pairs[x].name,conn->http.pairs[x].value);
MessageBox(NULL,string,"args",MB_OK | MB_TOPMOST);
x++;
}
}
// --------------------------------------------------------------------------------
// Return the value of an argument
bool GetArgValue(connection * conn, char * name, char * value, int len)
{
int x=0;
while(conn->http.pairs[x].name[0] != 0)
{
if (StrComp(name,conn->http.pairs[x].name))
{
//MessageBox(NULL,conn->http.pairs[x].value,"found",MB_OK | MB_TOPMOST);
lstrcpyn(value,conn->http.pairs[x].value,len);
for (int i=0;i= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
digit *= 16;
digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
return(digit);
}
// --------------------------------------------------------------------------------
// Formats string into a URL properly
void Escape_url(char * url)
{
char echars[] = " <>#%{}|\\^~[]`;/?:@=&"; // characters which have to be escaped
char eurl[255];
int x=0,y=0;
while (url[x] != 0)
{
if (contains(echars,url[x]))
{
wsprintf(eurl+y,"%%%2x",url[x]);
y+=3;
x++;
}
else
{
eurl[y] = url[x];
y++;
x++;
}
}
eurl[y] = 0;
lstrcpy(url,eurl);
}