예제 #1
0
int JNL_HTTPGet::run()
{
  int cnt=0;
  if (m_http_state==-1||!m_con) return -1; // error


run_again:
  m_con->run();

  if (m_con->get_state()==JNL_Connection::STATE_ERROR)
  {
    seterrstr(m_con->get_errstr());
    return -1;
  }
  if (m_con->get_state()==JNL_Connection::STATE_CLOSED) return 1;

  if (m_http_state==0) // connected, waiting for reply
  {
    if (m_con->recv_lines_available()>0)
    {
      char buf[4096];
      m_con->recv_line(buf,4095);
      buf[4095]=0;
      m_reply=(char*)malloc(strlen(buf)+1);
      strcpy(m_reply,buf);
    
      int code=getreplycode();
      if (code == 200 || code==206) m_http_state=2; // proceed to read headers normally
      else if (code == 301 || code==302) 
      {
        m_http_state=1; // redirect city
      }
      else 
      {
        seterrstr(buf);
        m_http_state=-1;
        return -1;
      }
      cnt=0;
    }
    else if (!cnt++) goto run_again;
  }
  if (m_http_state == 1) // redirect
  {
    while (m_con->recv_lines_available() > 0)
    {
      char buf[4096];
      m_con->recv_line(buf,4096);
      if (!buf[0])  
      {
        m_http_state=-1;
        return -1;
      }
      if (!strnicmp(buf,"Location:",9))
      {
        char *p=buf+9; while (*p== ' ') p++;
        if (*p)
        {
          connect(p);
          return 0;
        }
      }
    }
  }
  if (m_http_state==2)
  {
    if (!cnt++ && m_con->recv_lines_available() < 1) goto run_again;
    while (m_con->recv_lines_available() > 0)
    {
      char buf[4096];
      m_con->recv_line(buf,4096);
      if (!buf[0]) { m_http_state=3; break; }
      if (!m_recvheaders)
      {
        m_recvheaders_size=strlen(buf)+1;
        m_recvheaders=(char*)malloc(m_recvheaders_size+1);
        if (m_recvheaders)
        {
          strcpy(m_recvheaders,buf);
          m_recvheaders[m_recvheaders_size]=0;
        }
      }
      else
      {
        int oldsize=m_recvheaders_size;
        m_recvheaders_size+=strlen(buf)+1;
        char *n=(char*)malloc(m_recvheaders_size+1);
        if (n)
        {
          memcpy(n,m_recvheaders,oldsize);
          strcpy(n+oldsize,buf);
          n[m_recvheaders_size]=0;
          free(m_recvheaders);
          m_recvheaders=n;
        }
      }
    }
  }
  if (m_http_state==3)
  {
  }
  return 0;
}
예제 #2
0
void JNL_HTTPGet::connect(const char *url, int ver, char *requestmethod)
{
  deinit();
  m_http_url=(char*)malloc(strlen(url)+1);
  strcpy(m_http_url,url);
  do_parse_url(m_http_url,&m_http_host,&m_http_port,&m_http_request, &m_http_lpinfo);
  strcpy(m_http_url,url);
  if (!m_http_host || !m_http_host[0] || !m_http_port)
  {
    m_http_state=-1;
    seterrstr("invalid URL");
    return;
  }

  int sendbufferlen=0;

  if (!m_http_proxyhost || !m_http_proxyhost[0])
  {
    sendbufferlen += strlen(requestmethod)+1 /* GET */ + strlen(m_http_request) + 9 /* HTTP/1.0 */ + 2;
  }
  else
  {
    sendbufferlen += strlen(requestmethod)+1 /* GET */ + strlen(m_http_url) + 9 /* HTTP/1.0 */ + 2;
    if (m_http_proxylpinfo&&m_http_proxylpinfo[0])
    {
      sendbufferlen+=58+strlen(m_http_proxylpinfo)*2; // being safe here
    }
  }
  sendbufferlen += 5 /* Host: */ + strlen(m_http_host) + 2;

  if (m_http_lpinfo&&m_http_lpinfo[0])
  {
    sendbufferlen+=46+strlen(m_http_lpinfo)*2; // being safe here
  }

  if (m_sendheaders) sendbufferlen+=strlen(m_sendheaders);

  char *str=(char*)malloc(sendbufferlen+1024);
  if (!str)
  {
    seterrstr("error allocating memory");
    m_http_state=-1;    
  }

  if (!m_http_proxyhost || !m_http_proxyhost[0])
  {
    wsprintf(str,"%s %s HTTP/1.%d\r\n",requestmethod,m_http_request,ver%10);
  }
  else
  {
    wsprintf(str,"%s %s HTTP/1.%d\r\n",requestmethod, m_http_url,ver%10);
  }

  wsprintf(str+strlen(str),"Host:%s\r\n",m_http_host);

  if (m_http_lpinfo&&m_http_lpinfo[0])
  {
    strcat(str,"Authorization: Basic ");
    do_encode_mimestr(m_http_lpinfo,str+strlen(str));
    strcat(str,"\r\n");
  }
  if (m_http_proxylpinfo&&m_http_proxylpinfo[0])
  {
    strcat(str,"Proxy-Authorization: Basic ");
    do_encode_mimestr(m_http_proxylpinfo,str+strlen(str));
    strcat(str,"\r\n");
  }

  if (m_sendheaders) strcat(str,m_sendheaders);
  strcat(str,"\r\n");

  int a=m_recvbufsize;
  if (a < 4096) a=4096;
  m_con=new JNL_Connection(m_dns,strlen(str)+4,a);
  if (m_con)
  {
    if (!m_http_proxyhost || !m_http_proxyhost[0])
    {
      m_con->connect(m_http_host,m_http_port);
    }
    else
    {
      m_con->connect(m_http_proxyhost,m_http_proxyport);
    }
    m_con->send_string(str);
  }
  else
  {
    m_http_state=-1;
    seterrstr("could not create connection object");
  }
  free(str);

}
예제 #3
0
int JNL_HTTPGet::run()
{
    int cnt=0;
    if (m_http_state==-1||!m_con) return -1; // error


run_again:
    m_con->run();

    if (m_con->get_state()==JNL_Connection::STATE_ERROR)
    {
        seterrstr(m_con->get_errstr());
        return -1;
    }
    if (m_con->get_state()==JNL_Connection::STATE_CLOSED) return 1;

    if (m_http_state==0) // connected, waiting for reply
    {
        if (m_con->recv_lines_available()>0)
        {
            char buf[4096];
            m_con->recv_line(buf,4095);
            buf[4095]=0;
            m_reply=(char*)malloc(strlen(buf)+1);
            strcpy(m_reply,buf);

            int code=getreplycode();
            if (code == 200 || code==206 || code == 201) m_http_state=2; // proceed to read headers normally
            else if (code == 301 || code==302)
            {
                m_http_state=1; // redirect city
            }
            else
            {
                seterrstr(buf);
                m_http_state=-1;
                m_boy_george = 0;
                return -1;
            }
            cnt=0;
        }
        else if (!cnt++) goto run_again;
    }
    if (m_http_state == 1) // redirect
    {
        while (m_con->recv_lines_available() > 0)
        {
            char buf[4096];
            m_con->recv_line(buf,4096);
            if (!buf[0])
            {
                m_boy_george = 0;
                m_http_state=-1;
                return -1;
            }
            if (!strnicmp(buf,"Location:",9))
            {
                char *p=buf+9;
                while (*p== ' ') p++;
                if (*p)
                {
                    free(m_http_redir_url);
                    if(m_boy_george > MAX_RECURSION_COUNT)
                    {
                        seterrstr(strdup("Too many redirects"));
                        m_http_state=-1;
                        return -1;
                    }

                    m_boy_george++;

                    if(strnicmp(p,"http:",strlen("http:")))
                    {
                        char *newp;
                        newp = (char*)malloc(strlen(p) + strlen("http://") + strlen(m_http_host) + 1);
                        newp[0] = 0;
                        strcat(newp,"http://");
                        strcat(newp,m_http_host);
                        strcat(newp,p);
                        m_http_redir_url = newp;
                        p = newp;
                    }
                    else
                    {
                        m_http_redir_url = strdup(p);
                    }

                    connect(p);
                    return 0;
                }
            }
        }
    }
    if (m_http_state==2)
    {
        if (!cnt++ && m_con->recv_lines_available() < 1) goto run_again;

        m_boy_george = 0;

        while (m_con->recv_lines_available() > 0)
        {
            char buf[4096];
            m_con->recv_line(buf,4096);
            if (!buf[0]) {
                m_http_state=3;
                break;
            }
            if (!m_recvheaders)
            {
                m_recvheaders_size=strlen(buf)+1;
                m_recvheaders=(char*)malloc(m_recvheaders_size+1);
                if (m_recvheaders)
                {
                    strcpy(m_recvheaders,buf);
                    m_recvheaders[m_recvheaders_size]=0;
                }
            }
            else
            {
                int oldsize=m_recvheaders_size;
                m_recvheaders_size+=strlen(buf)+1;
                char *n=(char*)malloc(m_recvheaders_size+1);
                if (n)
                {
                    memcpy(n,m_recvheaders,oldsize);
                    strcpy(n+oldsize,buf);
                    n[m_recvheaders_size]=0;
                    free(m_recvheaders);
                    m_recvheaders=n;
                }
            }
        }
    }
    if (m_http_state==3)
    {
    }
    return 0;
}
예제 #4
0
int JNL_HTTPGet::run()
{
  int cnt=0;
  if (m_http_state==-1||!m_con) return -1; // error


run_again:
  static char main_buf[4096];
  char *buf = main_buf;
  m_con->run();

  if (m_con->get_state()==JNL_Connection::STATE_ERROR)
  {
    seterrstr(m_con->get_errstr());
    return -1;
  }
  if (m_con->get_state()==JNL_Connection::STATE_CLOSED) return 1;

  if (m_http_state==0) // connected, waiting for reply
  {
    if (m_con->recv_lines_available()>0)
    {
      m_con->recv_line(buf,4095);
      buf[4095]=0;
      m_reply=(char*)malloc(strlen(buf)+1);
      strcpy(m_reply,buf);

      if (strstr(buf,"200")) m_http_state=2; // proceed to read headers normally
      else if (strstr(buf,"301") || strstr(buf,"302")) 
      {
        m_http_state=1; // redirect city
      }
      else 
      {
        seterrstr(buf);
        m_http_state=-1;
        return -1;
      }
      cnt=0;
    }
    else if (!cnt++) goto run_again;
  }
  if (m_http_state == 1) // redirect
  {
    while (m_con->recv_lines_available() > 0)
    {
      m_con->recv_line(buf,4096);
      if (!buf[0])  
      {
        m_http_state=-1;
        return -1;
      }
      if (!my_strnicmp(buf,"Location:",9))
      {
        char *p=buf+9; while (*p== ' ') p++;
        if (*p)
        {
          connect(p);
          return 0;
        }
      }
    }
  }
  if (m_http_state==2)
  {
    if (!cnt++ && m_con->recv_lines_available() < 1) goto run_again;
    while (m_con->recv_lines_available() > 0)
    {
      m_con->recv_line(buf,4096);
      if (!buf[0]) { m_http_state=3; break; }

      char *h = buf;

      // workaround for bug #1445735
      //
      // some proxies, like WinProxy, prefix headers with tabs
      // or spaces. to make sure headers are detected properly,
      // this removes up to 128 useless white spaces.

      while ((h - buf < 128) && (*h == ' ' || *h == '\t')) h++;

      if (!m_recvheaders)
      {
        m_recvheaders_size=strlen(h)+1;
        m_recvheaders=(char*)malloc(m_recvheaders_size+1);
        if (m_recvheaders)
        {
          strcpy(m_recvheaders,h);
          m_recvheaders[m_recvheaders_size]=0;
        }
      }
      else
      {
        int oldsize=m_recvheaders_size;
        m_recvheaders_size+=strlen(h)+1;
        char *n=(char*)malloc(m_recvheaders_size+1);
        if (n)
        {
          memcpy(n,m_recvheaders,oldsize);
          strcpy(n+oldsize,h);
          n[m_recvheaders_size]=0;
          free(m_recvheaders);
          m_recvheaders=n;
        }
      }
    }
  }
  if (m_http_state==3)
  {
  }
  return 0;
}
예제 #5
0
void JNL_HTTPGet::connect(const char *url, int ver, char *requestmethod)
{
    deinit();
    m_http_url=(char*)malloc(strlen(url)+1);
    strcpy(m_http_url,url);
    do_parse_url(m_http_url,&m_http_host,&m_http_port,&m_http_request, &m_http_lpinfo);
    strcpy(m_http_url,url);
    if (!m_http_host || !m_http_host[0] || !m_http_port)
    {
        m_boy_george=0;
        m_http_state=-1;
        seterrstr("invalid URL");
        return;
    }

    int sendbufferlen=0;

    if (!m_http_proxyhost || !m_http_proxyhost[0])
    {
        sendbufferlen += strlen(requestmethod)+1 /* GET */ + strlen(m_http_request) + 9 /* HTTP/1.0 */ + 2;
    }
    else
    {
        sendbufferlen += strlen(requestmethod)+1 /* GET */ + strlen(m_http_url) + 9 /* HTTP/1.0 */ + 2;
        if (m_http_proxylpinfo&&m_http_proxylpinfo[0])
        {
            sendbufferlen+=58+strlen(m_http_proxylpinfo)*2; // being safe here
        }
    }
    sendbufferlen += 5 /* Host: */ + strlen(m_http_host) + 2;

    if (m_http_lpinfo&&m_http_lpinfo[0])
    {
        sendbufferlen+=46+strlen(m_http_lpinfo)*2; // being safe here
    }

    if (m_sendheaders) sendbufferlen+=strlen(m_sendheaders);

    char *str=(char*)malloc(sendbufferlen+1024);
    if (!str)
    {
        seterrstr("error allocating memory");
        m_http_state=-1;
        m_boy_george = 0;
    }

    if (!m_http_proxyhost || !m_http_proxyhost[0])
    {
        wsprintf(str,"%s %s HTTP/1.%d\r\n",requestmethod,m_http_request,ver%10);
    }
    else
    {
        wsprintf(str,"%s %s HTTP/1.%d\r\n",requestmethod, m_http_url,ver%10);
    }

    wsprintf(str+strlen(str),"Host:%s\r\n",m_http_host);

    if (m_http_lpinfo&&m_http_lpinfo[0])
    {
        strcat(str,"Authorization: Basic ");
        do_encode_mimestr(m_http_lpinfo,str+strlen(str));
        strcat(str,"\r\n");
    }
    if (m_http_proxylpinfo&&m_http_proxylpinfo[0])
    {
        strcat(str,"Proxy-Authorization: Basic ");
        do_encode_mimestr(m_http_proxylpinfo,str+strlen(str));
        strcat(str,"\r\n");
    }

    if (m_sendheaders) strcat(str,m_sendheaders);
    strcat(str,"\r\n");

    int a=m_recvbufsize;
    if (a < 4096) a=4096;
    //m_con=new JNL_Connection(m_dns,strlen(str)+4,a);
    /*
    **  Joshua Teitelbaum delta 1/15/2006
    */
#ifdef _JNETLIB_SSL_
    /*
    **  Joshua Teitelbaum 1/27/2006
    **  Check for secure
    */
    if(!strnicmp(m_http_url,"https:",strlen("https:")))
    {
        m_con=new JNL_SSL_Connection(NULL,m_dns,8192,a);
    }
    else
    {
        m_con=new JNL_Connection(m_dns,8192,a);
    }
#else
    m_con=new JNL_Connection(m_dns,8192,a);
#endif

    if (m_con)
    {
        if (!m_http_proxyhost || !m_http_proxyhost[0])
        {
            m_con->connect(m_http_host,m_http_port);
        }
        else
        {
            m_con->connect(m_http_proxyhost,m_http_proxyport);
        }
        m_con->send_string(str);
    }
    else
    {
        m_http_state=-1;
        m_boy_george = 0;
        seterrstr("could not create connection object");
    }
    free(str);

}