<commit_before>% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License.  You may obtain a copy of
% the License at
%
%   http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
% License for the specific language governing permissions and limitations under
% the License.

-module(couch_httpd).
-include("couch_db.hrl").

-export([start_link/3, stop/0]).

-record(doc_query_args, {
    options = [],
    rev = "",
    open_revs = ""
}).

-record(view_query_args, {
    start_key = nil,
    end_key = <<>>,
    count = 10000000000, % a huge huge default number. Picked so we don't have
                         % to do different logic for when there is no count
                         % limit
    update = true,
    direction = fwd,
    start_docid = nil,
    end_docid = <<>>,
    skip = 0
}).

start_link(BindAddress, Port, DocumentRoot) ->
    Loop = fun (Req) -> handle_request(Req, DocumentRoot) end,
    mochiweb_http:start([
        {loop, Loop},
        {name, ?MODULE},
        {ip, BindAddress},
        {port, Port}
    ]).

stop() ->
    mochiweb_http:stop(?MODULE).

handle_request(Req, DocumentRoot) ->
    % alias HEAD to GET as mochiweb takes care of stripping the body
    Method = case Req:get(method) of
        'HEAD' -> 'GET';
        Other -> Other
    end,

    % for the path, use the raw path with the query string and fragment
    % removed, but URL quoting left intact
    {Path, _, _} = mochiweb_util:urlsplit_path(Req:get(raw_path)),

    couch_log:debug("Method:      ~p", [Method]),
    couch_log:debug("Request URI: ~p", [Path]),
    couch_log:debug("Headers: ~p", [mochiweb_headers:to_list(Req:get(headers))]),

    {ok, Resp} = case catch(handle_request(Req, DocumentRoot, Method, Path)) of
        {ok, Resp0} ->
            {ok, Resp0};
        Error ->
            send_error(Req, Error)
    end,

    couch_log:info("~s - - ~p ~B", [
        Req:get(peer),
        atom_to_list(Req:get(method)) ++ " " ++ Path,
        Resp:get(code)
    ]).

handle_request(Req, DocumentRoot, Method, Path) ->
    case Path of
        "/" ->
            handle_welcome_request(Req, Method);
        "/_all_dbs" ->
            handle_all_dbs_request(Req, Method);
        "/favicon.ico" ->
            {ok, Req:serve_file("favicon.ico", DocumentRoot)};
        "/_replicate" ->
            handle_replicate_request(Req, Method);
        "/_utils" ->
            {ok, Req:respond({301, [{"Location", "/_utils/"}], <<>>})};<commit_msg>Display Request HTTP version on debug<commit_after>% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License.  You may obtain a copy of
% the License at
%
%   http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
% License for the specific language governing permissions and limitations under
% the License.

-module(couch_httpd).
-include("couch_db.hrl").

-export([start_link/3, stop/0]).

-record(doc_query_args, {
    options = [],
    rev = "",
    open_revs = ""
}).

-record(view_query_args, {
    start_key = nil,
    end_key = <<>>,
    count = 10000000000, % a huge huge default number. Picked so we don't have
                         % to do different logic for when there is no count
                         % limit
    update = true,
    direction = fwd,
    start_docid = nil,
    end_docid = <<>>,
    skip = 0
}).

start_link(BindAddress, Port, DocumentRoot) ->
    Loop = fun (Req) -> handle_request(Req, DocumentRoot) end,
    mochiweb_http:start([
        {loop, Loop},
        {name, ?MODULE},
        {ip, BindAddress},
        {port, Port}
    ]).

stop() ->
    mochiweb_http:stop(?MODULE).

handle_request(Req, DocumentRoot) ->
    % alias HEAD to GET as mochiweb takes care of stripping the body
    Method = case Req:get(method) of
        'HEAD' -> 'GET';
        Other -> Other
    end,

    % for the path, use the raw path with the query string and fragment
    % removed, but URL quoting left intact
    {Path, _, _} = mochiweb_util:urlsplit_path(Req:get(raw_path)),

    couch_log:debug("Version:     ~p", [Req:get(version)]),
    couch_log:debug("Method:      ~p", [Method]),
    couch_log:debug("Request URI: ~p", [Path]),
    couch_log:debug("Headers: ~p", [mochiweb_headers:to_list(Req:get(headers))]),

    {ok, Resp} = case catch(handle_request(Req, DocumentRoot, Method, Path)) of
        {ok, Resp0} ->
            {ok, Resp0};
        Error ->
            send_error(Req, Error)
    end,

    couch_log:info("~s - - ~p ~B", [
        Req:get(peer),
        atom_to_list(Req:get(method)) ++ " " ++ Path,
        Resp:get(code)
    ]).

handle_request(Req, DocumentRoot, Method, Path) ->
    case Path of
        "/" ->
            handle_welcome_request(Req, Method);
        "/_all_dbs" ->
            handle_all_dbs_request(Req, Method);
        "/favicon.ico" ->
            {ok, Req:serve_file("favicon.ico", DocumentRoot)};
        "/_replicate" ->
            handle_replicate_request(Req, Method);
        "/_utils" ->
            {ok, Req:respond({301, [{"Location", "/_utils/"}], <<>>})};
{'fraction_non_alphanumeric': 0.13649425287356323, 'fraction_numerical': 0.008261494252873564, 'mean_word_length': 2.609202851587816, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6510998', 'n_tokens_mistral': 1808, 'n_tokens_neox': 1760, 'n_words': 496}