예제 #1
0
static void process_new_connection(struct mg_connection *conn) {
  struct mg_request_info *ri = &conn->request_info;
  const char *cl;

  reset_per_request_attributes(conn);

  // If next request is not pipelined, read it in
  if ((conn->request_len = get_request_len(conn->buf, conn->data_len)) == 0) {
    conn->request_len = read_request(conn->client.sock,
        conn->buf, conn->buf_size, &conn->data_len);
  }
  assert(conn->data_len >= conn->request_len);
  if (conn->request_len == 0 && conn->data_len == conn->buf_size) {
    mg_send_http_error(conn, 413, "Request Too Large", "");
    return;
  } if (conn->request_len <= 0) {
    return;  // Remote end closed the connection
  }

  // Nul-terminate the request cause parse_http_request() uses sscanf
  conn->buf[conn->request_len - 1] = '\0';
  if (!parse_http_request(conn->buf, ri)) {
    // Do not put garbage in the access log, just send it back to the client
    mg_send_http_error(conn, 400, "Bad Request",
        "Cannot parse HTTP request: [%.*s]", conn->data_len, conn->buf);
  } else if (strcmp(ri->http_version, "1.0") && strcmp(ri->http_version, "1.1")) {
    // Request seems valid, but HTTP version is strange
    mg_send_http_error(conn, 505, "HTTP version not supported", "");
  } else {
    // Request is valid, handle it
    cl = get_header(ri, "Content-Length");
    conn->content_len = cl == NULL ? -1 : strtoll(cl, NULL, 10);
    conn->birth_time = time(NULL);
    handle_request(conn);
    discard_current_request_from_buffer(conn);
  }
}
예제 #2
0
// This is the heart of the Mongoose's logic.
// This function is called when the request is read, parsed and validated,
// and Mongoose must decide what action to take: serve a file, or
// a directory, or call embedded function, etcetera.
static void handle_request(struct mg_connection *conn) {
  struct mg_request_info *ri = &conn->request_info;
  int uri_len;

  if ((conn->request_info.query_string = strchr(ri->uri, '?')) != NULL) {
    * conn->request_info.query_string++ = '\0';
  }
  uri_len = strlen(ri->uri);
  (void) url_decode(ri->uri, (size_t)uri_len, ri->uri, (size_t)(uri_len + 1), 0);
  remove_double_dots_and_double_slashes(ri->uri);

  DEBUG_TRACE(("%s", ri->uri));
  if (call_user(conn, MG_NEW_REQUEST) == NULL) {
    mg_send_http_error(conn, 404, "Not Found", "%s", "File not found");
  }
}
예제 #3
0
static void *request_handler(enum mg_event event,
                             struct mg_connection *conn,
                             const struct mg_request_info *request_info) {
    if (event == MG_NEW_REQUEST) {
        if (!strcmp(request_info->uri, "/dd.xml") &&
            !strcmp(request_info->request_method, "GET")) {
            mg_printf(conn, "HTTP/1.1 200 OK\r\n"
                      "Content-Type: application/xml\r\n"
                      "Application-URL: http://%s:%d/apps/\r\n"
                      "\r\n", ip_addr, dial_port);
            mg_printf(conn, ddxml, friendly_name, model_name, uuid);
        } else {
            mg_send_http_error(conn, 404, "Not Found", "Not Found");
        }
        return "done";
    }
    return NULL;
}
예제 #4
0
static void *mongoose_callback(enum mg_event event, struct mg_connection *conn) {
  const struct mg_request_info *request_info = mg_get_request_info(conn);

  if (event == MG_INIT0)
  {
    verify_document_root(mg_get_conn_option(conn, "document_root"));
    return (void *)1;
  }

#if defined(_WIN32)
  if (event == MG_EVENT_LOG &&
      strstr(request_info->log_message, "cannot bind to") &&
      !strcmp(request_info->log_severity, "error"))
  {
    if (!error_dialog_shown_previously)
    {
      MessageBoxA(NULL, request_info->log_message, "Error", MB_OK);
      error_dialog_shown_previously = 1;
    }
    return 0;
  }
#endif

  if (event != MG_NEW_REQUEST) {
    // This callback currently only handles new requests
    return NULL;
  }

  {
    int file_found;
    struct mgstat fst;

    assert(request_info->phys_path);
    file_found = (0 == mg_stat(request_info->phys_path, &fst) && !fst.is_directory);
    if (file_found) {
      return NULL; // let mongoose handle the default of 'file exists'...
    }

#ifdef _WIN32
    // Send the systray icon as favicon
    if (!strcmp("/favicon.ico", request_info->uri)) {
      HMODULE module;
      HRSRC icon;
      DWORD len;
      void *data;

      module = GetModuleHandle(NULL);

      icon = FindResource(module, MAKEINTRESOURCE(IDR_FAVICON), RT_RCDATA);
      data = LockResource(LoadResource(module, icon));
      len = SizeofResource(module, icon);

      mg_add_response_header(conn, 0, "Content-Type", "image/x-icon");
      mg_add_response_header(conn, 0, "Cache-Control", "no-cache");
      mg_add_response_header(conn, 0, "Content-Length", "%u", (unsigned int)len);
      //mg_add_response_header(conn, 0, "Connection", suggest_connection_header(conn)); -- not needed any longer
      mg_write_http_response_head(conn, 200, NULL);

      if ((int)len != mg_write(conn, data, len)) {
        mg_send_http_error(conn, 580, NULL, "not all data was written to the socket (len: %u)", (unsigned int)len); // internal error in our custom handler or client closed connection prematurely
      }
      return (void *)1;
    }
#endif
  }

  return NULL;
}
예제 #5
0
static void *mongoose_callback(enum mg_event event, struct mg_connection *conn) {
  const struct mg_request_info *request_info = mg_get_request_info(conn);

  if (event == MG_INIT0)
  {
    verify_document_root(mg_get_conn_option(conn, "document_root"));
    return (void *)1;
  }

#if defined(_WIN32)
  if (event == MG_EVENT_LOG &&
      strstr(request_info->log_message, "cannot bind to") &&
      !strcmp(request_info->log_severity, "error"))
  {
    if (!error_dialog_shown_previously)
    {
      MessageBoxA(NULL, request_info->log_message, "Error", MB_OK);
      error_dialog_shown_previously = 1;
    }
    return 0;
  }
#endif

#if USE_BEL2125_TEST_NR_18_EVENT_HANDLER
  {
    int contentLength = 0;
    int dataRead = 0;
    char postData[BUFFER_SIZE] = { 0 };
    const char* contentType = NULL;

    if (event == MG_NEW_REQUEST)
    {
        if (strstr(request_info->uri, "/echo") == request_info->uri)
        {
            int ie_hack = 0;  // testing an assumption; turns out it doesn't matter whether headers make it into TCP stack before you expect to fetch all input data at once.
            int ie_hack2 = 0;

            contentLength = atoi(mg_get_header(conn, "Content-Length"));
            assert(contentLength <= BUFFER_SIZE);

            mg_set_response_code(conn, 200);

            if (ie_hack2) mg_connection_must_close(conn);  // the stackoverflow suggested fix: http://stackoverflow.com/questions/3731420/why-does-ie-issue-random-xhr-408-12152-responses-using-jquery-post

            contentType = mg_get_header(conn, "Content-Type");

            if (ie_hack)
            {
                //mg_add_response_header(conn, 0, "Connection", mg_suggest_connection_header(conn)); -- not needed any longer
                mg_add_response_header(conn, 0, "Content-Type", contentType);
                mg_add_response_header(conn, 0, "Content-Length", "%d", contentLength);
                mg_write_http_response_head(conn, 0, 0);  // let the previous mg_set_response_code() decide for us
            }

            dataRead = mg_read(conn, postData, contentLength);
            if (dataRead > 0)
            {
                assert(dataRead == contentLength);

                if (!ie_hack)
                {
                    //mg_add_response_header(conn, 0, "Connection", mg_suggest_connection_header(conn)); -- not needed any longer
                    mg_add_response_header(conn, 0, "Content-Type", contentType);
                    mg_add_response_header(conn, 0, "Content-Length", "%d", dataRead);
                    mg_write_http_response_head(conn, 0, 0);  // let the previous mg_set_response_code() decide for us
                }

                if (mg_write(conn, postData, dataRead) != contentLength)
                {
                    mg_send_http_error(conn, 580, NULL, "not all data was written to the socket (len: %u)", (unsigned int)contentLength); // internal error in our custom handler or client closed connection prematurely
                }

                return (void*)1;
            }
            else
            {
                mg_send_http_error(conn, 500, NULL, "I/O failure during mg_read() from connection: %s", mg_strerror(ERRNO));
            }
        }
    }
  }
#endif // USE_BEL2125_TEST_NR_18_EVENT_HANDLER

  if (event != MG_NEW_REQUEST) {
    // This callback currently only handles new requests
    return NULL;
  }

  {
    int file_found;
    struct mgstat fst;

    assert(request_info->phys_path);
    file_found = (0 == mg_stat(request_info->phys_path, &fst) && !fst.is_directory);
    if (file_found) {
      return NULL; // let mongoose handle the default of 'file exists'...
    }

#ifdef _WIN32
    // Send the systray icon as favicon
    if (!strcmp("/favicon.ico", request_info->uri)) {
      HMODULE module;
      HRSRC icon;
      DWORD len;
      void *data;

      module = GetModuleHandle(NULL);

      icon = FindResource(module, MAKEINTRESOURCE(IDR_FAVICON), RT_RCDATA);
      data = LockResource(LoadResource(module, icon));
      len = SizeofResource(module, icon);

      mg_add_response_header(conn, 0, "Content-Type", "image/x-icon");
      mg_add_response_header(conn, 0, "Cache-Control", "no-cache");
      mg_add_response_header(conn, 0, "Content-Length", "%u", (unsigned int)len);
      //mg_add_response_header(conn, 0, "Connection", suggest_connection_header(conn)); -- not needed any longer
      mg_write_http_response_head(conn, 200, NULL);

      if ((int)len != mg_write(conn, data, len)) {
        mg_send_http_error(conn, 580, NULL, "not all data was written to the socket (len: %u)", (unsigned int)len); // internal error in our custom handler or client closed connection prematurely
      }
      return (void *)1;
    }
#endif
  }

  return NULL;
}