📄 webserver.c
字号:
void post_method(int plug_handle )
{
int result;
char http_intro[k_string_length];
tcp_control.still_receiving_http_request = 0;
http_response.http_result_code_and_message = "200 OK";
http_response.http_content_type = http_request.url[strlen(http_request.url) - 1] == 'f'
? "image/gif" : "text/html";
http_response.html_response[0] = 0;
if(http_response.html_response_length == 0)
http_response.html_response_length = strlen(http_response.html_response);
// |
// | Load response structure
// |
sprintf(http_intro,"HTTP/1.1 %s\r\nContent-type: %s\r\n\r\n",
http_response.http_result_code_and_message,
http_response.http_content_type
);
nr_plugs_send(plug_handle,http_intro,strlen(http_intro),0);
result = get_content_length();
get_entity_data(NULL, NULL, result, plug_handle);
}
// +--------------------------------------------
// | r_get_html_from_wosfs(url,html_out,html_length_out)
// |
// | Look for a WOSFS file with a file name
// | matching the URL, and fill html_out with
// | its contents if found. If no such file
// | is found, return result -1.
// |
// | The length is also returned, since it
// | might be a gif image, and strlen will not
// | work on that.
// |
static int r_get_html_from_wosfs(char *url,char *html_out,int *html_length_out)
{
ns_wosfs_directory_entry de;
int result = 0;
int file_index;
file_index = nr_wosfs_get_directory_entry_by_name(url,&de);
if(file_index >= 0)
{
// |
// | Found a wosfs file with the same name
// | as the url requested. Get the file contents.
// | Also, add a null terminator, to make it
// | a C string.
// |
nr_wosfs_read(file_index,0,de.file_length,html_out); // should check length...
html_out[de.file_length] = 0; // c string terminator
*html_length_out = de.file_length; // and return the length, too
}
else
result = -1;
return result;
}
// +--------------------------------------------
// | r_get_html_404(url,html_out)
// |
// | Construct a 404 error message page.
// |
static int r_get_html_404(char *url,char *html_out)
{
ns_wosfs_directory_entry de;
int result = 0;
int file_index;
printf("[r_get_html_404] Assembling 404 Error\n");
file_index = nr_wosfs_get_directory_entry_by_name("404_page.html",&de);
if(file_index >= 0)
{
nr_wosfs_read(file_index,0,de.file_length,html_out);
html_out[de.file_length] = 0; // C string terminator
// |
// | r_substitute_string() searches for the first
// | occurence of "%s" and replaces it with the string
// | (in this case the URL, so the error page can say
// | what the bad URL was)
// |
r_substitute_string(html_out,url);
}
else
{
// |
// | This shouldnt happen, only if our wosfs
// | is missing the file "404_page.html".
// |
strcpy(html_out,"<h1>404: File Not Found</h1>");
}
return result;
}
// +-----------------------------------------------
// | r_get_html_dynamically(url,url_and_args,html_out)
// |
// | This routine generates any dynamic html for the web server
// | It first retrieves a wosfs file named "<url>.template", if
// | any, and then checks for several possible dynamically
// | generated pages. If it's not one of those, return an error.
// |
static int r_get_html_dynamically(char *url,char *url_and_args,char *html_out)
{
char template_file[k_string_length];
ns_wosfs_directory_entry de;
int result = 0;
int file_index;
strcpy(template_file,url);
strcat(template_file,".template");
printf("[r_get_html_dynamically] looking for template %s\n",template_file);
file_index = nr_wosfs_get_directory_entry_by_name(template_file,&de);
if(file_index >= 0)
{
nr_wosfs_read(file_index,0,de.file_length,html_out); // should check length...
html_out[de.file_length] = 0;
}
else
html_out[0] = 0;
if(!strcmp(url,"template_page.html"))
{
// |
// | General Info page
// | Fill in a couple of blanks
// | with the number of web inquiries so far,
// | and the number of milliseconds since starting
// |
char s[k_string_length];
sprintf(s,"%4d",tcp_control.inquiry_number); // s must be more than 2 chars long!
r_substitute_string(html_out,s);
sprintf(s,"%4d",nr_timer_milliseconds()); // s must be more than 2 chars long!
r_substitute_string(html_out,s);
}
else if(!strcmp(url,"dynamic_page.html"))
{
// |
// | The memory dump page is generated entirely in this
// | routine. No WOSFS file is used.
// |
char x[k_string_length];
char *w;
char c;
int i;
int j;
int address;
sprintf(html_out,"<HTML><HEAD><TITLE>Nios</TITLE><BODY BGCOLOR=#FFFFFF><BLOCKQUOTE><H1><A HREF=index.html><IMG SRC=exc-nios.gif BORDER=0></A>Nios Memory Dump</H1><HR><BLOCKQUOTE><PRE>");
r_get_cgi_param(url_and_args,"address",x);
w = x;
address = 0;
while((c = *w++) != 0)
{
if(c > '9')
c += 9;
address = (address << 4) + (c & 0x0f);
}
for(j = address; j < address + 1024; j += 32)
{
sprintf(html_out+strlen(html_out),"%08x: ",0x000000+j);
for(i = 0; i < 32; i++)
{
sprintf(html_out+strlen(html_out),"%02x ",*(unsigned char *)(0x000000 + j + i));
}
sprintf(html_out+strlen(html_out)," : ");
for(i = 0; i < 32; i++)
{
c = *(unsigned char *)(0x000000 + j + i);
if(c < 32 || c > 0x7e)
c = '.';
if(c == '<')
sprintf(html_out+strlen(html_out),"<");
else
sprintf(html_out+strlen(html_out),"%c",c);
}
sprintf(html_out+strlen(html_out),"\n");
}
sprintf(html_out+strlen(html_out),"</PRE></BLOCKQUOTE><HR> <FORM ACTION=dynamic_page.html name=a_form> <INPUT TYPE=submit name=next value=\"Show Next 1024 bytes\"> <INPUT TYPE=hidden name=address value=%08x> </FORM><HR> <FORM ACTION=dynamic_page.html name=b_form> Base Address: <INPUT TYPE=text name=address size=30> <INPUT TYPE=submit name=submit value=Show> </FORM><HR><A HREF=index.html>Home</A></BLOCKQUOTE></BODY></HTML>",address+1024);
}
else
{
// |
// | Else, it's a dynamic url we dont know about. return error.
// |
result = -1;
}
return result;
}
// +-------------------------------------
// | r_substitute_string(char *fmt,char *s)
// |
// | Scan fmt for the first occurence of
// | "%s", and replace it with string s.
// |
// | Very useful for implementing dynamic
// | pages where a few parts are written
// | in with values or something.
// |
static int r_substitute_string(char *fmt,char *s)
{
int result = 0;
int i;
int fmt_len;
int s_len;
fmt_len = strlen(fmt);
s_len = strlen(s);
for(i = 0; i < (fmt_len - 1); i++)
{
if(fmt[i] == '%' && fmt[i + 1] == 's')
{
// |
// | found "%s", move stuff around a bit.
// |
bcopy(fmt + i,fmt + i + s_len - 2,fmt_len - i + 1); // -2 for %s itself
bcopy(s,fmt + i,s_len);
goto go_home;
}
}
result = -1; // didnt find %s, so didnt do substitution
go_home:
return result;
}
// +------------------------------------------
// | Given a pointer to a char *, read a string until
// | either a null terminator or the until_character
// | is hit. Leave the char * pointing to this
// | last character.
static void r_read_string_until(char **wp,char *string_out,char until_character)
{
char *w = *wp;
char c;
while(1)
{
c = *w;
if(c == 0 || c == until_character)
goto go_home;
if(c == '+') // | http, + means blank
c = ' ';
else if(c == '%') // | http, %AB is hex encoding
{
char a;
w++;
c = *w;
if(!c)
goto go_home;
c -= '0';
if(c > 9)
c = (c & 15) + 9;
a = *w;
if(!a)
goto go_home;
a -= '0';
if(a > 9)
a = (a & 15) + 9;
c += (a<<4);
}
*string_out++ = c;
w++;
}
go_home:
*string_out = 0;
*wp = w;
}
// +---------------------------------------------------
// | Extract a single CGI parameter from the arguments
// |
// | URL and arguments are of the form
// |
// | <url>?<param>=<val>+<param>=<val>...
// |
// | Example: /controls/index.html?number=300&menu=fish
// |
// | This routine takes that URL and arguments string and
// | pulls out the named parameter into a string you
// | pass in. If you pass NULL for the parameter, it
// | extracts just the URL.
// | If the named parameter is not present, it returns
// | a zero-length string for the value_out.
// |
static void r_get_cgi_param(char *url_and_args,char *parameter, char *value_out)
{
char *w;
char this_param[k_string_length];
value_out[0] = 0; // assume empty string output
// | First, advance past url, to the parameters
w = url_and_args;
// |
// | Read the first thing, the URL
// |
r_read_string_until(&w,value_out,'?');
// |
// | parameter=NULL means we wanted the URL
// | Which we have just found.
// |
if(parameter == 0)
goto go_home;
// |
// | Read each param name & param value, and then see if it's
// | the one we are looking for.
// |
read_next_param_name:
// |
// | *w was left pointing at either 0 or the until_char of last segment
// |
value_out[0] = 0;
if(*w++ == 0)
goto go_home;
value_out[0] = 0;
r_read_string_until(&w,this_param,'=');
if(*w++ == 0)
goto go_home;
r_read_string_until(&w,value_out,'&');
if(nr_wosfs_string_match(this_param,parameter))
return;
// |
// | if not, go up there & try again
// |
goto read_next_param_name;
go_home:
return;
}
// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -