예제 #1
0
static int sendResponse(Session *sn, Request *rq, HTTPResponse *resp)
{
   pb_param *pb_entry;

   /*
    *	collect up the headers
    */
   pb_entry = pblock_remove(CONTENT_TYPE,rq->srvhdrs);			/* remove default */
   param_free(pb_entry);			/* aB. Need to free parameters we remove from pblocks !!! */
   st_perform(resp->headers,gethdr,rq);

   /*
    *	ensure a content length
    */
   if (pblock_findval(CONTENT_LENGTH, rq->srvhdrs) == NULL) {
      char length[64];
      util_itoa(resp->content_length,length);
      pblock_nvinsert(CONTENT_LENGTH,length, rq->srvhdrs);
   }

   protocol_status(sn, rq, resp->status, resp->statusMsg);

   if (protocol_start_response(sn, rq) == REQ_NOACTION) {
      WOLog(WO_ERR,"protocol_start_response() returned REQ_NOACTION (!?)");
      return REQ_PROCEED;
   }

   if (resp->content_length)
      if (net_write(sn->csd, resp->content, resp->content_length) == IO_ERROR) {
         WOLog(WO_ERR,"Failed to send content to client");
         return REQ_EXIT;
      }

         return REQ_PROCEED;
}
예제 #2
0
HTTPResponse *resp_getResponseHeaders(WOConnection *instanceConnection, WOInstanceHandle instHandle)
{
   HTTPResponse *resp;
   String *response;

   /*
    *	get the status
    */
   response = transport->recvline(instanceConnection->fd);
   if (!response)
      return NULL;

   WOLog(WO_INFO,"New response: %s", response->text);
   resp = resp_new(response->text, instHandle, instanceConnection);

   str_free(response);
   if (resp == NULL)
      return NULL;
   
   /*
    *	followed by the headers...
    */
   while ((response = transport->recvline(instanceConnection->fd)) != NULL) {
      if (response->length == 0)
         break;
      WOLog(WO_DBG,"Header read: %s", response->text); // mstoll 13.10.2005 debug output added
      resp_addHeader(resp, response);
   }
   if((resp->flags & RESP_LENGTH_EXPLICIT) != RESP_LENGTH_EXPLICIT)
   {
      if((resp->flags & RESP_CONTENT_TYPE_SET) != RESP_CONTENT_TYPE_SET)
      {
         // no content type: no body, so content-length is implicit 0
         resp->content_length = 0;
      } else {
         // 2009/06/10: no content-length defined.  To be able to process the
         //             request although, we set the maximum allowed value and close
         //             the client socket communication if the end-of-response-
         //             stream was reached.  The maximum allowed value is UINT_MAX,
         //             because resp->content_length is defined as "unsigned".
         //             But the function used to convert a content-length string
         //             returns an int and assignments like
         //                 int value = resp->content_length;
         //             can be found in the adaptor source code.  Therefore, we
         //             should better use INT_MAX!
         resp->content_length = INT_MAX;
         WOLog(WO_WARN, "Response doesn't specify a content-length: assuming %u bytes!",
               resp->content_length);
      }
   }
   if (response)
      str_free(response);
   else {
      /* recvline() must have failed */
      resp_free(resp);
      WOLog(WO_ERR, "Error receiving headers - response dropped");
      return NULL;
   }
   return resp;
}
예제 #3
0
파일: shmem.c 프로젝트: getsharp/wonder
/*
 * Writes len bytes of zeros at the end of the open file fd.
 * Returns the number of bytes actually written. If this is
 * less than len, an error occurred (which was logged).
 * In general the size written may be larger than what was requested.
 */
static int append_zeros(int fd, int len)
{
   /* write zeros to initialize */
   int buff[1024], result, ret = 0;
   char *errMsg = NULL;

   memset(buff, 0, sizeof(buff));
   while (len > 0 && !errMsg)
   {
      if (lseek(WOShmem_fd, 0, SEEK_END) == -1)
      {
         errMsg = WA_errorDescription(WA_error());
         WOLog(WO_ERR, "append_zeros: lseek() failed: %s", errMsg);
      }
      if (!errMsg)
      {
         result = write(WOShmem_fd, buff, sizeof(buff));
         if (result == -1)
         {
            errMsg = WA_errorDescription(WA_error());
            WOLog(WO_ERR, "append_zeros: write() failed: %s", errMsg);
         } else {
            len -= result;
            ret += result;
         }
      }
   }
   if (errMsg)
      WA_freeErrorDescription(errMsg);
   return ret;
}
예제 #4
0
파일: shmem.c 프로젝트: getsharp/wonder
void *sha_checkout(ShmemArray *array, unsigned int elementNumber)
{
   void *element;
   if (elementNumber < array->elementCount)
   {
      /* read locks block if a write is pending */
#ifdef EXTRA_DEBUGGING_LOGS
       WOLog(WO_DBG, "sha_checkout(): about to check out %s element %d", array->name, elementNumber);
#endif
      WA_lock(array->elements[elementNumber].writeLock);
      WA_lock(array->elements[elementNumber].lock);
      WA_unlock(array->elements[elementNumber].writeLock);
      element = array->elements[elementNumber].element;
      /* if this was the first read lock by this process, obtain a file lock on the data as well */
      if (array->elements[elementNumber].lockCount == 0)
         array->elements[elementNumber].lockHandle = WOShmem_lock(element, array->elementSize, 0);
      array->elements[elementNumber].lockCount++;
      WA_unlock(array->elements[elementNumber].lock);
#ifdef EXTRA_DEBUGGING_LOGS
       WOLog(WO_DBG, "sha_checkout(): checked out %s element %d", array->name, elementNumber);
#endif
   } else {
      element = NULL;
      WOLog(WO_ERR, "sha_checkout(): failed to check out %s element %d", array->name, elementNumber);
   }

   return element;
}
예제 #5
0
파일: shmem.c 프로젝트: getsharp/wonder
inline static int lock_file_section(int fd, off_t start, off_t len, struct flock *lockInfo, int exclusive)
{
   int err, errCount = 0;
   do {
      lockInfo->l_start = start;
      lockInfo->l_len = len;
      lockInfo->l_type = exclusive ? F_WRLCK : F_RDLCK;
      lockInfo->l_whence = SEEK_SET;
      if (fcntl(WOShmem_fd, F_SETLKW, lockInfo) == -1)
      {
         err = WA_error();
         errCount++;
         if (err != EAGAIN || errCount % 10 == 0)
         {
            char *errMsg = WA_errorDescription(err);
            WOLog(WO_ERR, "lock_file_section(): failed to lock (%d attempts): %s", errCount, errMsg);
            WA_freeErrorDescription(errMsg);
         }
         if (err == EAGAIN)
         {
            WA_yield();
            if (errCount > LOCK_RETRY_SLEEP_COUNT)
               sleep(1);
            if (errCount > LOCK_RETRY_FAIL_COUNT)
            {
               WOLog(WO_ERR, "lock_file_section(): could not aquire lock after %d attempts. Giving up.", LOCK_RETRY_FAIL_COUNT);
            }
         }
      } else
         err = 0;
   } while (err == EAGAIN && errCount < LOCK_RETRY_FAIL_COUNT);
   return err;
}
예제 #6
0
static TR_STATUS sendbytes(net_fd appfd, const char *buf, int len)
{
   int remaining, sent, n;
   int s = appfd->s;
   struct timeval tv;
   fd_set wset;
   TR_STATUS ret = TR_OK;

   if (appfd->status != TR_OK)
      return TR_ERROR;
   
   remaining = len;
   while (remaining > 0 && ret == TR_OK) {
      while((sent = send(s, (void *)buf, remaining, 0)) < 0 && ret == TR_OK) {
         int ec = WA_error();
         if (WA_wouldBlock(ec)) {
            FD_ZERO(&wset);
            FD_SET(s, &wset);
            tv.tv_sec = appfd->send_to;
            tv.tv_usec = 0;

            n = select(s + 1, NULL, &wset, NULL, &tv);
            if (n == 0) {
               /* Timed out */
               WOLog(WO_DBG, "sendbytes(): timed out");
               ret = TR_TIMEOUT;
               break;
            } else if (n < 0) {
               char *errMsg = WA_errorDescription(WA_error());
               WOLog(WO_ERR, "sendbytes(): select error: %s", errMsg);
               WA_freeErrorDescription(errMsg);
               ret = TR_ERROR;
               break;
            }
            /* Drop back into the while loop and retry the send() */
         } else if (WA_intr(ec)) {
            /* Try send again */
         } else if (WA_brokenPipe(ec)) {
            ret = TR_RESET;
         } else {
            /* If we get EPIPE or any other error, bail out. */
            char *errMsg = WA_errorDescription(WA_error());
            WOLog(WO_ERR, "sendbytes(): send error: %s", errMsg);
            WA_freeErrorDescription(errMsg);
            ret = TR_ERROR;
            break;
         }
      }

      /* if we get here with sent < 0, we have a failure */
      if (ret != TR_OK && ret != TR_RESET) {
         WOLog(WO_ERR,"sendbytes(): failed to send data to app");
      } else {
         remaining -= sent;
         buf += sent;
      }
   }
   return ret;
}
예제 #7
0
파일: request.c 프로젝트: desertsky/wonder
int req_sendRequest(HTTPRequest *req, net_fd socket)
{
   struct iovec *buffers, *bufferIterator;
   int bufferCount, result;

   buffers = WOMALLOC((st_count(req->headers) * 4 + 3) * sizeof(struct iovec));
   buffers[0].iov_base = req->request_str;
   buffers[0].iov_len = strlen(req->request_str);
   bufferIterator = &buffers[1];
   st_perform(req->headers, (st_perform_callback)setupIOVec, &bufferIterator);
   bufferIterator->iov_base = "\r\n";
   bufferIterator->iov_len = 2;
   bufferCount = st_count(req->headers) * 4 + 2;
   if (req->content_length > 0)
   {
      bufferCount++;
      bufferIterator++;
      bufferIterator->iov_base = req->content;
      bufferIterator->iov_len = req->content_buffer_size;
   }
   result = transport->sendBuffers(socket, buffers, bufferCount);

   /* If we are streaming the content data, continue until we have sent everything. */
   /* Note that we reuse buffers, and the existing content-data buffer. */
   if (req->content_length > req->content_buffer_size)
   {
      long total_sent = req->content_buffer_size;
      long len_read, amount_to_read;
      req->haveReadStreamedData = 1;
      while (total_sent < req->content_length && result == 0)
      {
         amount_to_read = req->content_length - total_sent;
         if (amount_to_read > req->content_buffer_size)
            amount_to_read = req->content_buffer_size;
         len_read = req->getMoreContent(req, req->content, amount_to_read, 0);
         if (len_read > 0)
         {
            buffers[0].iov_base = req->content;
            buffers[0].iov_len = len_read;
            result = transport->sendBuffers(socket, buffers, 1);
            total_sent += len_read;
         } else if (len_read < 0) {
            WOLog(WO_ERR, "Failed to read streamed content.");
            result = -1;
         }
      }
   }
   WOFREE(buffers);
   if (result == 0)
      result = transport->flush_connection(socket);
   else
      WOLog(WO_ERR, "error sending request");

   return result;
}
예제 #8
0
파일: xmlparse.c 프로젝트: ATLTed/wonder
/*
 *	The entry point for the parser.
 *      Returns nonzero if there was an error during parsing.
 */
static int xml_parseConfiguration(char *buf, int len)
{
   XMLCDocumentHandler handler;
   WOXMLEdits config;
   XMLCParser *parser;
   int error = 0, i;

   /* initialize the config struct */
   config.current_element = NULL;
   config.new_apps = wolist_new(16);
   config.current_app = NULL;
   config.current_app_instances = NULL;
   config.current_instance = NULL;
   config.new_app_instances =  wolist_new(16);
   config.error = 0;
   config.errorLocation = buf;
   
   if (len == 0)
      return 1; 		/* no content is considered an error */
   
   /* Set up a new document handler struct for the parser */
   memcpy(&handler, &_document, sizeof(XMLCDocumentHandler));
   handler.document = (XMLCDocument *)(&config);

   /* set up and invoke the xml parser */
   parser = xmlcParserInit();
   xmlcTokenizerSetBuffer(parser->tokenizer, buf, len);
   xmlcParserSetPreserveWhiteSpace(parser, 0);
   error = (int)xmlcParserParse(parser, &handler);

   if (error != 0) {
      /* config error */
      WOLog(WO_ERR,"Error parsing configuration: %s", xmlcParserErrorDescription(error));
      if ((intptr_t)config.errorLocation < (intptr_t)buf + len)
      {
         char *badconfig = WOMALLOC((len+1)*sizeof(char));
         strncpy(badconfig, buf, len);
         badconfig[len] = '\0';
         WOLog(WO_ERR,"Error near:\n%s", config.errorLocation);
         WOFREE(badconfig);
      }
   } else {
      /*
       *	load the new settings...
       */
      if (config.new_apps)
         for (i=0; i<wolist_count(config.new_apps); i++)
            ac_updateApplication((strtbl *)wolist_elementAt(config.new_apps, i), (list *)wolist_elementAt(config.new_app_instances, i));
   }

   /* clean up and return */
   freeWOXMLEdits(&config);
   xmlcParserDealloc(parser);
   return error;
}
예제 #9
0
static void copyHeaderForServerVariable(char *var, EXTENSION_CONTROL_BLOCK *p, HTTPRequest *req) {
    char *buf, *value, stackBuf[2048];
    DWORD bufsz = sizeof(stackBuf), pos;

    WOLog(WO_DBG, "reading buffer for server variable %s", var);
    if (p->GetServerVariable(p->ConnID, var, stackBuf, &bufsz) == TRUE) {
        buf = stackBuf;
    } else {
        if(GetLastError() == 122) // ERROR_INSUFFICIENT_BUFFER
        {
            WOLog(WO_DBG, "buffer too small; need %d", bufsz);
            buf = WOMALLOC(bufsz);
            if (p->GetServerVariable(p->ConnID, var, buf, &bufsz) != TRUE)
            {
                WOFREE(buf);
                WOLog(WO_ERR, "Could not get header.");
                return;
            }
        } else
            return; // header not set
    }

    if (buf) {
        //WOLog(WO_DBG, "got raw buffer: %s", buf);
        pos = 0;
        while (pos < bufsz) {
            while (pos < bufsz && buf[pos] < 33)
                pos++;
            if (pos < bufsz)  {
                /* got start of new value */
                value = &buf[pos];
                do {
                    while (pos < bufsz && buf[pos] != '\r')
                        pos++;
                    if (pos + 2 < bufsz && buf[pos+1] == '\n' && (buf[pos+2] == ' ' || buf[pos+2] == '\t')) {
                        /* got a multiline header; change CRLF to whitespace and keep parsing */
                        buf[pos] = ' ';
                        buf[pos+1] = ' ';
                    } else {
                        buf[pos] = 0;
                    }
                } while (pos < bufsz && buf[pos] != 0);
                WOLog(WO_DBG, "found value=\"%s\"", value ? value : "(NULL)");
                if (value)
                    req_addHeader(req, var, value, STR_COPYKEY|STR_COPYVALUE);
                else
                    req_addHeader(req, var, "", STR_COPYKEY);
            }
        }
        if (buf != stackBuf)
            WOFREE(buf);
    }

   return;
}
예제 #10
0
static int nonBlockingConnectHostent(int sd, int connectTimeout, struct hostent *hostentry, unsigned int port) {
   int n, rc;
   fd_set wset;
   struct timeval tval;
   struct sockaddr_in connect_addr;
   int connect_addr_len;

   rc = 0;

   if (hostentry) {
      connect_addr.sin_family = AF_INET;
      connect_addr.sin_port = htons((unsigned short)port);
      memcpy(&connect_addr.sin_addr, hostentry->h_addr_list[0], hostentry->h_length);
      connect_addr_len = sizeof(struct sockaddr_in);

      /* Since we're non-blocking, we expect an EINPROGRESS error. */
      if ((n = connect(sd, (struct sockaddr *)&connect_addr, connect_addr_len)) < 0) {
         int ec = WA_error();
         /* Note that on Windows, connect returns WSAEWOULDBLOCK, not WSAEINPROGRESS. */
         if (!WA_inProgress(ec) && !WA_wouldBlock(ec)) {
            char *errMsg = WA_errorDescription(ec);
            WOLog(WO_ERR, "WOSocket: connect error in NB connect: %s", errMsg);
            WA_freeErrorDescription(errMsg);
            return -1;
         }
      }

      /* If n = 0, we connected immediately (e.g. client = host). */
      if (n) {
         FD_ZERO(&wset);
         FD_SET(sd, &wset);
         tval.tv_sec = connectTimeout;
         tval.tv_usec = 0;

         if ((n = select(sd + 1, NULL, &wset, NULL, &tval)) < 0)
         {
            WOLog(WO_DBG, "WOSocket: select failed");
            return -1;
         }

         if (n == 0)
         {
            /* timed out */
            WOLog(WO_DBG, "WOSocket: connect timeout in NB connect");
            return -2;
         }
      }
   } else {
      WOLog(WO_ERR, "WOSocket: hostent NULL - unknown host?");
      rc = -1;
   }
   return rc;
}
예제 #11
0
void resp_addHeader(HTTPResponse *resp, String *rawhdr)
{
   char *key, *value;

   /* keep track of the String */
   resp_addStringToResponse(resp, rawhdr);
   
   /*
    *	break into key/value, make key lowercase
    *   Note that this walks over the String's buffer, but
    *   at this point the response owns the String so that's ok.
    *   The String buffer will get reclaimed when responseStrings
    *   is freed, in resp_free().
    */
   for (key = rawhdr->text, value = key; *value != ':'; value++) {
      if(*value == '\0') // mstoll 13.10.2005 check added
      {
         WOLog(WO_ERR,"Header without ':': %s", rawhdr->text);
         break;
      }
      if (isupper((int)*value))
         *value = tolower((int)*value);				/* ... and change to lowercase. */
   }
   if (*value == ':') {
      *value++ = '\0';			/* terminate key string */
      while (*value && isspace((int)*value))	value++;
   } else {
      return;			/* Zounds ! something wrong with header... */
   }

   st_add(resp->headers, key, value, 0);
   
   /*
    *	scan inline for content-length
    */
   if ((resp->content_length == 0) && ((strcasecmp(CONTENT_LENGTH,key) == 0) || strcasecmp("content_length", key) == 0))
   {
      // 2009/06/10: an explicit content-length value is available.
      //             Update response flag information:
      resp->flags |= RESP_LENGTH_EXPLICIT;
      resp->content_length = atoi(value);
      WOLog(WO_INFO,"content-length was set expl.: %d", resp->content_length);
   }

   if (((strcasecmp(CONTENT_TYPE,key) == 0) || strcasecmp("content_type", key) == 0))
   {
      // 2011/11/16: an explicit content-type value is available.
      //             Update response flag information:
      resp->flags |= RESP_CONTENT_TYPE_SET;
   }

   return;
}
예제 #12
0
static void sig_handler(int signum) {
    switch (signum) {
	case SIGUSR1 : should_terminate = 1;
		       WOLog(WO_INFO,"<FastCGI> Signal %s caught", strsignal(signum));
		       break;
	case SIGPIPE : WOLog(WO_WARN,"<FastCGI> Signal %s caught", strsignal(signum));
		       break;
	case SIGTERM : WOLog(WO_ERR,"<FastCGI> Signal %s caught", strsignal(signum));
		       exit(-1);
	default:       WOLog( WO_INFO,"<FastCGI> Signal %s caught", strsignal(signum));
    }
}
예제 #13
0
파일: xmlparse.c 프로젝트: ATLTed/wonder
/*
 *      Called from the xml parser.
 *	Here is where we begin parsing <application>... or <instance>...
 *	or <adaptor>...
 */
static void createElement(XMLCDocument *document, const XMLCCharacter *name, const unsigned int length)
{
   WOXMLEdits *config = (WOXMLEdits *)document;

   if (config->error != 0)		/* would be nice to tell parser to stop */
      return;

   config->errorLocation = name;
   
   if (length == 7 && strncasecmp(name, "adaptor", length) == 0)
   {
      /* do nothing; don't generate a warning */
   } else if (length == 11 && strncasecmp(name, "application", length) == 0) {
      /* begin <application> */
      if (config->current_element != NULL) {
         WOLog(WO_ERR,"Error parsing config: found unexpected <application> tag");
         config->error = 1;
         return;
      }
      /* create new app settings dictionary, instance list, and set current_element to the app dictionary*/
      config->current_app = st_new(8);
      wolist_add(config->new_apps, config->current_app);
      config->current_app_instances = wolist_new(8);
      wolist_add(config->new_app_instances, config->current_app_instances);
      config->current_element = config->current_app;

   } else if (length == 8 && strncasecmp(name, "instance", length) == 0) {
      /* begin <instance> */
      if (config->current_element != config->current_app || config->current_app == NULL) {
         WOLog(WO_ERR,"Error parsing config: found unexpected <instance> tag");
         config->error = 1;
         return;
      }
      /* create new instance settings dictionary and set current_element to point to it */
      config->current_instance = st_new(8);
      wolist_add(config->current_app_instances, config->current_instance);
      config->current_element = config->current_instance;

   } else {
      /* Got something unexpected. Ignore the tag. */
      char *buffer = WOMALLOC(length+1);
      strncpy(buffer,name,length);
      buffer[length] = '\0';
      WOLog(WO_WARN,"Unknown tag in XML: \"%s\"",buffer);
      config->current_element = NULL;
      WOFREE(buffer);
   }
   return;
}
예제 #14
0
/* Returns the number of bytes read, or -1 on error. */
static int readContentData(HTTPRequest *req, void *buffer, int dataSize, int mustFill)
{
   WOLog (WO_INFO, "data size: %d", dataSize );
   //int n = fread(buffer, 1, dataSize, stdin);
   int n = FCGX_GetStr(buffer, dataSize, in);
   if (n != dataSize) {
      //int err = ferror(stdin);
	  int err = FCGX_GetError(in);
      if (err)
         WOLog(WO_ERR,"Error getting content data: %s (%d)", strerror(errno), err);
   }
/*	*((char*)buffer+dataSize) = '\0';
	 WOLog ( WO_INFO, "buffer: %s", (char *)buffer );*/
   return n == dataSize ? n : -1;
}
예제 #15
0
static DWORD die(EXTENSION_CONTROL_BLOCK *p, const char *msg, int status)
{
   HTTPResponse *resp;
   WOLog(WO_ERR,"Sending aborting request - %s",msg);
   resp = resp_errorResponse(msg, status);
   return die_resp(p, resp);
}
예제 #16
0
파일: strtbl.c 프로젝트: rentzsch/woplat
void st_add(strtbl *st, const char *key, const char *value, int flags)
{
    strtblelem *kv;

    kv = st_newKV(st);
    if (kv != NULL)
    {
        st->count++;
        kv->flags = flags;
        if (flags & STR_COPYKEY)
        {
            kv->key = WOSTRDUP(key);
            kv->flags |= STR_FREEKEY;
        } else
            kv->key = key;
        if (flags & STR_COPYVALUE)
        {
            kv->value = WOSTRDUP(value);
            kv->flags |= STR_FREEVALUE;
        } else
            kv->value = value;
    } else
        WOLog(WO_ERR, "st_add(): no space to add element: %s = %s", key, value);
    return;
}
예제 #17
0
   const char *documentRoot() {
      static char path[MAXPATHLEN+1] = "";

      if (path[0] == '\0') {
#ifdef WIN32
         WOReadKeyFromConfiguration(CGI_DOCUMENT_ROOT, path, MAXPATHLEN);
#else
         const char *doc_root;
         /* Apache provides this as an environment variable straight */
         if ((doc_root = FCGX_GetParam(CGI_DOCUMENT_ROOT, hdrp)) != NULL) {
            strncpy(path, doc_root, MAXPATHLEN);
         } else {
            const char *path_trans, *path_info;
            path_trans = FCGX_GetParam(PATH_TRANSLATED, hdrp);
            path_info = FCGX_GetParam(CGI_PATH_INFO, hdrp);

            if (path_trans && path_info) {
               char *e = strstr(path_trans,path_info);
               if (e) {
                  strncpy(path,path_trans,e-path_trans);
               }
            }
         }
#endif
      }
      if (path[0] != '\0')
         return path;
      else {
         WOLog(WO_ERR,"<FastCGI> Can't find document root in CGI variables");
         return "/usr/local/apache/htdocs";		/* this is bad.... */
      }
}
예제 #18
0
파일: strdict.c 프로젝트: ATLTed/wonder
void *sd_add(strdict *sd, const char *key, void *value)
{
   strdictel *kv;
   void *oldValue;

   oldValue = sd_removeKey(sd, key);
   if (value != NULL)
   {
      if (sd->count == sd->capacity) {
         kv = findNull(sd);			/* try to recycle space */
         if (kv == NULL) {
            sd_setCapacity(sd, sd->capacity * 2);	/* make more space */
            if (sd->count == sd->capacity)
            {
               WOLog(WO_ERR, "sd_add(): could not add element (%s = %s) due to allocation failure", key, value);
               return oldValue;
            } else {
               kv = sd->head + sd->count;
               sd->count++;
            }
         }
      } else {
         kv = sd->head + sd->count;
         sd->count++;
      }
      kv->key = WOSTRDUP(key);
      kv->value = value;
   }
   return oldValue;
}
예제 #19
0
HTTPResponse *resp_new(char *statusStr, WOInstanceHandle instHandle, WOConnection *instanceConnection)
{
   HTTPResponse *resp;
   char *status = statusStr;

   /*
    *	reformat the status line from
    *	"HTTP/1.0 200 OK Apple WebObjects" to "OK Apple..."
    */
   while (status && *status && !isspace((int)*status))	status++;
   while (*status && !isdigit((int)*status))	status++;
   if ( !(status && *status) ) {
      WOLog(WO_ERR,"Invalid response!");
      return NULL;
   }

   resp = WOCALLOC(1,sizeof(HTTPResponse));
   resp->status = atoi(status);
   resp->statusMsg = (char *)apple;
   if (strncmp(statusStr, "HTTP/1.", 7) == 0)
   {
      if (statusStr[7] == '0')
         resp->flags |= RESP_HTTP10;
      else if (statusStr[7] == '1')
         resp->flags |= RESP_HTTP11;
   }

   resp->headers = st_new(10);
   resp->instanceConnection = instanceConnection;
   resp->instHandle = instHandle;

   return resp;
}
예제 #20
0
파일: transaction.c 프로젝트: ATLTed/wonder
static HTTPResponse *_errorResponse(WOAppReq *app, WOURLComponents *wc, HTTPRequest *req)
{
   HTTPResponse *resp;
   const char *redirect_url = &app->redirect_url[0];

   WOLog(WO_ERR,"Request handling error: %s",_errors[app->error]);

   if (app->redirect_url[0] == 0)
      redirect_url = adaptor_valueForKey(WOERRREDIR);

   /*
    *	try to do the right thing...
    */
   if (redirect_url != NULL) {
      resp = resp_redirectedResponse(redirect_url);
   } else if (app->error == err_notFound) {
      if (ac_authorizeAppListing(wc))
         resp = WOAdaptorInfo(NULL, wc);
      else {
         resp = resp_errorResponse(NOT_FOUND_APP, HTTP_NOT_FOUND);
         if (resp->statusMsg)	WOFREE(resp->statusMsg);
         resp->statusMsg = WOSTRDUP("File Not Found");
      }
   } else
       resp = resp_errorResponse(_errors[app->error], HTTP_SERVER_ERROR);

   if (resp)
   {
      st_add(resp->headers, "Cache-Control", "no-cache, private, no-store, must-revalidate, max-age=0", 0);
      st_add(resp->headers, "Expires", "Thu, 01 Jan 1970 00:00:00 GMT", 0);
      st_add(resp->headers, "date", "Thu, 01 Jan 1970 00:00:00 GMT", 0);
      st_add(resp->headers, "pragma", "no-cache", 0);
   }
   return resp;
}
예제 #21
0
파일: request.c 프로젝트: desertsky/wonder
/*
 *	common routing to add header called by both addHeader()
 */
inline
static
const char *req_AddHeader_common(HTTPRequest *req,const char *key,const char *value)
{
   const char *customKey;
   const char *hdrkey;

   customKey = customHeaderFor(key);
   hdrkey = (customKey != NULL) ? customKey : key;

   if (req->headers == NULL)
      req->headers = st_new(HEADER_CNT);

   /*
    *	we inspect the headers in line here to grab the content length
    */
   if ((req->content_length == 0) &&
       ((strcasecmp(key, CONTENT_LENGTH) == 0) || (strcasecmp(key, "content_length") == 0)))	/* get content-length */
       req->content_length = atol(value);

#ifdef DEBUG
       WOLog(WO_DBG,"(req-hdr) %s: %s",key, value);
#endif

       return hdrkey;
}
예제 #22
0
파일: shmem.c 프로젝트: getsharp/wonder
/*
 * Ensure that the open file fd is at least size bytes long.
 * Expands the file as needed using append_zeros(). File locking
 * is used to ensure no data is overwritten.
 * Returns the actual size of the file on success, -1 on error.
 */
static int ensure_file_size(int fd, size_t size)
{
   struct stat st;
   struct flock lockInfo;
   char *errMsg = NULL;
   int error = 0;

   if (fstat(WOShmem_fd, &st))
   {
      errMsg = WA_errorDescription(WA_error());
      WOLog(WO_ERR, "ensure_file_size(): initial fstat() failed: %s", errMsg);
      error = 1;
   }
   if (!error && st.st_size < size)
   {
      if (lock_file_section(WOShmem_fd, st.st_size, size - st.st_size, &lockInfo, 1))
      {
         error = 1;
      } else {
         /* someone else may have just changed the size, so repeat the stat */
         if (fstat(WOShmem_fd, &st))
         {
            errMsg = WA_errorDescription(WA_error());
            WOLog(WO_ERR, "ensure_file_size(): second fstat() failed: %s", errMsg);
            WA_freeErrorDescription(errMsg);
            error = 1;
         }
         if (!error && st.st_size < size)
         {
            st.st_size += append_zeros(WOShmem_fd, size - st.st_size);
            if (st.st_size < size)
               error = 1;
         }
         lockInfo.l_type = F_UNLCK;
         if (fcntl(WOShmem_fd, F_SETLK, &lockInfo) == -1)
         {
            errMsg = WA_errorDescription(WA_error());
            WOLog(WO_ERR, "ensure_file_size(): failed to unlock: %s", errMsg);
            WA_freeErrorDescription(errMsg);
            error = 1;
         }
      }
   }
   return error ? -1 : st.st_size;
}
예제 #23
0
파일: xmlparse.c 프로젝트: ATLTed/wonder
/*
 *	here's where we end application/instance/error parsing
 */
static void endElementNamed(XMLCDocument *document, const XMLCCharacter *name, const unsigned int length)
{
   WOXMLEdits *config = (WOXMLEdits *)document;

   if (config->error != 0)		/* would be nice to tell parser to stop */
      return;

   if (length == 7 && strncasecmp(name, "adaptor", 7) == 0)
   {
      /* do nothing; don't generate a warning */
   } else if (length == 11 && strncasecmp(name, "application", 11) == 0) {
      if (config->current_element != config->current_app) {
         WOLog(WO_ERR,"Error parsing config: </application> found at top level or with open <instance> tag");
         config->error = 1;
         return;
      }
      config->current_element = NULL;
      config->current_app = NULL;
      config->current_app_instances = NULL;

   } else if (length == 8 && strncasecmp(name, "instance", 8) == 0) {
      if (config->current_element != config->current_instance) {
         WOLog(WO_ERR,"Error parsing config: unexpected </instance>");
         config->error = 1;
         return;
      }
      config->current_element = config->current_app;
      config->current_instance = NULL;

   } else if (length == 7 && strncasecmp(name, "adaptor", 7) == 0) {
      config->current_element = NULL;
   } else {
#ifdef _MSC_VER // SWK VC can't allocate dynamic char buffer[length + 1]
      char *buffer = (char *)alloca((length+1) * sizeof(char));
#else
      char buffer[length+1];
#endif
	  strncpy(buffer,name,length);
      buffer[length] = '\0';
      WOLog(WO_WARN,"Unknown end tag in XML: %s",buffer);
      if (config->current_element != NULL)	/* only an error if we were parsing something we know about */
         config->error = 1;
   }
   return;
}
예제 #24
0
파일: shmem.c 프로젝트: getsharp/wonder
void sha_unlock(ShmemArray *array, unsigned int elementNumber)
{
   if (elementNumber < array->elementCount)
   {
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_unlock(): about to unlock %s element %d", array->name, elementNumber);
#endif
      WA_lock(array->elements[elementNumber].lock);
      /* release the file lock on the data */
      WOShmem_unlock(array->elements[elementNumber].lockHandle);
      array->elements[elementNumber].lockHandle = NULL;
      WA_unlock(array->elements[elementNumber].lock);
      WA_unlock(array->elements[elementNumber].writeLock);
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_unlock(): unlocked %s element %d", array->name, elementNumber);
#endif
   }
}
예제 #25
0
파일: Platform.c 프로젝트: ATLTed/wonder
void WA_lock(WA_recursiveLock _lock)
#endif
{
   WinRecursiveLock *lock = (WinRecursiveLock *)_lock;
#ifdef EXTRA_DEBUGGING_LOGS
   if (_lock != logMutex)
      WOLog(WO_DBG, "locking %s from %s:%d", lock->name, file, line);
#endif
   WaitForSingleObject(lock->lock, INFINITE);
}
예제 #26
0
파일: Platform.c 프로젝트: ATLTed/wonder
void WA_unlock(WA_recursiveLock _lock)
#endif
{
   WinRecursiveLock *lock = (WinRecursiveLock *)_lock;
#ifdef EXTRA_DEBUGGING_LOGS
   if (_lock != logMutex)
      WOLog(WO_DBG, "unlocking %s from %s:%d", lock->name, file, line);
#endif
   ReleaseMutex(lock->lock);
}
예제 #27
0
static TR_STATUS reset(net_fd appfd)
{
   int result, warned = 0, n;
   struct timeval tv;
   fd_set wset;

   if (appfd->status != TR_OK)
      return TR_ERROR;
   
   /* drain any data from the socket */
   do {
      result = nonBlockingRecv(appfd, 0, appfd->buf, NETBUFSZ);
      if (result > 0 && warned == 0)
      {
         WOLog(WO_WARN, "reset(): leftover data in socket buffer");
         warned = 1;
      }
      if (result == -1 && appfd->status == TR_TIMEOUT)
         appfd->status = TR_OK;
   } while (result > 0);
   /* clear our buffer */
   if (appfd->status == TR_OK)
   {
      if (appfd->count != 0)
         WOLog(WO_WARN, "reset(): leftover data in buffer");
      appfd->count = 0;
      appfd->pos = appfd->buf;

      FD_ZERO(&wset);
      FD_SET(appfd->s, &wset);
      tv.tv_sec = 0;
      tv.tv_usec = 0;

      n = select(appfd->s + 1, NULL, &wset, NULL, &tv);
      if (n != 1)
      {
         WOLog(WO_WARN, "reset(): connection dropped");
         appfd->status = TR_RESET;
      }
   }
   return appfd->status;
}
예제 #28
0
파일: shmem.c 프로젝트: getsharp/wonder
void sha_checkin(ShmemArray *array, unsigned int elementNumber)
{
   if (elementNumber < array->elementCount)
   {
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_checkin(): about to check in %s element %d", array->name, elementNumber);
#endif
      WA_lock(array->elements[elementNumber].lock);
      array->elements[elementNumber].lockCount--;
      /* if this was the last read lock by this process, release the file lock on the data as well */
      if (array->elements[elementNumber].lockCount == 0)
      {
         WOShmem_unlock(array->elements[elementNumber].lockHandle);
         array->elements[elementNumber].lockHandle = NULL;
      }
      WA_unlock(array->elements[elementNumber].lock);
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_checkin(): checked in %s element %d", array->name, elementNumber);
#endif
   }
}
예제 #29
0
파일: WebObjects.c 프로젝트: ATLTed/wonder
static void sendResponse(EXTENSION_CONTROL_BLOCK *p, HTTPResponse *resp)
{
   String *resphdrs;
   char status[128];
   DWORD len;

   p->dwHttpStatusCode = resp->status;
   sprintf(status, "%d %s",resp->status, resp->statusMsg);


   /*
    *	send the headers (collected into one buffer)
    */
   resphdrs = resp_packageHeaders(resp);
   if (resphdrs)
   {
      len = resphdrs->length;
      /* ccording to the Microsoft web site, HSE_REQ_SEND_RESPONSE_HEADER is depreciated */
      /* HSE_REQ_SEND_RESPONSE_HEADER_EX is preferred. */
      /* However, moving to HSE_REQ_SEND_RESPONSE_HEADER_EX will not work if we must support IIS 3.0. */
      if (p->ServerSupportFunction(p->ConnID, HSE_REQ_SEND_RESPONSE_HEADER,
                                   status, &len, (LPDWORD)resphdrs->text) != TRUE)
      {
         WOLog(WO_ERR,"Failed to send response headers (%d)", GetLastError());
      } else {
         len = 2;
         if (p->WriteClient(p->ConnID, CRLF, &len, 0) != TRUE)
            WOLog(WO_ERR,"Failed to send \\r\\n (%d)", GetLastError());
         /*
          *	send the content data
          */
         len = resp->content_length;
         if (len && (p->WriteClient(p->ConnID, resp->content, &len, 0) != TRUE))
            WOLog(WO_ERR,"Failed to send content (%d)", GetLastError());
      }
      str_free(resphdrs);
   } /* else? return warning */

    return;
}
예제 #30
0
파일: shmem.c 프로젝트: getsharp/wonder
void *sha_lock(ShmemArray *array, unsigned int elementNumber)
{
   void *element;
   if (elementNumber < array->elementCount)
   {
#ifdef EXTRA_DEBUGGING_LOGS
      WOLog(WO_DBG, "sha_lock(): about to lock %s element %d", array->name, elementNumber);
#endif
      /* block read lock requests */
      WA_lock(array->elements[elementNumber].writeLock);
      WA_lock(array->elements[elementNumber].lock);
      int maxTry = 10000;
      while (array->elements[elementNumber].lockCount > 0 && maxTry-- > 0)
      {
         WA_unlock(array->elements[elementNumber].lock);
         WA_yield();
         WA_lock(array->elements[elementNumber].lock);
      }

      if(array->elements[elementNumber].lockCount <= 0)
      {
         element = array->elements[elementNumber].element;
         array->elements[elementNumber].lockHandle = WOShmem_lock(element, array->elementSize, 1);
         WA_unlock(array->elements[elementNumber].lock);
#ifdef EXTRA_DEBUGGING_LOGS
         WOLog(WO_DBG, "sha_lock(): locked %s element %d", array->name, elementNumber);
#endif
      } else
      {
         WA_unlock(array->elements[elementNumber].lock);
         WA_unlock(array->elements[elementNumber].writeLock);
         element = NULL;
         WOLog(WO_ERR, "sha_lock(): element already locked: %s / %d", array->name, elementNumber);
      }
   } else {
      element = NULL;
      WOLog(WO_ERR, "sha_lock(): failed to lock %s element %d", array->name, elementNumber);
   }
   return element;
}