当前位置: 首页 > 工具软件 > SHTTPD > 使用案例 >

ptpd 源码解析_shttpd源码分析(1) 初识shttpd,大概印象

潘辰龙
2023-12-01

/** This file is an example of how to embed web-server functionality

* into existing application.

* Compilation line:

* cc example.c shttpd.c -DEMBEDDED*/#ifdef _WIN32

#include#definesnprintf _snprintf#ifndef _WIN32_WCE

#ifdef _MSC_VER/*pragmas not valid on MinGW*/#pragmacomment(lib,"ws2_32")#endif/* _MSC_VER */#defineALIAS_URI "/my_c"#defineALIAS_DIR "c:\\"#else/* _WIN32_WCE *//*Windows CE-specific definitions*/#pragmacomment(lib,"ws2")//#include "compat_wince.h"#defineALIAS_URI "/my_root"#defineALIAS_DIR "\\"#endif/* _WIN32_WCE */#else#include#include#defineALIAS_URI "/my_etc"#defineALIAS_DIR "/etc/"#endif#ifndef _WIN32_WCE/*Some ANSI #includes are not available on Windows CE*/#include#include#include#endif#include#include#include#include#include"shttpd.h"/** This callback function is attached to the "/" and "/abc.html" URIs,

* thus is acting as "index.html" file. It shows a bunch of links

* to other URIs, and allows to change the value of program's

* internal variable. The pointer to that variable is passed to the

* callback function as arg->user_data.*/staticvoidshow_index(structshttpd_arg*arg)

{int*p=arg->user_data;/*integer passed to us*/charvalue[20];constchar*host,*request_method,*query_string,*request_uri;

request_method=shttpd_get_env(arg,"REQUEST_METHOD");

request_uri=shttpd_get_env(arg,"REQUEST_URI");

query_string=shttpd_get_env(arg,"QUERY_STRING");/*Change the value of integer variable*/value[0]='\0';if(!strcmp(request_method,"POST")) {/*If not all data is POSTed, wait for the rest*/if(arg->flags&SHTTPD_MORE_POST_DATA)return;

(void) shttpd_get_var("name1", arg->in.buf, arg->in.len,

value,sizeof(value));

}elseif(query_string!=NULL) {

(void) shttpd_get_var("name1", query_string,

strlen(query_string), value,sizeof(value));

}if(value[0]!='\0') {*p=atoi(value);/** Suggested by Luke Dunstan. When POST is used,

* send 303 code to force the browser to re-request the

* page using GET method. This prevents the possibility of

* the user accidentally resubmitting the form when using

* Refresh or Back commands in the browser.*/if(!strcmp(request_method,"POST")) {

shttpd_printf(arg,"HTTP/1.1 303 See Other\r\n""Location: %s\r\n\r\n", request_uri);

arg->flags|=SHTTPD_END_OF_OUTPUT;return;

}

}

shttpd_printf(arg,"%s","HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n""

Welcome to embedded example of SHTTPD");

shttpd_printf(arg,"v. %s

  • ", shttpd_version());

shttpd_printf(arg,"

REQUEST_METHOD: %s""REQUEST_URI: \"%s\"QUERY_STRING: \"%s\"""REMOTE_ADDR: %s REMOTE_USER: \"(null)\"
",

request_method, request_uri,

query_string?query_string :"(null)",

shttpd_get_env(arg,"REMOTE_ADDR"));

shttpd_printf(arg,"

Internal int variable value: %d",*p);

shttpd_printf(arg,"%s","

Enter new value:""""");

shttpd_printf(arg,"%s","

Enter new value:""""");

shttpd_printf(arg,"%s","


""Protected page (guest:guest)
"" Output lots of data
"" Aliased"ALIAS_DIR"directory
");

shttpd_printf(arg,"%s","

On-disk file (Makefile)
"" Wildcard URI example
"" Custom 404 handler
");

host=shttpd_get_header(arg,"Host");

shttpd_printf(arg,"

'Host' header value: [%s]
",

host?host :"NOT SET");

shttpd_printf(arg,"

Upload file example.""""");

shttpd_printf(arg,"%s","");

arg->flags|=SHTTPD_END_OF_OUTPUT;

}/** This callback is attached to the URI "/post"

* It uploads file from a client to the server. This is the demostration

* of how to use POST method to send lots of data from the client.

* The uploaded file is saved into "uploaded.txt".

* This function is called many times during single request. To keep the

* state (how many bytes we have received, opened file etc), we allocate

* a "struct state" structure for every new connection.*/staticvoidshow_post(structshttpd_arg*arg)

{constchar*s,*path="uploaded.txt";structstate {

size_t cl;/*Content-Length*/size_t nread;/*Number of bytes read*/FILE*fp;

}*state;/*If the connection was broken prematurely, cleanup*/if(arg->flags&SHTTPD_CONNECTION_ERROR&&arg->state) {

(void) fclose(((structstate*) arg->state)->fp);

free(arg->state);

}elseif((s=shttpd_get_header(arg,"Content-Length"))==NULL) {

shttpd_printf(arg,"HTTP/1.0 411 Length Required\n\n");

arg->flags|=SHTTPD_END_OF_OUTPUT;

}elseif(arg->state==NULL) {/*New request. Allocate a state structure, and open a file*/arg->state=state=calloc(1,sizeof(*state));

state->cl=strtoul(s, NULL,10);

state->fp=fopen(path,"wb+");

shttpd_printf(arg,"HTTP/1.0 200 OK\n""Content-Type: text/plain\n\n");

}else{

state=arg->state;/** Write the POST data to a file. We do not do any URL

* decoding here. File will contain form-urlencoded stuff.*/(void) fwrite(arg->in.buf, arg->in.len,1, state->fp);

state->nread+=arg->in.len;/*Tell SHTTPD we have processed all data*/arg->in.num_bytes=arg->in.len;/*Data stream finished? Close the file, and free the state*/if(state->nread>=state->cl) {

shttpd_printf(arg,"Written %d bytes to %s",

state->nread, path);

(void) fclose(state->fp);

free(state);

arg->flags|=SHTTPD_END_OF_OUTPUT;

}

}

}/** This callback function is attached to the "/secret" URI.

* It shows simple text message, but in order to be shown, user must

* authorized himself against the passwords file "passfile".*/staticvoidshow_secret(structshttpd_arg*arg)

{

shttpd_printf(arg,"%s","HTTP/1.1 200 OK\r\n");

shttpd_printf(arg,"%s","Content-Type: text/html\r\n\r\n");

shttpd_printf(arg,"%s","

");

shttpd_printf(arg,"%s","

This is a protected page");

arg->flags|=SHTTPD_END_OF_OUTPUT;

}/** This callback function is attached to the "/huge" URI.

* It outputs binary data to the client.

* The number of bytes already sent is stored directly in the arg->state.*/staticvoidshow_huge(structshttpd_arg*arg)

{intstate=(int) arg->state;if(state==0) {

shttpd_printf(arg,"%s","HTTP/1.1 200 OK\r\n");

shttpd_printf(arg,"%s","Content-Type: text/plain\r\n\r\n");

}while(arg->out.num_bytesout.len) {

arg->out.buf[arg->out.num_bytes]=state%72?'A':'\n';

arg->out.num_bytes++;

state++;if(state>1024*1024) {/*Output 1Mb Kb of data*/arg->flags|=SHTTPD_END_OF_OUTPUT;break;

}

}

arg->state=(void*) state;

}/** This callback function is used to show how to handle 404 error*/staticvoidshow_404(structshttpd_arg*arg)

{

shttpd_printf(arg,"%s","HTTP/1.1 200 OK\r\n");

shttpd_printf(arg,"%s","Content-Type: text/plain\r\n\r\n");

shttpd_printf(arg,"%s","Oops. File not found!");

shttpd_printf(arg,"%s","This is a custom error handler.");

arg->flags|=SHTTPD_END_OF_OUTPUT;

}/** This callback function is attached to the wildcard URI "/users/.*"

* It shows a greeting message and an actual URI requested by the user.*/staticvoidshow_users(structshttpd_arg*arg)

{

shttpd_printf(arg,"%s","HTTP/1.1 200 OK\r\n");

shttpd_printf(arg,"%s","Content-Type: text/html\r\n\r\n");

shttpd_printf(arg,"%s","

");

shttpd_printf(arg,"%s","

Hi. This is a wildcard uri handler""for the URI /users/*/

");

shttpd_printf(arg,"

URI: %s

",

shttpd_get_env(arg,"REQUEST_URI"));

arg->flags|=SHTTPD_END_OF_OUTPUT;

}/** This function will be called on SSI directive , or

* , and 'returns' TRUE condition*/staticvoidssi_test_true(structshttpd_arg*arg)

{

arg->flags|=SHTTPD_SSI_EVAL_TRUE;

}/** This function will be called on SSI directive , or

* , and 'returns' FALSE condition*/staticvoidssi_test_false(structshttpd_arg*arg)

{/*Do not set SHTTPD_SSI_EVAL_TRUE flag, that means FALSE*/}/** This function will be called on SSI */staticvoidssi_print_stuff(structshttpd_arg*arg)

{

time_t t=time(NULL);

shttpd_printf(arg,"SSI user callback output: Current time: %s", ctime(&t));

arg->flags|=SHTTPD_END_OF_OUTPUT;

}

 类似资料: