[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libmicrohttpd] How to give busy message to second file upload clien
From: |
Christian Grothoff |
Subject: |
Re: [libmicrohttpd] How to give busy message to second file upload client when 1st client file |
Date: |
Fri, 22 Aug 2008 15:59:07 -0600 |
User-agent: |
KMail/1.9.9 |
First of all, a rejection message for a POST as you propose should be put in
here (to be send instead of 100 CONTINUE):
if( NULL == con_info ){
return;
}
Other than that, I would strongly urge you to write your code to handle
concurrent uploads, users are unlikely to be happy with a server that
is "busy".
I hope this helps...
Christian
On Wednesday 20 August 2008 08:15:02 am sudhansu sahoo wrote:
> Hello,
> Thank you very much for your help, Now I am able to upload files into
> server using libmicrohttpd(code attached below) successfully.
>
> I am trying to write code to upload one file at a time into the server, so
> if any other user try to upload his file while 1st user's file upload is in
> progress he should get a message that " Server is busy processing another
> user's request so please wait". I thought this message can be placed in "
> postexample_answerRequest" method as shown below in the code example but
> not able to do that as the client connection is refused rather than getting
> a message that server is busy. Could you please have a look into the code
> below and help me where I can put this message?
>
>
>
>
>
> FileUpload.c
> ==============
>
>
>
> #include <microhttpd.h>
> #include <string.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <pthread.h>
>
> #define PORT 8888
> #define POSTBUFFERSIZE (1024)
> #define MAXNAMESIZE (32 * 1024)
> #define MAXANSWERSIZE (512)
>
> #define GET 0
> #define POST 1
> #define TRUE 1
> #define FALSE 0
>
>
>
> static pthread_mutex_t fileUploadMutex = PTHREAD_MUTEX_INITIALIZER;;
>
>
> #define u8 unsigned char
> struct connection_info_struct {
>
> int connectiontype;
> char *answerstring;
> struct MHD_PostProcessor * postprocessor;
> };
>
> const char* askpage = "<form enctype=multipart/form-data action=put
> method=POST>Choose a file to upload: <input name=uploadedfile type=file
> /><br /><input type=submit value=Upload File /><input type=reset
> value=Cancel /></form>";
>
> const char* greatingpage = "<html><body><h1>Welcome,
> %s!</center></h1></body></html>";
> const char* errorpage = "<html><body>This doesn't seem to be
> right.</body></html>";
>
>
>
> void
> postexample_unlock( void ) {
> pthread_mutex_unlock( &fileUploadMutex );
> }
>
> u8
> postexample_lockObtained( void ) {
> if( pthread_mutex_trylock( &fileUploadMutex ) == 0 ) {
> return TRUE;
> }
> return FALSE;
> }
>
> int
> postexample_sendPage( struct MHD_Connection * connection,
> const char * page ) {
>
> int ret;
> struct MHD_Response *response;
>
>
> response =
> MHD_create_response_from_data( strlen( page),
> ( void* ) page,
> MHD_NO, MHD_NO );
>
> if( !response ) {
>
> return MHD_NO;
> }
>
> ret = MHD_queue_response( connection, MHD_HTTP_OK, response );
> MHD_destroy_response (response);
>
> return ret;
> }
>
> static FILE * inputFile = NULL;
>
> static u8
> postexample_openFile( const char * filename ) {
>
> u8 filenameBuf[ 256 ];
> if( !filename ) {
> return FALSE;
> }
>
> memset( filenameBuf, 0, sizeof( filenameBuf ));
> strcpy( filenameBuf, "/tmp/" );
> strcat( filenameBuf, filename );
>
> inputFile = fopen( filenameBuf, "wb+" );
>
> if( !inputFile ) {
> return FALSE;
> }
>
> printf( "postexample_openFile: opened the file \n " );
>
> return TRUE;
> }
>
> static u8
> SaveData( const char * data, size_t offset, size_t size ) {
>
> if( !inputFile || !size ) {
> return FALSE;
> }
>
> if( fseek( inputFile, offset, SEEK_SET ) ) {
>
> return FALSE;
> }
>
> if( size != fwrite( data, sizeof( unsigned char ), size, inputFile ) ) {
> return FALSE;
> }
> #ifdef UPLOAD_DEBUG
> printf( "SaveData: wrote %d bytes \n", size );
> #endif
>
> return TRUE;
> }
>
>
> static u8
> postexample_closeFile( void ) {
>
>
> fclose( inputFile );
> return TRUE;
> }
>
> int
> postexample_iteratePost( void * coninfo_cls,
> enum MHD_ValueKind kind, const
> char * key,
> const char * filename,
> const char * content_type,
> const char * transfer_encoding,
> const char * data,
> size_t offset,
> size_t size ) {
>
>
> struct connection_info_struct * con_info =
> (struct connection_info_struct*) coninfo_cls;
>
> #ifdef UPLOAD_DEBUG
> printf( "ValueKind is : %d \n", kind );
> printf( "KEY Value is : %s \n", key );
> printf( "Filename is : %s \n", filename );
> printf( "Content-Type is : %s \n", content_type );
> printf( "Transfer-encoding is : %s \n", transfer_encoding );
> printf( "Data-Offset : %d \n", offset );
>
> #endif
>
> printf( "Data-Size : %d \n", size );
>
> if( offset == 0 ) {
> /* If offset 0 then make sure file is closed first
> * it at all it is open. Then open the file.
> */
>
> postexample_closeFile();
>
> postexample_openFile( filename );
> }
>
> if( !strcmp( key, "uploadedfile" ) ) {
>
> if( (size > 0) && (size <= MAXNAMESIZE) ) {
>
> SaveData( data, offset, size );
> }
>
> return MHD_YES;
> }
>
> return MHD_YES;
> }
>
> void
> postexample_requestCompleted( void * cls,
> struct MHD_Connection *connection,
> void **con_cls,
> enum
> MHD_RequestTerminationCode toe ) {
>
> struct connection_info_struct *con_info =
> (struct connection_info_struct*) *con_cls;
>
>
>
> if( NULL == con_info ){
> return;
> }
>
> if( con_info->connectiontype == POST ) {
>
> MHD_destroy_post_processor( con_info->postprocessor );
> snprintf( con_info->answerstring, MAXANSWERSIZE,
> greatingpage, "Wait" );
>
>
> if( con_info->answerstring ) {
> free( con_info->answerstring );
> }
>
> /* Release the lock so other users can proceed to upload files
> */
> postexample_unlock();
>
> printf( "Request is completed....unlocked! \n" );
>
> }
>
> free( con_info );
> }
>
>
> int
> postexample_answerRequest( void * cls,
> struct MHD_Connection * connection,
> const char * url,
> const char * method,
> const char * version,
> const char * upload_data,
> unsigned int * upload_data_size,
> void ** con_cls ) {
>
> if( NULL == *con_cls ) {
>
> struct connection_info_struct * con_info;
>
> con_info = malloc( sizeof (struct connection_info_struct) );
>
> if( NULL == con_info ) {
>
> return MHD_NO;
> }
>
> if( (!strcmp( method, "POST" )) && (!postexample_lockObtained()) ) {
>
> /* Failed to acquire lock to upload a file
> *
> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
> * Want to give a message to the client that server is busy
> processing another
> * user request so please wait.
> *
> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
> */
> return MHD_NO;
> }
>
> if( !strcmp( method, "POST" )) {
>
> printf( "postexample: creating postProcessor-1. lock acquired\n " );
>
> con_info->answerstring = malloc( MAXANSWERSIZE );
>
> if( !con_info->answerstring ) {
> return MHD_NO;
> }
>
> con_info->postprocessor =
> MHD_create_post_processor( connection, POSTBUFFERSIZE,
> postexample_iteratePost,
> (void *)con_info );
>
> if( NULL == con_info->postprocessor ) {
>
> free (con_info);
> return MHD_NO;
> }
>
> con_info->connectiontype = POST;
>
>
> } else {
>
> con_info->connectiontype = GET;
> }
>
> *con_cls = ( void* )con_info;
>
> return MHD_YES;
> }
>
> if( !strcmp( method, "GET" )) {
>
> return postexample_sendPage( connection, askpage );
> }
>
> if( !strcmp( method, "POST" ) ) {
>
> struct connection_info_struct *con_info = *con_cls;
>
> if( *upload_data_size != 0 ){
>
> struct MHD_Response *response;
>
> //printf( "postexample: calling MHD_post_process \n " );
>
> MHD_post_process( con_info->postprocessor, upload_data,
> *upload_data_size );
>
> *upload_data_size = 0;
> return MHD_YES;
>
> } else {
>
> printf( "postexample_closeFile: closed the file \n " );
>
> postexample_closeFile();
>
> if( con_info->answerstring ) {
>
> snprintf( con_info->answerstring, MAXANSWERSIZE,
> greatingpage, "GotData" );
> }
>
> return postexample_sendPage( connection,
> con_info->answerstring );
> }
> }
>
> return postexample_sendPage( connection,
> errorpage );
> }
>
> int
> main() {
>
> struct MHD_Daemon * daemon;
>
> daemon = MHD_start_daemon( MHD_USE_THREAD_PER_CONNECTION,
> PORT,
> NULL, NULL,
> &postexample_answerRequest, NULL,
> MHD_OPTION_NOTIFY_COMPLETED,
> postexample_requestCompleted, NULL,
> MHD_OPTION_END );
>
> if( !daemon ) {
> return 1;
> }
>
> while( 1 ) {
> /* Sleep for ever */
> sleep( 0xeffffff );
> }
>
> MHD_stop_daemon( daemon );
>
> return 0;
> }