📄 nedk_example_web_server.c
字号:
// |
// | Send the HTTP stuff
// |
sprintf(http_intro,"HTTP/1.1 %s\r\nContent-type: %s\r\n\r\n",
http_result_code_and_message,
http_content_type
);
nr_plugs_send(plug_handle,http_intro,strlen(http_intro),0);
}
{
int this_packet;
int size_left = html_response_length;
char *w = html_response;
int mtu = 512;
// |
// | And send the HTML, broken up into MTU sized bits
// |
while(size_left)
{
this_packet = size_left;
if(this_packet > mtu)
this_packet = mtu;
nr_plugs_send(plug_handle,w,this_packet,0);
size_left -= this_packet;
w += this_packet;
}
}
// And close the connection by re-listening
r_start_listening();
}
}
// +--------------------------------------------
// | 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",g.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: ",j);
for(i = 0; i < 32; i++)
sprintf(html_out+strlen(html_out),"%02x ",*(unsigned char *)(j + i));
sprintf(html_out+strlen(html_out)," : ");
for(i = 0; i < 32; i++)
{
c = *(unsigned char *)(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;
}
// +-----------------------------------
// | r_printable_string
// |
// | return a char * to the string with
// | all unprintable characters replaced
// | with some oddball symbol. (Uses a
// | static string buffer, so only the
// | most recent result of this function
// | is available.)
static char *r_printable_string(char *s)
{
int c;
static char printable_string[k_string_length];
int i = 0;
while((c = *s++) != 0 && i < (k_string_length - 1))
{
if(c < 0x20 || c > 0x7e)
c = 21;
printable_string[i++] = c;
}
printable_string[i] = 0;
return printable_string;
}
// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -