⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpd.c

📁 picoos源码。The RTOS and the TCP/IP stack will be built automatically.
💻 C
📖 第 1 页 / 共 5 页
字号:
  if ((conn->servlet == NULL) || (conn->session == NULL))
    return -1;

  hsl_printf(slobj, "<input type=\"hidden\" name=\"" HTTP_SESSIONIDNAME
                    "\" value=\"%08x\">\n", conn->session->id);
  return 0;
}


/* create a new link container
 */
sint_t hsl_linkCreate(SERVLET_t *slobj, const char* url, u32_t flags)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
  char *u, *d;

  if (conn == NULL)
    return -1;

  if (conn->servlet == NULL)
    return -1;

  u = (char*) url;
  d = conn->linkbuf;

  if (u == NULL)
  {
    u = conn->servlet->filename;
    if (*u != '/')
      *d++ = '/';
  }

  if ((sysStrlen(u) + 1 + 1 + HTTP_MAXSIDLENGTH) > HTTP_MAXSTRLEN)
    return -1;

  sysStrcpy(d, u);
  conn->linkflags = flags;

  if (((flags & HSL_LINK_SID) != 0) && (conn->session != NULL))
  {
    sprintf(conn->linkbuf + sysStrlen(conn->linkbuf),
            "?" HTTP_SESSIONIDNAME "=%08x", conn->session->id);
  }
  else
  {
    conn->linkflags |= HSL_LINK_QM;
  }

  return 0;
}


/* add a string value to the parameter list of a link
 */
sint_t hsl_linkAddStringVal(SERVLET_t *slobj, const char *name,
                            const char* val)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
  sint_t i;

  if ((conn == NULL) || (name == NULL) || (val == NULL))
    return -1;

  if ((sysStrlen(conn->linkbuf) + sysStrlen(name) + sysStrlen(val) + 2) >
      HTTP_MAXSTRLEN)
    return -1;

  i = sysStrlen(conn->linkbuf);  
  if (i == 0)
    return -1;

  if (conn->linkbuf[i-1] != '&')
  {
    conn->linkbuf[i] = (conn->linkflags & HSL_LINK_QM) ? '?' : '&';
    conn->linkbuf[i+1] = 0;
    conn->linkflags &= ~HSL_LINK_QM;
  }

  sysStrcat(conn->linkbuf, name);
  sysStrcat(conn->linkbuf, "=");

  i = sysStrlen(conn->linkbuf);
  ht_doEscape(val, conn->linkbuf + i, HTTP_MAXSTRLEN - i);
  return 0;
}


/* add a dezimal value to the parameter list of a link
 */
sint_t hsl_linkAddNumberVal(SERVLET_t *slobj, const char *name, u32_t val)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
  sint_t i;

  if ((conn == NULL) || (name == NULL))
    return -1;

  if ((sysStrlen(conn->linkbuf) + sysStrlen(name) + 10 + 2) >
      HTTP_MAXSTRLEN)
    return -1;

  i = sysStrlen(conn->linkbuf);
  if (i == 0)
    return -1;

  if (conn->linkbuf[i-1] != '&')
  {
    conn->linkbuf[i] = (conn->linkflags & HSL_LINK_QM) ? '?' : '&';
    conn->linkbuf[i+1] = 0;
    conn->linkflags &= ~HSL_LINK_QM;
  }

  sysStrcat(conn->linkbuf, name);
  sysStrcat(conn->linkbuf, "=");
  sprintf(conn->linkbuf + sysStrlen(conn->linkbuf), "%u", val);

  return 0;
}


/* insert a link into the servlet output stream
 */
sint_t hsl_linkInsert(SERVLET_t *slobj, const char *linktext)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;

  if (conn == NULL)
    return -1;

  if ((conn->linkflags & HSL_LINK_RAW) == 0)
  {
    if (linktext == NULL)
      return -1;

    hsl_printf(slobj, "<a href=\"%s\">%s</a>", conn->linkbuf, linktext);
  }
  else
  {
    hsl_printf(slobj, "%s", conn->linkbuf);
  }

  return 0;
}


/* add session id as hidden parameter to a form
 */
sint_t hsl_addSessionIdToForm(SERVLET_t *slobj)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;

  if (conn == NULL)
    return -1;

  if (conn->session == NULL)
    return -1;

  hsl_printf(slobj, "<input type=\"hidden\" name=\"" HTTP_SESSIONIDNAME
             "\" value=\"%08x\">", conn->session->id);
  return 0;
}


/* calculate a pseudo random number
 */
static u32_t ht_random(sint_t init)
{
  static u16_t r1 = 0x15a6;
  static u16_t r2 = 0xa26f;
  u16_t r, i, time = (u16_t) COUNTERVAR;

  if (init != 0)
  {
    r1 += time & 0x55AA;
    r2 += time & 0xAA55;
    if (r1 == 43690) r1++;
    if (r2 == 43690) r2--;
  }  

  for (i = 1 + (time & 1); i > 0; i--)
  {
    r = (1 ^ r1 ^ (r1 >> 12) ^ (r1 >> 3)) & 1;
    r1 = (r1 >> 1) | (r << 15);
  }

  for (i = ((r1 & 3) == 0) ? 2 : 1; i > 0; i--)
  {
    r = (1 ^ r2 ^ (r2 >> 12) ^ (r2 >> 5)) & 1;
    r2 = (r2 >> 1) | (r << 15);
  }

  return (u32_t)r1 + ((u32_t)r2 << 16) + time;
}


/* create a new session id
 */
static u32_t ht_newSessionId(void)
{
  SESSION_t *ss;
  u32_t id;

  do
  {
    id = ht_random(0);
    for (ss = FIRST_LIST_ELEM(&sessionListHead_g, SESSION_t*);
         !END_OF_LIST(&sessionListHead_g, ss);
         ss = NEXT_LIST_ELEM(ss, SESSION_t*))
    {
      if (ss->id == id)
        break;
    }
  }
  while (!END_OF_LIST(&sessionListHead_g, ss));

  return id;
}


/* destroy a servlet session
 */
static void ht_destroySession(SESSION_t *ss)
{
  if (ss != NULL)
  {
    ht_listDel(&ss->list);
    allocatedSessionMem_g -= ss->userMemSize + sizeof(SESSION_t);
    sysMemFree(ss);
  }
}


/* try to assign a session to a HTTP servlet connection
 */
static sint_t ht_assignSession(HTTPCONN_t *conn)
{
  SESSION_t *ss;
  char *p;
  u32_t sid;

  p = hsl_getParameterByName((SERVLET_t) conn, HTTP_SESSIONIDNAME);
  if (p == NULL)
    return 0;

  if (sscanf(p, "%08x", &sid) != 1)
    return 0;

  for (ss = FIRST_LIST_ELEM(&sessionListHead_g, SESSION_t*);
       !END_OF_LIST(&sessionListHead_g, ss);
       ss = NEXT_LIST_ELEM(ss, SESSION_t*))
  {  
    if (ss->id == sid)
    {
      conn->session = ss;
      return 0;
    }
  }

  return -1;
}


/* This function destorys a servlet session.
 * It should be called when the user logs out.
 */
sint_t hsl_destroySession(SERVLET_t *slobj)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;

  if (conn == NULL)
    return -1;

  if (conn->session == NULL)
    return -1;

  ht_destroySession(conn->session);
  conn->session = NULL;
  return 0;
}


/* This function returns a pointer to the servlets session memory.
 */
void* hsl_getSession(SERVLET_t *slobj)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;

  if (conn == NULL)
    return NULL;

  if (conn->session == NULL)
    return NULL;

  conn->session->lastUsed = COUNTERVAR;
  return (void*) conn->session->userData;
}


/* This function returns the own name (name of the servlet).
 */
char* hsl_getOwnName(SERVLET_t *slobj)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
  char *n;

  if (conn == NULL)
    return NULL;

  n = conn->servlet->filename;
  if (*n == '/')
    n++;
  return n;
}


/* This function creates a new session.
 */
void* hsl_newSession(SERVLET_t *slobj, u32_t memsize, u32_t timeout)
{
  HTTPCONN_t *conn = (HTTPCONN_t*) slobj;
  SESSION_t *ss;
  u32_t size;

  if (conn == NULL)
    return NULL;

  if (timeout == 0)
    timeout = 300;

  size = sizeof(SESSION_t) + memsize;
  if ((allocatedSessionMem_g + size) > maxSessionMem_g)
    return NULL;

  ss = (SESSION_t*) sysMemAlloc(size);
  if (ss == NULL)
    return NULL;

  allocatedSessionMem_g += size;

  sysMemSet(&ss->userData, 0, memsize);
  ss->id          = ht_newSessionId();
  ss->userMemSize = memsize;
  ss->lastUsed    = COUNTERVAR;
  ss->timeout     = timeout * COUNTERTPS;
  ht_listAddTail(&sessionListHead_g, &ss->list);

  conn->session = ss;

  return (void*) ss->userData;
}


/* allocate a servlet buffer
 */
static SLBUF_t *ht_allocServletBuffer(void)
{
  SLBUF_t *b;

  b = freeServletBufList_g;
  if (b != NULL)
  {
    freeServletBufList_g = b->nextbuf;
    return b;
  }

  if ((allocatedServletMem_g + HTTP_SERVLETMINBUF) > maxServletMem_g)
    return NULL;

  b = (SLBUF_t*) sysMemAlloc(sizeof(SLBUF_t));
  if (b != NULL)
    allocatedServletMem_g += sizeof(SLBUF_t);
  return b;
}


/* free a servlet buffer
 */
static void ht_freeServletBuffer(SLBUF_t *buf)
{
  HTTPCONN_t *conn;

  if (buf != NULL)
  {
    buf->nextbuf = freeServletBufList_g;
    freeServletBufList_g = buf;

    /* new memory available, try to handle the next waiting servlet */
    if (!IS_LIST_EMPTY(&memWaitingList_g))
    {
      conn = GET_TRUE_ELEM( FIRST_LIST_ELEM(&memWaitingList_g, lelem_t*),
                            HTTPCONN_t*, mwlist );
      if (ht_tryAllocateBuffers(conn) == 0)
      {
        ht_handleServlet(conn);
      }
    }
  }
}


/* free a servlet buffer chain
 */
static void ht_freeServletBufferChain(SLBUF_t *firstbuf)
{
  SLBUF_t *nextbuf, *buf = firstbuf;

  while (buf != NULL)
  {
    nextbuf = buf->nextbuf;
    buf->nextbuf = freeServletBufList_g;
    freeServletBufList_g = buf;
    buf = nextbuf;
  }
}


/* try to allocate requested sl-buffers
 */
static sint_t ht_tryAllocateBuffers(HTTPCONN_t *conn)
{
  HTTPCONN_t  *mcon;
  SLBUF_t     *buf;

  if (conn->neededBufs == 0)
    return 0;

  if (!IS_ON_LIST(&conn->mwlist))
  {
    ht_listAddTail(&memWaitingList_g, &conn->mwlist);
  }

  mcon = GET_TRUE_ELEM( FIRST_LIST_ELEM(&memWaitingList_g, lelem_t*),
                        HTTPCONN_t*, mwlist );

  while (mcon->neededBufs > 0)
  {
    buf = ht_allocServletBuffer();
    if (buf == NULL)
      break;
    if (mcon->stdoutbuf == NULL)
    {
      buf->nextbuf = NULL;
      mcon->stdoutbuf = buf;
      mcon->curoutbuf = buf;
    }
    else
    {
      buf->nextbuf = mcon->freeSlBufs;
      mcon->freeSlBufs = buf;
    }
    mcon->outbufsize += HTTP_SERVLETMINBUF;
    mcon->neededBufs--;
  }

  if (mcon->neededBufs == 0)
  {
    ht_listDel(&mcon->mwlist);
    if (conn == mcon)
    {
      /* all buffers allocated, enable write again and return */
      ht_addWrSocket(conn->socket);
      return 0;
    }
  }

  /* failed to allocate buffer, must wait */

  /* disable write for the socket */
  FD_CLR(conn->socket, &globalWrSocketSet);
/*
  if (conn->wrDisabled == 0)
  {
    ht_disableWrite(conn);
  }
*/
  return -1;
}


/* handle a servlet
 */
static void ht_handleServlet(HTTPCONN_t *conn)
{
  sint_t rc;

  if (conn->servlet == NULL)
    return;

  if (conn->state != STATE_INIT)
    return;
 
  SYS_MTASK_LOCK(servletLock_g);

  if (ht_tryAllocateBuffers(conn) != 0)
  {
    /* memory allocation failed, try later again */
    SYS_MTASK_UNLOCK(servletLock_g);
#ifdef _MYDEBUG
if (conn->neededBufs == 1)
 printf("connection %i: failed to allocated 1 buffer\n", conn->socket);
#endif
    return;
  }

  /* call servlet */
  rc = (conn->servlet->func)((SERVLET_t) conn);

  SYS_MTASK_UNLOCK(servletLock_g);

  if (rc == SLERR_NEEDMEM)
  {
    return; /* try later again */
  }

  if (rc != SLERR_OK)
  {
    /* other errors */
    switch (rc)
    {
      case SLERR_BADREQUEST:  rc = ht_sendStatus(conn, status_400); break;
      case SLERR_NOTFOUND:    rc = ht_sendStatus(conn, status_404); break;
      case SLERR_CREATED:     rc = ht_sendStatus(conn, status_201); break;
      case SLERR_ACCEPTED:    rc = ht_sendStatus(conn, status_202); break;
      case SLERR_PARTIAL:     rc = ht_sendStatus(conn, status_206); break;
      case SLERR_FORBIDDEN:   rc = ht_sendStatus(conn, status_403); break;
      case SLERR_TOOLARGE:    rc = ht_sendStatus(conn, status_413); break;
      case SLERR_UNAVAILABLE: rc = ht_sendStatus(conn, status_503); break;
      case SLERR_BUSY:        rc = ht_sendStatus(conn, status_busy); break;
      case SLERR_SERVER:
      default:
        rc = ht_sendStatus(conn, status_500); /* Internal Server Error */
    }
    if (rc == 0)
      ht_nextTransfer(conn);
    return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -