Exemple #1
0
/*----------------------------------------------------------------------
|    ATX_HttpResponse_Emit
+---------------------------------------------------------------------*/
extern ATX_Result
ATX_HttpResponse_Emit(const ATX_HttpResponse* response,
                      ATX_OutputStream*       stream)
{
    /* check that we have what we need */
    if (ATX_String_IsEmpty(&response->base.protocol)) return ATX_ERROR_INVALID_PARAMETERS;
    if (response->status_code >= 1000) return ATX_ERROR_INVALID_PARAMETERS;

    /* output response line */
    ATX_OutputStream_WriteString(stream, ATX_CSTR(response->base.protocol));
    {
        char code_string[5];
        unsigned  code_int = response->status_code;
        code_string[0] = ' ';
        code_string[1] = '0' + code_int/100; 
        code_int -= 100*(code_int/100);
        code_string[2] = '0' + code_int/10;
        code_int -= 10*(code_int/10);
        code_string[3] = '0' + code_int;
        code_string[4] = ' ';
        ATX_OutputStream_Write(stream, code_string, 5, NULL);
    }
    ATX_OutputStream_WriteString(stream, ATX_CSTR(response->reason_phrase));
    ATX_OutputStream_Write(stream, "\r\n", 2, NULL);

    /* output the rest of the message */
    return ATX_HttpMessage_Emit((ATX_HttpMessage*)response, stream);
}
/*----------------------------------------------------------------------
|    AlsaOutput_Open
+---------------------------------------------------------------------*/
static BLT_Result
AlsaOutput_Open(AlsaOutput* self)
{
    int io_result;

    ATX_LOG_FINE_1("openning output - name=%s", ATX_CSTR(self->device_name));

    switch (self->state) {
      case BLT_ALSA_OUTPUT_STATE_CLOSED:
        ATX_LOG_FINER("snd_pcm_open");
        io_result = snd_pcm_open(&self->device_handle,
                                 ATX_CSTR(self->device_name),
                                 SND_PCM_STREAM_PLAYBACK,
                                 0);
        if (io_result != 0) {
            self->device_handle = NULL;
            return BLT_FAILURE;
        }
        break;

      case BLT_ALSA_OUTPUT_STATE_OPEN:
        /* ignore */
        return BLT_SUCCESS;

      case BLT_ALSA_OUTPUT_STATE_CONFIGURED:
      case BLT_ALSA_OUTPUT_STATE_PREPARED:
        return BLT_FAILURE;
    }

    /* update the state */
    AlsaOutput_SetState(self, BLT_ALSA_OUTPUT_STATE_OPEN);

    return BLT_SUCCESS;
}
/*----------------------------------------------------------------------
|   BLT_TcpNetworkStream_Create
+---------------------------------------------------------------------*/
BLT_Result 
BLT_TcpNetworkStream_Create(const char* name, ATX_InputStream** stream)
{
    ATX_Socket* sock;
    ATX_String  hostname = ATX_String_Create(name);
    ATX_UInt16  port = BLT_TCP_NETWORK_STREAM_DEFAULT_PORT;
    int         sep;
    ATX_Result  result = ATX_SUCCESS;

    /* default */
    *stream = NULL;

    /* parse the hostname/port */
    sep = ATX_String_FindCharFrom(&hostname, ':', 6);
    if (sep > 0) {
        /* we have a port number */
        int port_long = 0;
        result = ATX_ParseInteger(name+sep+1, &port_long, ATX_FALSE);
        if (ATX_FAILED(result)) {
            ATX_LOG_WARNING("BLT_TcpNetworkStream_Create - invalid port spec");
            goto end;
        }
        port = (ATX_UInt16)port_long;
        ATX_String_SetLength(&hostname, sep);
    }

    /* create a socket */
    result = ATX_TcpClientSocket_Create(&sock);
    if (ATX_FAILED(result)) goto end;
    
    /* connect */
    ATX_LOG_FINE_2("BLT_TcpNetworkStream_Create - connecting to %s:%d",
                   ATX_CSTR(hostname), port);
    result = ATX_Socket_ConnectToHost(sock, ATX_CSTR(hostname), port, BLT_TCP_NETWORK_STREAM_DEFAULT_TIMEOUT);
    if (ATX_FAILED(result)) {
        ATX_LOG_WARNING_1("BLT_TcpNetworkStream_Create - failed to connect (%d)", result);
        goto end;
    }
    ATX_LOG_FINE("BLT_TcpNetworkStream_Create - connected");

    /* return the input stream */
    result = ATX_Socket_GetInputStream(sock, stream);

    /* release the socket */
    ATX_DESTROY_OBJECT(sock);
    
end:
    ATX_String_Destruct(&hostname);
    return result;
}
Exemple #4
0
/*----------------------------------------------------------------------
|    ATX_HttpMessage_Emit
+---------------------------------------------------------------------*/
static ATX_Result
ATX_HttpMessage_Emit(const ATX_HttpMessage* message, ATX_OutputStream* stream)
{
    ATX_ListItem* item = ATX_List_GetFirstItem(message->headers);

    /* output the headers */
    while (item) {
        ATX_HttpHeader* header = ATX_ListItem_GetData(item);
        if (header && 
            !ATX_String_IsEmpty(&header->name) && 
            !ATX_String_IsEmpty(&header->value)) {
            ATX_OutputStream_WriteString(stream, ATX_CSTR(header->name));
            ATX_OutputStream_Write(stream, ": ", 2, NULL);
            ATX_OutputStream_WriteLine(stream, ATX_CSTR(header->value));
            ATX_LOG_FINE_2("ATX_HttpMessage::Emit - %s: %s", ATX_CSTR(header->name), ATX_CSTR(header->value));
        }
        item = ATX_ListItem_GetNext(item);
    }

    return ATX_SUCCESS;
}
Exemple #5
0
/*----------------------------------------------------------------------
|    ATX_HttpRequest_Emit
+---------------------------------------------------------------------*/
ATX_Result
ATX_HttpRequest_Emit(const ATX_HttpRequest* request, ATX_OutputStream* stream)
{
    /* check that we have all we need */
    if (ATX_String_IsEmpty(&request->method) || 
        ATX_String_IsEmpty(&request->base.protocol)) {
        return ATX_ERROR_INVALID_PARAMETERS;
    }

    /* output the request line */
    ATX_OutputStream_WriteString(stream, ATX_CSTR(request->method));
    ATX_OutputStream_Write(stream, " ", 1, NULL);
    ATX_OutputStream_WriteString(stream, ATX_CSTR(request->url.path));
    ATX_OutputStream_Write(stream, " ", 1, NULL);
    ATX_OutputStream_WriteString(stream, ATX_CSTR(request->base.protocol));

    /* output the headers */
    ATX_HttpMessage_Emit(&request->base, stream);

    /* terminating line */
    ATX_OutputStream_Write(stream, "\r\n", 2, NULL);

    return ATX_SUCCESS;
}
Exemple #6
0
/*----------------------------------------------------------------------
|       Listener_OnPropertyChanged
+---------------------------------------------------------------------*/
static void
Listener_OnPropertyChanged(ATX_PropertyListener*    _self,
                           ATX_CString              name,
                           ATX_PropertyType         type,
                           const ATX_PropertyValue* value)
{
    Listener* self = ATX_SELF(Listener, ATX_PropertyListener);

    ATX_Debug("OnPropertyChanged[%s]: ", ATX_CSTR(self->name));
    if (value) {
        PrintProperty(name, type, value);
    } else {
        ATX_Debug("name=%s [REMOVED]\n", name);
    }
}
Exemple #7
0
/*----------------------------------------------------------------------
|    ATX_HttpRequest_Create
+---------------------------------------------------------------------*/
ATX_Result 
ATX_HttpRequest_Create(ATX_CString       method, 
                       ATX_CString       url,
                       ATX_HttpRequest** request)
{
    ATX_Result result;

    /* allocate a new object */
    *request = (ATX_HttpRequest*)ATX_AllocateZeroMemory(sizeof(ATX_HttpRequest));
    if (*request == NULL) {
        return ATX_ERROR_OUT_OF_MEMORY;
    }

    /* construct the base object */
    result = ATX_HttpMessage_Construct(&(*request)->base);
    if (ATX_FAILED(result)) {
        ATX_FreeMemory((void*)request);
        return result;
    }

    /* construct the object */
    (*request)->method = ATX_String_Create(method);
    result = ATX_HttpUrl_Construct(&(*request)->url, url);
    if (ATX_FAILED(result)) {
        ATX_HttpMessage_Destruct(&(*request)->base);
        ATX_FreeMemory((void*)request);
        return result;
    }

    /* set the host header */
    if (!ATX_String_IsEmpty(&(*request)->url.host)) {
        ATX_HttpMessage_SetHeader((ATX_HttpMessage*)(*request), 
                                  ATX_HTTP_HEADER_HOST, 
                                  ATX_CSTR((*request)->url.host));
    }

    return ATX_SUCCESS;
}
Exemple #8
0
/*----------------------------------------------------------------------
|    ATX_HttpResponse_Parse
+---------------------------------------------------------------------*/
static ATX_Result 
ATX_HttpResponse_Parse(ATX_HttpResponse* response, ATX_InputStream* stream)
{
    char        buffer[ATX_HTTP_MAX_LINE_SIZE+1];
    char*       line = buffer;
    char*       find;
    ATX_Boolean header_pending = ATX_FALSE;
    ATX_String  header_name = ATX_EMPTY_STRING;
    ATX_String  header_value = ATX_EMPTY_STRING;
    ATX_Result  result;

    /* get the first line from the stream */
    result = ATX_InputStream_ReadLine(stream, line, sizeof(buffer), NULL);
    if (ATX_FAILED(result)) return result;

    /* get the protocol */
    find = (char*)ATX_Http_FindChar(line, ' ');
    if (find == NULL) {
        return ATX_ERROR_INVALID_SYNTAX;
    }
    *find = '\0';
    ATX_String_Assign(&response->base.protocol, line);

    /* get the status code */
    line = (char*)ATX_Http_SkipWhitespace(find+1);
    find = (char*)ATX_Http_FindChar(line, ' ');
    if (find == NULL) {
        return ATX_ERROR_INVALID_SYNTAX;
    }
    *find = '\0';
    if (ATX_StringLength(line) != 3) {
        return ATX_ERROR_INVALID_SYNTAX;
    }
    {
        int i;
        response->status_code = 0;
        for (i=0; i<3; i++) {
            if (line[i] < '0' || line[i] > '9') {
                return ATX_ERROR_INVALID_SYNTAX;
            }
            response->status_code *= 10;
            response->status_code += line[i]-'0';
        }
    }

    /* the rest is the reason phrase */
    line = (char*)ATX_Http_SkipWhitespace(find+1);
    ATX_String_Assign(&response->reason_phrase, line);

    /* parse headers until an empty line or end of stream */
    do {
        /* read a line */
        result = ATX_InputStream_ReadLine(stream, line, sizeof(buffer), NULL);
        if (ATX_FAILED(result)) break;

        /* stop if line is empty */
        if (line[0] == '\0' || line[0] == '\r' || line[0] == '\n') {
            if (header_pending) {
                ATX_String_TrimWhitespace(&header_value);
                ATX_HttpMessage_SetHeader((ATX_HttpMessage*)response, 
                                          ATX_CSTR(header_name), 
                                          ATX_CSTR(header_value));
                ATX_LOG_FINE_2("ATX_HttpResponse::Parse - %s: %s",
                               ATX_CSTR(header_name),
                               ATX_CSTR(header_value));
            }
            break;
        }

        /* process the line */
        if ((line[0] == ' ' || line[0] == '\t') && header_pending) {
            /* this is a line continuation */
            ATX_String_Append(&header_value, line+1);
        } else {
            /* this is a new header */
            const char* name;
            const char* value;

            /* add the pending header to the list */
            if (header_pending) {
                ATX_String_TrimWhitespace(&header_value);
                ATX_HttpMessage_SetHeader((ATX_HttpMessage*)response, 
                                          ATX_CSTR(header_name), 
                                          ATX_CSTR(header_value));
                ATX_LOG_FINE_2("ATX_HttpResponse::Parse - %s: %s",
                               ATX_CSTR(header_name),
                               ATX_CSTR(header_value));
            }

            /* parse header name */
            name = ATX_Http_SkipWhitespace(line);
            value = ATX_Http_FindChar(name, ':');
            ATX_String_AssignN(&header_name, name, (ATX_Size)(value-name));
            value = ATX_Http_SkipWhitespace(value+1);
            ATX_String_Assign(&header_value, value);

            /* don't add the header now, it could be continued */
            header_pending = ATX_TRUE;
        }
    } while(ATX_SUCCEEDED(result));

    /* keep a reference to the stream */
    response->base.body = stream;
    ATX_REFERENCE_OBJECT(stream);

    /* cleanup */
    ATX_String_Destruct(&header_name);
    ATX_String_Destruct(&header_value);

    return ATX_SUCCESS;
}
Exemple #9
0
/*----------------------------------------------------------------------
|   ATX_HttpClient_SendRequestOnce
+---------------------------------------------------------------------*/
static ATX_Result
ATX_HttpClient_SendRequestOnce(ATX_HttpClient*    self, 
                               ATX_HttpRequest*   request, 
                               ATX_HttpResponse** response)

{
    ATX_SocketAddress address;
    ATX_Socket*       connection = NULL;
    ATX_InputStream*  input_stream = NULL;
    ATX_OutputStream* output_stream = NULL;
    ATX_Result        result;

    ATX_COMPILER_UNUSED(self);

    /* set default return value */
    *response = NULL;

    /* resolve the host address */
    ATX_LOG_INFO_1("ATX_HttpClient::SendRequest - resolving name [%s]...",
                   ATX_CSTR(request->url.host));
    result = ATX_IpAddress_ResolveName(&address.ip_address, 
                                       ATX_CSTR(request->url.host),
                                       ATX_HTTP_RESOLVER_TIMEOUT);
    if (ATX_FAILED(result)) return result;
    address.port = request->url.port;
    ATX_LOG_INFO("ATX_HttpClient::SendRequest - name resolved");

    /* setup some headers */
    ATX_HttpMessage_SetHeader((ATX_HttpMessage*)request,
                              ATX_HTTP_HEADER_CONNECTION,
                              "close");
    ATX_HttpMessage_SetHeader((ATX_HttpMessage*)request,
                              ATX_HTTP_HEADER_HOST,
                              ATX_CSTR(request->url.host));
    ATX_HttpMessage_SetHeader((ATX_HttpMessage*)request,
                              ATX_HTTP_HEADER_USER_AGENT,
                              ATX_HTTP_HEADER_DEFAULT_AGENT);

    /* create a socket to connect to the server */
    result = ATX_TcpClientSocket_Create(&connection);
    if (ATX_FAILED(result)) return result;

    /* connect to the server */
    ATX_LOG_INFO_1("ATX_HttpClient::SendRequest - connecting on port %d...",
               request->url.port);
    result = ATX_Socket_Connect(connection, &address, ATX_HTTP_CONNECT_TIMEOUT);
    if (ATX_FAILED(result)) goto end;

    /* emit the request onto the connection */
    result = ATX_Socket_GetOutputStream(connection, &output_stream);
    if (ATX_FAILED(result)) goto end;
    result = ATX_HttpRequest_Emit(request, output_stream);
    if (ATX_FAILED(result)) goto end;

    /* create a response from the connection's input stream */
    result = ATX_Socket_GetInputStream(connection, &input_stream);
    if (ATX_FAILED(result)) goto end;
    result = ATX_HttpResponse_CreateFromStream(input_stream, response);
    if (ATX_FAILED(result)) {
        *response = NULL;
        goto end;
    }

end:
    if (ATX_FAILED(result)) {
        if (*response != NULL) {
            ATX_HttpResponse_Destroy(*response);
        }
    }
    ATX_RELEASE_OBJECT(input_stream);
    ATX_RELEASE_OBJECT(output_stream);
    ATX_DESTROY_OBJECT(connection);
    return result;
}
Exemple #10
0
/*----------------------------------------------------------------------
|       StdcFile_Open
+---------------------------------------------------------------------*/
ATX_METHOD
StdcFile_Open(ATX_File* _self, ATX_Flags mode)
{ 
    StdcFile* self = ATX_SELF(StdcFile, ATX_File);
    FILE*     stdc_file;

    /* decide wheter this is a file or stdin/stdout/stderr */
    if (ATX_String_Equals(&self->name, 
                          ATX_FILE_STANDARD_INPUT, 
                          ATX_FALSE)) {
        stdc_file = stdin;
    } else if (ATX_String_Equals(&self->name, 
                                 ATX_FILE_STANDARD_OUTPUT, 
                                 ATX_FALSE)) {
        stdc_file = stdout;
    } else if (ATX_String_Equals(&self->name, 
                                 ATX_FILE_STANDARD_ERROR,
                                 ATX_FALSE)) {
        stdc_file = stderr;
    } else {
        const char* fmode = "";

        /* compute mode */
        if (mode & ATX_FILE_OPEN_MODE_WRITE) {
            if (mode & ATX_FILE_OPEN_MODE_CREATE) {
                if (mode & ATX_FILE_OPEN_MODE_TRUNCATE) {
                    /* write, read, create, truncate */
                    fmode = "w+b";
                } else {
                    /* write, read, create */
                    fmode = "a+b";
                }
            } else {
                if (mode & ATX_FILE_OPEN_MODE_TRUNCATE) {
                    /* write, read, truncate */
                    fmode = "w+b";
                } else {
                    /* write, read */
                    fmode = "r+b";
                }
            }
        } else {
            /* read only */
            fmode = "rb";
        }

        /* try to open the file */
        stdc_file = fopen(ATX_CSTR(self->name), fmode);
        if (stdc_file == NULL) {
            switch (errno) {
              case EACCES:
                return ATX_ERROR_ACCESS_DENIED;

              case ENOENT:
                return ATX_ERROR_NO_SUCH_FILE;

              default:
                return ATX_ERROR_ERRNO(errno);
            }
        }
    }

    /* set the buffered/unbuffered option */
    if (mode & ATX_FILE_OPEN_MODE_UNBUFFERED) {
        setvbuf(stdc_file, NULL, _IONBF, 0);
    }

    /* remember the mode */
    self->mode = mode;

    /* create a wrapper */
    return StdcFileWrapper_Create(stdc_file, self->size, &self->file);
}