Implement XDG compliance, logging, and improved 401 error handling
- Install to ~/.local/bin/winamp-mpris - Use ~/.local/state/winamp-mpris/bridge.log for logging - Use $XDG_RUNTIME_DIR/winamp-mpris.pid for PID management - Add detailed user notification for 401 Unauthorized errors - Add install.sh for automated, standard-compliant setup - Include Winamp Web Interface source code and installer in repository
This commit is contained in:
280
Wawi Source/net_http_html.cpp
Normal file
280
Wawi Source/net_http_html.cpp
Normal file
@@ -0,0 +1,280 @@
|
||||
/* --- NET_HTTP_HTML.CPP ---
|
||||
/
|
||||
/ Written by Phil Himsworth, 2001-2002.
|
||||
/
|
||||
/*/
|
||||
|
||||
#include <windows.h>
|
||||
#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,"<h3>Error!</h3>\n");
|
||||
prints(conn,errstring);
|
||||
prints(conn,"<p>Back to <a href=\"\\\">main page</a></p>\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,"<h3>403 Bad Request</h3>\n");
|
||||
prints(conn,"<p>Your browser sent a request that this server could not understand.</p>\n");
|
||||
prints(conn,"<p>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,"</p>\n<hr>\n<address>Wawi - Winamp HTTP Server</address>\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<lstrlen(value);i++)
|
||||
if (value[i]=='+')
|
||||
value[i] = ' ';
|
||||
return true;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Removes '%20's and the like from a string
|
||||
void Unescape_url(char * url)
|
||||
{
|
||||
int x,y;
|
||||
|
||||
for(x=0,y=0;url[y];++x,++y) {
|
||||
if((url[x] = url[y]) == '%')
|
||||
{
|
||||
url[x] = x2c(&url[y+1]);
|
||||
y+=2;
|
||||
}
|
||||
}
|
||||
url[x] = 0;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Returns a single character from a '%xx' string
|
||||
char x2c(char *what)
|
||||
{
|
||||
char digit;
|
||||
|
||||
digit = (what[0] >= '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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user