File: clTernWorkerThread.cpp

package info (click to toggle)
codelite 14.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 112,816 kB
  • sloc: cpp: 483,662; ansic: 150,144; php: 9,569; lex: 4,186; python: 3,417; yacc: 2,820; sh: 1,147; makefile: 52; xml: 13
file content (98 lines) | stat: -rw-r--r-- 2,902 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "clTernWorkerThread.h"
#include "SocketAPI/clSocketClient.h"
#include "clTernServer.h"
#include <wx/buffer.h>
#include <sstream>
#include "file_logger.h"

clTernWorkerThread::clTernWorkerThread(clTernServer* ternServer)
    : m_ternSerer(ternServer)
{
    m_port = m_ternSerer->GetPort();
}

clTernWorkerThread::~clTernWorkerThread() {}

struct MallocDeleter {
    char* m_ptr;
    MallocDeleter(char* p)
        : m_ptr(p)
    {
    }

    ~MallocDeleter()
    {
        if(m_ptr) {
            free(m_ptr);
            m_ptr = NULL;
        }
    }
};

void clTernWorkerThread::ProcessRequest(ThreadRequest* request)
{
    clTernWorkerThread::Request* r = dynamic_cast<clTernWorkerThread::Request*>(request);
    clSocketClient* client = new clSocketClient();
    clSocketBase::Ptr_t p(client);
    
    // Make sure that the jsonReuqest is destroyed
    MallocDeleter deleter(r->jsonRequest);
    
    bool wouldBlock;
    try {
        if(!client->ConnectRemote("127.0.0.1", m_port, wouldBlock)) {
            m_ternSerer->CallAfter(&clTernServer::OnError, client->error().c_str());
            return;
        }

        // POST /path/script.cgi HTTP/1.0
        // From: frog@jmarshall.com
        // User-Agent: HTTPTool/1.0
        // Content-Type: application/x-www-form-urlencoded
        // Content-Length: 32

        wxMemoryBuffer buffer;
        std::stringstream ss;
        ss << "POST / HTTP/1.1\r\n";
        ss << "From: Eran Ifrah\r\n";
        ss << "User-Agent: CodeLite IDE\r\n";
        ss << "Content-Type: application/x-www-form-urlencoded\r\n";
        ss << "Content-Length: ";
        ss << strlen(r->jsonRequest) << "\r\n";
        ss << "\r\n";
        ss << r->jsonRequest;

        std::string strBuffer = ss.str();
        buffer.AppendData(strBuffer.c_str(), strBuffer.length());
        
        CL_DEBUG("[WebTools] %s", strBuffer.c_str());
        
        client->Send(buffer);
        wxMemoryBuffer output;
        client->Read(output, 5);

        // Strip the HTTP headers and send only the JSON reply back to the main thread
        wxString str = wxString::From8BitData((const char*)output.GetData(), output.GetDataLen());
        int where = str.Find("\r\n\r\n");
        if(where == wxNOT_FOUND) {
            CL_DEBUG("Tern invalid output:\n%s\n", str);
            m_ternSerer->CallAfter(&clTernServer::OnError, "Invalid output");
            return;
        }

        wxString json = str.Mid(where + 4);

        // Skip the ID
        json = json.AfterFirst('{');
        json.Prepend("{");
        clTernWorkerThread::Reply reply;
        reply.json.swap(json);
        reply.filename.swap(r->filename);
        reply.requestType = r->type;

        m_ternSerer->CallAfter(&clTernServer::OnTernWorkerThreadDone, reply);

    } catch(clSocketException& e) {
        m_ternSerer->CallAfter(&clTernServer::OnError, e.what().c_str());
    }
}